webpack构建速度和体积优化策略

一. 都有哪些策略?

  1. Scope Hoisting
  2. Tree-sharking
  3. 公共资源分离
  4. 图片压缩
  5. 动态Polyfill

二. 具体是什么,有哪些细节?

1. 初级分析:使用webpack内置的stats(构建的统计信息)

2. 速度分析:使用spees-measure-webpack-plugin

用法如下:

const SpeedMeasureWebpackPlugin = require(‘speed-measure-webpack-plugin’);
const smp = new SpeedMeasureWebpackPlugin();
const webpackConfig = smp.wrap({
    plugins: [
        new Myplugin(),
        new MyOtherPugin()
    ]
})

可以看到每个loader和插件执行耗时
为什么要用速度分析插件?

  1. 为了分析整个打包耗时
  2. 分析每个插件和loader的耗时情况

3. 体积分析:使用web pack-bundle-analyzer

代码示例:

const BundleAnalyzerPlugin = require(“webpack-bundle-analyzer”)
  .BundleAnalyzerPlugin;

module.exports = {
  plugins: [new BundleAnalyzerPlugin()()]
};

可以分析哪些问题?

  1. 依赖的第三方模块文件大小
  2. 业务里面的组件代码大小

4. 使用更高版本的webapck和node.js

webpack4相比较webpack3构建时间降低了60%-80%;

webpack4做了哪些优化?
  1. V8带来的优化(for of 替代forEach 、 Map和Set替代 Object,includes替代indexOf)
  2. 默认使用更快算法的md4 hash算法
  3. webpack AST可以直接从loader传递给AST,减少解析时间
  4. 使用字符串方法替代正则表达式。

5. 多进程/多实例构建

  1. 使用HappyHack解析资源
  2. 使用 thread-loader解析资源
  3. 并行压缩

6. 分包

  1. 设置Externals
  2. 预编译资源模块

7.缓存

目的:提升二次构建速度
缓存思路:

  1. babel-loader开启缓存
  2. Terser-webpack-plugin开启缓存
  3. cahcher-loader或者hard-source-webpack-plugin

8.缩小构建目标

目的:尽可能的少构建模块

  1. 比如babel-loader不解析node_modules
module.exports = {
    rules: [
        test: /\.js$/,
        loader: ‘happypack/loader’,
        // 不解析node_modules
        exclude: ‘node_modules’
    ]
}
  1. 减少文件搜索范围
module.exports = {
    resolve: {
        alias: {
          ‘react’: path.resolve(__dirname, ‘./node_modules/react/umd/react.production.min.js’),
        // 减少模块搜索层级
        modules: [path.resolve(__dirname, 'node_modules')],
        extensions: ['.js'],
        mainFields: ['main']
    }
}

9. 使用Tree Shaking擦除无用的js和css

什么是tree shaking?

1个模块可能有多个方法,只要其中的某个方法使用到了,则整个文件都会被打到bundle里面,tree shaking 就是只把用到的方法打入bundle,没用到的方法在uglify阶段擦除掉。(也就是按需打包使用到的方法)

无用的css如何删除?

  1. PurifyCss: 遍历代码,识别已经用到的css class
  2. uincss : html需要通过jsdom加载,所有的样式通过PostCSS解析,通过document.querySelector来识别在html文件里面不存在的选择器

10. 图片压缩

使用imagemin或者tinypng API,通过配置image-webpack-loader即可。

{
        test: /.(png|jpg|gif|jpeg)$/,
        use: [
          {
            loader: “file-loader”,
            options: {
              name: “[name]_[hash:8].[ext]”
            }
          },
          {
            loader: “image-webpack-loader”,
            options: {
              mozjpeg: {
                progressive: true,
                quality: 65
              },
              // optipng.enabled: false will disable optipng
              optipng: {
                enabled: false
              },
              pngquant: {
                quality: "65-90",
                speed: 4
              },
              gifsicle: {
                interlaced: false
              },
              // the webp option will enable WEBP
              webp: {
                quality: 75
              }
            }
          }
        ]
      }

imagemin的优点:

  1. 有很多定制选项
  2. 可以引入更多的第三方优化插件
  3. 可以处理多种图片格式

imagemin的压缩原理

  1. pngquant:是一款PNG压缩器,通过将图像转换为具有alpha通道(通常比24/32位PNG文件小60%-80%) 的更高效的8位PNG格式,可显著减小文件大小。
  2. Pngcrush: 其主要目的是通过尝试不同的压缩级别和PNG过滤方法来降低PNG IDAT数据流的大小。
  3. optipng: 其设计灵感来自于pngcrush.optinpng可将图像文件重新压缩为更小尺寸,而不会丢失任何信息。
  4. tinypng: 将24位PNG文件转换为更小有索引的8位图片,同时所有非必要的metadata也会被剥离

11. 使用动态Polyfill服务:Polyfill Service

Polyfill Service原理:识别不同的user agent,下发不同的Polyfill

如何使用?

  1. polyfill.io官方提供服务,网址如下:https://polyfill.io/v3/polyfill.min.js
  2. 基于官方自建polyfill服务:(网址换成自己的网址即可)

三:这一章跟你有什么关系?

这一章是webpack的进阶用法,提出了在拥有基本webpack配置的情况下如何更优秀。是高级前端用的到工程化优化方案。
通过学习这一章,我意识到webapck社区也是真的强,现在场景下的需求基本都有对应的loader和插件可供使用。
前端工程化,webpack值得好好深入学习。

你可能感兴趣的:(webpack构建速度和体积优化策略)