性能文章>webpack构建速度和体积优化策略>

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

153001

前言

对自己性能优化以及webpack优化进行总结,目前文章对webpack进行了描述,后续会对webpack之前的性能进行总结。

整体脑图如下: 

 

初级分析:使用webpack内置的stats

在package.json中使用stats

 "scripts": {
    "stats": "webpack --json > stats.json"
  },
通过npm run stats 即可生产stas.json文件,json文件内容包含了构建的统计信息

速度分析:使用speed-measure-webpack-plugin

使用webpack内置的stas分析,颗粒度比较粗,很难发现文件大小、构建速度的问题所在 使用speed-measure-webpack-plugin可以分析每个loader、plugin的耗时所在 

const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");

const **p = new SpeedMeasurePlugin();

const webpackConfig = **p.wrap({
  plugins: [new MyPlugin(), new MyOtherPlugin()],
});

体积分析: 使用webpack-bundle-****yzer 分析体积

const BundleAnalyzerPlugin = require('webpack-bundle-****yzer').BundleAnalyzerPlugin;

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

性能提升的方法(针对构建速度和体积优化)

使用高版本的 webpack 和 Node.js

webpack4刚出来时,和webpack3在推特上做了比较,webpack4的构建时间减低了60%-98%

使用webpack4的原因:

  1. V8带来的优化(for of 代替了forEach、Map和set代替了Object、includes代替indexOf)

  2. 默认使用更快的md4 hash算法 去替代 MD5

  3. webpacks AST 可以直接从loader传递给AST, 减少解析时间

  4. 使用字符串方法替代正则表达式

多进程、多实例:解析构建

可选方案:

  1. thread-loader(官方)
  2. parallel-webpack
  3. HappyPack

使用HappyPack去解析资源 原理:每次webpack解析一个模块,HappyPack会将它及它的依赖分配给worker线程中 webpack - HappyLoader - HappyPlguin (创建线程池) - HappyThreadPool - HappyThread[1...N] (各线程会处理各自负责的模块和依赖) - HappyWorkerChannel[1...N] - HappyWorker[1..N] (HappyPack工作流)

使用thread-loader去解析资源

原理:和HappyPack一致,每次webpack解析一个模块,thread-loader会将它及它的依赖分配给worker线程中

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        include: path.resolve('src'),
        use: [
          'thread-loader',
          // your expensive loader (e.g babel-loader)
        ],
      },
    ],
  },
};

如果需要配置three-loader可以通过配置项的形式

use: [
  {
    loader: 'thread-loader',
    // loaders with equal options will share worker pools
    options: {
      // the number of spawned workers, defaults to (number of cpus - 1) or
      // fallback to 1 when require('os').cpus() is undefined
      workers: 2,
 
      // number of jobs a worker processes in parallel
      // defaults to 20
      workerParallelJobs: 50,
 
      // additional node.js arguments
      workerNodeArgs: ['--max-old-space-size=1024'],
 
      // Allow to respawn a dead worker pool
      // respawning slows down the entire compilation
      // and should be set to false for development
      poolRespawn: false,
 
      // timeout for killing the worker processes when idle
      // defaults to 500 (ms)
      // can be set to Infinity for watching builds to keep workers alive
      poolTimeout: 2000,
 
      // number of jobs the poll distributes to the workers
      // defaults to 200
      // decrease of less efficient but more fair distribution
      poolParallelJobs: 50,
 
      // name of the pool
      // can be used to create different pools with elsewise identical options
      name: 'my-pool',
    },
  },
  // your expensive loader (e.g babel-loader)
];


多进程、多实例:并行压缩

方法一: 使用parallel-uglify-plugin插件

方法二:uglifyjs-webpack-plugin开启parallel参数 (webpack4.0以前推荐)

方法三:terser-webpack-plugin 开启parallel参数 (推荐)

module.exports = {
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        parallel: true, // parallel默认值是当前电脑环境CPU数量的2倍减1
      }),
    ],
  },
};

如果你使用的是 webpack v5 或以上版本,你不需要安装这个插件。webpack v5 自带最新的 terser-webpack-plugin。如果使用 webpack v4,则必须安装 terser-webpack-plugin v4 的版本

进一步分包:预编译资源模块

方法一:使用html-webpack-externals-plugin (例如将react,react-dom基础包通过cdn引入,不打入bundle中)

方法二:使用SplitChunksPlugin

方法三:使用DLLPlugin进行分包,DIIReferencePlugin对mainfest.json引用 (官方内置的插件)

一般先创建webpack.dll.js文件对公共基础包、业务基础包进行分包 然后在webpack.config.js通过

webpack.DllReferenctPlugin进行引用 

充分利用缓存提升二次构建速度

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

  1. babel-loader 开启缓存
  2. terser-webpack-plugin开启缓存
  3. 使用 cache-loader 或者 hard-source-webpack-plugin

缩小构建目标

目的:尽可能的少构建模块 比如babel-loader不解析node_modules

