webpack 初步性能优化

开发环境性能优化

  • 优化打包构建速度(HMR)
    HMR:hot module replacement 热模块替换,一个模块发生变化,只会重新打包变化的模块,而不是所有模块,提升构建速度
    1、样式文件可以使用HMR功能,只要在loader 中使用style-loader
 {
    
    
    // 处理css资源
      test: /\.css$/,
      use: ['style-loader', 'css-loader']
    }

2、js 文件 默认不能使用HMR功能需要修改js 添加支持HMR 功能的代码,但是只能处理非入口js文件的其他文件

if (module.hot) {
    
    
  // 一旦 module.hot 为true,说明开启了HMR功能。 --> 让HMR功能代码生效
  module.hot.accept('./print.js', function() {
    
    
    // 方法会监听 print.js 文件的变化,一旦发生变化,其他模块不会重新打包构建。
    // 会执行后面的回调函数
    print();
  });
}

3、HTML 文件默认不能使用HMR 一般不需要做热更新。

entry: ['./src/js/index.js', './src/index.html'],
  • 优化代码调试(source-map)
    source-map: 一种 提供源代码到构建后代码映射 技术 (如果构建后代码出错了,通过映射可以追踪源代码错误)
devtool: 'eval-source-map'
类型 作用范围
source-map 映射单独的外部文件,能错误代码准确信息和源代码的错误位置
inline-source-map 映射一个单独内联source-map,错误代码准确信息和源代码的错误位置
hidden-source-map 映射单独的外部文件,错误代码错误原因,但是没有错误位置,不能追踪源代码错误,只能提示到构建后代码的错误位置
eval-source-map 每一个文件都生成对应的source-map,都在eval 错误代码准确信息 和 源代码的错误位置
nosources-source-map 错误代码准确信息, 但是没有任何源代码信息
cheap-source-map 错误代码准确信息 和 源代码的错误位置, 只能精确到行
cheap-module-source-map 错误代码准确信息 和 源代码的错误位置

生产环境性能优化

  • 优化打包构建速度
    1、oneOf
    当一个文件只需要被一个loader 处理时,使用oneOf 只会匹配一个loader
 oneOf: [
          {
    
    
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
          },
   ]

2、多进程打包

开启多进程打包。 只有工作消耗时间比较长,才需要多进程打包

 {
    
    
     loader: 'thread-loader',
      options: {
    
    
        workers: 2 // 进程2个
      }
    }

3、externals

把不行打包文件排除

externals: {
    
    
    // 拒绝jQuery被打包进来
    jquery: 'jQuery'
  }

4、dll

(1)需要运行 webpack.dll.js 文件

使用dll技术,对某些库(第三方库:jquery、react、vue…)进行单独打包
当你运行 webpack 时,默认查找 webpack.config.js 配置文件
–> webpack --config webpack.dll.js

 plugins: [
    // 打包生成一个 manifest.json --> 提供和jquery映射
    new webpack.DllPlugin({
    
    
      name: '[name]_[hash]', // 映射库的暴露的内容名称
      path: resolve(__dirname, 'dll/manifest.json') // 输出文件路径
    })
  ],

(2)告诉webpack哪些库不参与打包,同时使用时的名称也得变

 new webpack.DllReferencePlugin({
    
    
      manifest: resolve(__dirname, 'dll/manifest.json')
    }),

(3)将某个文件打包输出去,并在html中自动引入该资源

 new AddAssetHtmlWebpackPlugin({
    
    
      filepath: resolve(__dirname, 'dll/jquery.js')
    })
  • 优化代码运行的性能
    1、缓存(hash-chunkhash-contenthash)

babel缓存设置 cacheDirectory: true 可以让第二次打包构建速度更快

 // 第二次构建时,会读取之前的缓存
  cacheDirectory: true

文件资源缓存
(1) hash: 每次wepack构建时会生成一个唯一的hash值。
问题: 因为js和css同时使用一个hash值。
(2) chunkhash:根据chunk生成的hash值。如果打包来源于同一个chunk,那么hash值就一样
问题: js和css的hash值还是一样的
因为css是在js中被引入的,所以同属于一个chunk
(3) contenthash: 根据文件的内容生成hash值。不同文件hash值一定不一样

  output: {
    
    
    filename: 'js/built.[contenthash:10].js',
    path: resolve(__dirname, 'build')
  }

2、tree shaking

tree shaking:去除无用代码;
前提:1. 必须使用ES6模块化 2. 开启production环境
作用: 减少代码体积
问题:可能会把css / @babel/polyfill (副作用)文件干掉
在package.json中配置 “sideEffects”: [".css", ".less"]

"sideEffects": [
    "*.css"
  ]

3、code spilt
(1)配置入口// entry

// 单入口
  // entry: './src/js/index.js',
  entry: {
    
    
    // 多入口:有一个入口,最终输出就有一个bundle
    index: './src/js/index.js',
    test: './src/js/test.js'
  },

(2)设置 optimization

/*
    1. 可以将node_modules中代码单独打包一个chunk最终输出
    2. 自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk
  */
  optimization: {
    
    
    splitChunks: {
    
    
      chunks: 'all'
    }
  },

(3) import动态导入语法

/*
  通过js代码,让某个文件被单独打包成一个chunk
  import动态导入语法:能将某个文件单独打包
*/
import(/* webpackChunkName: 'test' */'./test')
  .then(({
    
     mul, count }) => {
    
    
    // 文件加载成功~
    // eslint-disable-next-line
    console.log(mul(2, 5));
  })
  .catch(() => {
    
    
    // eslint-disable-next-line
    console.log('文件加载失败~');
  });

4、懒加载 预加载

// 懒加载:当文件需要使用时才加载
// 预加载 :会在使用之前,提前加载js文件
// 正常加载可以认为是并行加载(同一时间加载多个文件)
// 预加载 prefetch:等其他资源加载完毕,浏览器空闲了,再偷偷加载资源

import(/* webpackChunkName: 'test', webpackPrefetch: true */'./test').then(({
    
     mul }) => {
    
    
    console.log(mul(4, 5));
  });

5、PWA

PWA: 渐进式网络开发应用程序(离线可访问)
workbox --> workbox-webpack-plugin

 new WorkboxWebpackPlugin.GenerateSW({
    
    
      /*
        1. 帮助serviceworker快速启动
        2. 删除旧的 serviceworker

        生成一个 serviceworker 配置文件~
      */
      clientsClaim: true,
      skipWaiting: true
    })

猜你喜欢

转载自blog.csdn.net/cyadyx/article/details/106939850