手动配置 webpack(三) 之性能优化

webpack 性能优化

  • 开发环境性能优化
  • 生产环境性能优化

开发环境性能优化

  • 优化打包构建速度

HMR(热模块替换)

当我们修改某一个文件,但其它的文件都没有修改时,用 webpack 进行打包,会发现所有的 文件都会被重新打包。但是只修改某一个文件,却将所有的文件都打包,这样做反而是没有必要的。所以,我们就要做的是,那个文件进行了修改,再打包的时候只打印这个文件即可,所以我们就需要使用到 HMR(热模块替换)

常见的文件有三种:html、js 和 css

  • css文件,可以使用 HMR,因为 style-loader 内部实现了
  • js 文件,默认不使用 HMR,需要修改入口文件来监听其它 js 文件的变化,另外入口文件没有 HMR 功能,所以当入口文件改变时,所有的文件都会被重新编译
  • html 文件:当开启 HMR 功能后,html 文件改变不会被重新进行重新编译,需要在 entry 中加入 html 文件
if (module.hot) {
  // 一旦 module.hot 为true,说明开启了HMR功能。 --> 让HMR功能代码生效
  module.hot.accept('./print.js', function() {
    // 方法会监听 print.js 文件的变化,一旦发生变化,其他模块不会重新打包构建。
    // 会执行后面的回调函数
   	// 要监听改变的代码
  });
}

在这里插入图片描述
在这里插入图片描述

source-map

一种提供源代码到构建后代码映射技术,如果构建后代码出错了,通过映射可以追踪源代码错误的语句

生成位置是否有错误代码的原因是否有错误的位置
source-map外部
hidden-source-map外部不能准确追踪源代码错误位置,只提示构建后代码的错误位置
nosources-source-map外部没有
cheap-source-map外部源代码的错误位置,精确到行,提示该行全部出错
cheap-module-source-map外部有,nodule会将 loader 的 sourec-map 加入
inline-source-map内联
eval-source-map内联

生成文件内联和外部的区别

  • 外部生成单独的文件,内联没有
  • 内联构建速度更快

开发环境建议用:eval-source-map / eval-cheap-module-source-map

生产环境建议用 source-map / cheap-module-source-map
如果要隐藏代码可以用 nosources-source-map / hidden-source-map

nosources-source-map 的 hidden-source-map 区别:一个是半隐藏一个是全隐藏

在这里插入图片描述

oneOf

若多个配置有用到相同的loader,则只加载一个,减少资源消耗
但是oneOf中不能有两个配置处理同一种类型文件

const {
  resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
  entry: ['./src/index.js', './src/index.html'],
  output: {
    filename: './js/index.js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
        // 比如这里可以配置 eslint
      },
      {
        oneOf: [{
            test: /\.(css|less)$/,
            use: ['style-loader', 'css-loader', 'less-loader']
          },
          {
            test: /\.(png|svg|jpg|gif)$/,
            loader: 'url-loader',
            options: {
              limit: 8 * 1024,
              name: '[name][hash:10].[ext]',
              outputPath: 'imgs'
            }
          },
          {
            test: /\.html$/,
            loader: 'html-loader'
          },
          {
            exclude: /\.(html|css|less|js|png|jpg|svg|gif|png|jpg)$/,
            loader: 'file-loader',
            options: {
              name: '[hash:10][ext]',
              outputPath: 'static'
            }
          }
        ]
      }

    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ],
  mode: 'development',
  devServer: {
    contentBase: resolve(__dirname, 'build'),
    compress: true,
    open: true,
    port: 4000,
    hot: true,
    devtool: 'source-map'
  }
}

缓存

当某些文件已经加载后,再次加载时,不会重新加载,而是从缓存中读取已经加载过的文件

  • babel缓存 文件再次编译的时候会优先从缓存中取
  • 文件资源缓存
    • hash: 每次webpack构建时会生成一个唯一的hash值。问题:js和css会同时使用同一个hash值,当只改变一个文件时,重新打包会使缓存失效
    • chunkhash:根据chunk生成的hash值,如果打包来源于同一个chunk,那么hash值就一样。问题:js和css的值还是一样的,因为css是在js中被引入的,所以同属于一个chunk
    • contenthash:根据文件内容生成hash值,不同文件hash值一定不一样
module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'js/built.[contenthash:10].js',
    path: resolve(__dirname, 'build')
  },
  module: {
    rules: [
      {
       // eslint
      },
      {
        oneOf: [
          {
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            options: {
              presets: [
                [
                  '@babel/preset-env',
                  {
                    useBuiltIns: 'usage',
                    corejs: { version: 3 },
                    targets: {
                      chrome: '60',
                      firefox: '50'
                    }
                  }
                ]
              ],
              // 开启babel缓存
              // 第二次构建时,会读取之前的缓存
              cacheDirectory: true
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: 'css/built.[contenthash:10].css'
    }),
    new OptimizeCssAssetsWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: './src/index.html',
      minify: {
        collapseWhitespace: true,
        removeComments: true
      }
    })
  ],
  mode: 'production',
  devtool: 'source-map'
};

tree shaking

tree shaking: 去除无用代码

  • 使用es6模块化 2.开启production环境
    • package.json中的配置
    • “sideEffects”: false 所有代码没有副作用
    • 问题:可能会把css等直接引入但在js文件中没有使用的文件给抹去
    • “sideEffects”: ["*.css"] //css不被优化
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值