webpack 性能优化

1、开发环境性能优化

打包构建速度

  1. HMR 模块热更新 (hot module replacement)~

    • 一个模块变化,只重新打包一个模块,极大的提高构建速度
    • style-loader0 内置了热更新,所以只需在devServer 配置 hot: true
    • js 文件默认没有HMR
    • html 文件默认没有HMR。通过修改entry,将html文件引入。因为只有一个html,所以不需要
  2. 代码调试~

    • sourceMap 提供源代码到构建后代码映射的技术;如果构建后代码出错了,通过映射关系可以追踪到源代码的错误,从而去修改源代码,非常利于我们去调试。配置:
    module.export = {
        entry: ....,
        output: ...,
        ...
        ...
        devtool: 'source-map' // 外部生成 map文件; 错误代码的准确信息和源代码的错误位置
        devtool: 'inline-source-map' // 内连 只生成一个sourcemap 生成在 bundle内,速度更快;效果和上面差不多
        devtool: 'hidden-source-map' // 外部生成 ; 提示错误代码,但是没有源码的错误位置,只能提示到构建代码的错误位置
        devtool: 'eavl-source-map' // 内连 每个文件都有sourcemap; 错误代码的准确信息和源代码错误位置
        devtool: 'nosources-source-map' // 外部生成; 找到错误代码准确信息,没有任何源代码信息
        devtool: 'cheap-source-map' // 外部生产;提示错误信息,只能精确到源代码的行,那一列不知道
        devtool: 'cheap-module-source-map' // 外部生成;将webpack loader sourcemap加入
    }
    复制代码
    • 开发环境下 追求的速度快 eval > inline cheap-source-map; 建议使用 eval-source-map / eavl-cheap-source-map;

    • 生产环境 nosource-map / hidden-source-map 内连会让代码体积变得很大,所以一般不选择

2、生产环境性能优化

  • 打包构建速度
    oneOf 去优化 loader 只匹配一个loader

  • 优化代码的性能

3、缓存

Babel 缓存

  • babel-loaderoptions 里直接配置 cacheDirectory: true 就行
  • 第二次构建的时候读取缓存,使得构建的速度更快

文件资源缓存

  • 每次webpack打包会生成一个唯一的hash
    1. 问题:文件使用的都是一个hash值,如果重新打包会导致所有缓存失效
    2. 解决: chunkhash,
    3. chunk: 代码块,所有根据入口文件生成的代码同属一个chunkhash,问题是入口只有一个,那尼玛不又全部一样了?
    4. contenthash: 根据文件内容生成hash,不同文件的hash肯定不一样,所以在输出的时候文件后加上contenthash

4、treeshaking

去掉业务场景中没有使用的代码,使得打包后的代码体积更小,从而实现性能提升

前提

  1. 必须使用es6 module, 使用producitonmode
  2. 自动会对代码进行 treeshaking
  3. 问题: package.jsonsideEffects: false意思所有的代码都是没有副作用的(都可以进行treeshking),会导致将js里中的css @babel/polyfill文件干掉。所以需要修改一下 sideEffects: [*.css],标记一下不需要treeshaking的代码

5、code split (代码分割)

将一个大的文件,分割成更多的文件,可以实现按需加载

多入口

意味着多输出,实现代码分割,基本不太被使用

optimization

  • 将node_modules中代码单独打包成一个chunk

  • 自动分析多入口文件中有没有公共的依赖,如果有会打包成一个单独的chunk, 默认大于30kb才会代码分割

    // webpack.config.js
    optimization: {
        splitChunks: {
          chunks: 'all'
        }
      }
    复制代码
  • vue-router的写法

    import('./test.js')
    .then(() => {
    })
    .catch(() => {})
    复制代码

6、懒加载 lazy-loading

  • 前提一定是代码分割,才会懒加载,vue-router的路由懒加载就是这么搞得
  • 预加载会将文件提前加载
  • 懒加载会在文件需要使用时候才加载
  • 那么 预加载跟正常加载有什么区别呢? 正常加载是并行加载(同一时间加载多个文件),而预加载prefetch等其他资源加载完毕浏览器空闲了才会去加载资源。不影响阻塞浏览器运行。问题就是兼容性非常差,慎用。

7、PWA(渐进式网络开发程序:离线可访问)

帮助程序离线也可以加载,因为兼容性问题,没被普及,YouTube是不是有这个功能,会在网络断开的情况下也加载
貌似没有前景,已经被很多公司丢弃了,淘宝就不用了。

8、多进程打包

  • thread-loader 开启多进程打包, 在 babel-loader中使用
  • 启动进程600ms,进程通信也需要时间开销,只有在时间消耗比较长得时候才会使用

9、dll

使用dll技术对某些库(第三方库: Vue, React )进行单独打包

  • 专门打包某些库,生成打包后的库和一个 manifest.json
  • manifest.json映射出哪些库不用打包了,webpack就不会打包这个库
  • 通过webpack.DllReferencePlugin配置webpack不再打包这个库
  • 再用 AddAssetHtmlWebpackPlugin将这个资源自动在html文件中引入
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享