减少文件搜索范围

  1. 优化resolve.modules 配置 (减少模块搜索层级)
  2. 优化resolve.mainFields配置
  3. 优化resolve.extensions配置
  4. 合理使用alias (自己标记一下,还是不错的这个alias)

使用Tree Shaking 擦除无用的JavaScript和CSS

关于 tree shaking

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

使用:webpack默认支持,在.babelrc里面设置modules:false即可 production mode 的情况下默认开启

要求:必须是ES6语法,CJS的方法不支持

擦除无用的CSS

使用purgecss-webpack-plugin和mini-css-extract-plugin配合使用

const path = require('path');
const glob = require('glob')
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const SpeedMeasureWebpackPlugin = require('speed-measure-webpack-plugin');
const **p = new SpeedMeasureWebpackPlugin();
const BundleAnalyzerPlugin = require('webpack-bundle-****yzer').BundleAnalyzerPlugin;
const TerserPlugin = require("terser-webpack-plugin");
const webpack = require('webpack');
const PurgeCSSPlugin = require('purgecss-webpack-plugin')


const PATHS = {
    src: path.join(__dirname)
}

module.exports = **p.wrap({
    // 开发者工具 不需要开发调试
    devtool: false,
    // 开发模式 不进行代码压缩
    mode: 'development',
    // 入口文件
    entry: './index.js',
    output: {
      // 输出文件名称
      filename: 'bundle.js',
      // 输出文件路径
      path: path.join(__dirname, './'),
    },
    module: {
        rules: [
            {
                // 正则匹配后缀名为 .css 的文件
                test: /\.css$/,
                use: [MiniCssExtractPlugin.loader, 'css-loader'],
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin(),
        new PurgeCSSPlugin({
            paths: glob.sync(`${PATHS.src}/*`,  { nodir: true }),  // 只支持绝对路径
        }),
    ],
});
 

使用动态Polyfill服务

使用webpack进行图片压缩

使用image-webpack-loader

体积优化策略总结

  1. scope Hoisting
  2. Tree-shaking
  3. 公共资源分离
  4. 图片压缩
  5. 动态polyfill


作者:左耳咚

分类:标签:
请先登录,感受更多精彩内容
快去登录吧,你将获得
  • 浏览更多精彩评论
  • 和开发者讨论交流,共同进步

为你推荐

webpack5优化实战
本文围绕webpack优化进行讲述,其中也会作某些原理性地解释,尽量做到让大家知道为什么这么做,以及这么做的结果是什么。
玩转 webpack5(上)
前言本篇长文是学习程柳峰老师开设的《玩转 webpack》专栏的实践笔记,和专栏不一样的是,我的实战源码是基于 webpack5,它的配置和源码实现上与 webpack4 有许多不同的地方,感兴趣的同学可以结合我在上面放出的源码仓库进行学习,相信会有不小的收获。看完本篇长文,你将收获:能
使用 webpack 进行 Web 性能优化(三)
即使您配置 webpack 以使应用程序尽可能小,跟踪它并知道它包含什么仍然很重要。 否则,您可以安装一个使应用程序变大两倍的依赖项——甚至不会注意到它!本节介绍可帮助您了解捆绑包的工具。跟踪包大小要监控您的应用程序大小,请在开发期间使用 webpack-dashboa
使用 webpack 进行 Web 性能优化(二)
改善应用程序加载时间的下一件事(在优化应用程序大小之后)是缓存。 使用它将应用程序的某些部分保留在客户端上,并避免每次都重新下载它们。使用包版本控制和缓存标头进行缓存的常用方法:告诉浏览器将文件缓存很长时间(例如,一年): # Server headerCache-Contro
webpack构建速度和体积优化策略
前言对自己性能优化以及webpack优化进行总结,目前文章对webpack进行了描述,后续会对webpack之前的性能进行总结。整体脑图如下:  初级分析:使用webpack内置的stats在package.json中使用stats "scripts": {
领导:小伙子,咱们这个页面出来太慢了!赶紧给我优化一下!
性能优化这样一个词应该已经是老生常谈了,不仅在面试中面试官会以此和你掰头,而且在工作中领导也会因为网页加载速度慢来敲打你学(打)习(工),那么前端性能优化,如果判断到底需不需要做,如果需要做又怎么去做或者说怎么去找到优化的切入点? 接下来让我们一起来探索前端性能优化(emo~&n
我的第一次webpack优化,首屏渲染从9s到1s
大家好,我是考拉🐨,本文基于vue2(虽然vue3已出,但是本文也很实用)谈到webpack优化大部分人可能都看腻了,无非就那几招嘛,我之前也是看过许多类似的文章,但都没有自己真正上手过,下面是我用公司的项目真实操练下来的,首屏加载速度提升很大(刷刷的),希望能帮到你。废话不多说,先
微医对于webpack5持久化缓存优化的实践
导语 1、公司的云his静态项目代码量巨大,依赖的npm包大概有100个,打包一次大概要14分钟;2、自研的hammer工具的本地打包虽然能提升部署时间,但是依赖开发的手动操作;3、用来存放本地构建产物的服务器容量满了,所以为了正常使用本地打包功能,还得定期去清理服务器上的老文件,