优化

文章目录
  1. 1. 大小优化
    1. 1.1. tree-shaking
    2. 1.2. code splitting
    3. 1.3. CDN
    4. 1.4. 其它
  2. 2. 时间优化
    1. 2.1. 调试
    2. 2.2. 获取和解析依赖的时间
    3. 2.3. 打包时间
    4. 2.4. 压缩时间
    5. 2.5. 二次打包的时间

首先使用工具检查哪一部分需要优化【参考资料

大小优化

webpack-bundle-analyzer: 查看打包后各模块体积大小

tree-shaking

# 这两种模式都会开启tree-shaking
webpack --mode production
webpack --optimize--minimize
  • tree-shaking必须要使用import来按需引用,require不支持;比如关闭babel的modules编译模式,防止import被编译成require导致webpack的tree-shaking失效

    // .babelrc
    {
    "presets": [
    "env", { "modules": false }
    ]
    }
  • 减少使用IIFE/立即函数调用

  • 适时设置packsge.jsonsideEffects:false,删掉无影响的副作用代码;”没有副作用”这个短语可以被解释为”不与顶层模块以外的东西进行交互”(比如没有设置window变量);在b模块中虽然有一些副作用的代码(IIFE和更改全局变量/属性的操作),但是我们不认为删除它是有风险的,比如console.log;【参考资料

code splitting

  • entry vendor: 指定包名称来拆分公共代码 【参考资料
  • split chunk: 更细粒度地拆分公共代码,比如按使用次数【参考资料
  • css-extract
  • 对于react-router这类SPA项目来说,可以结合import()来做代码拆分并动态加载;

CDN

参考资料

{
externals: {
jquery: 'jQuery',
},
plugins: [
new HtmlWebpackPlugin({({
title: 'Custom template',
template: 'index.html',
files: {
js: [
'https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js',
],
}
})
]
}

其它

  • 按需引入
  • 压缩

时间优化

调试

获取和解析依赖的时间

{
noParse: /jquery/, // 不处理jquery,也可以将其抽到cdn

resolve: {
modules: [ // 指定require查找路径
path.resolve('src'),
path.resolve('node_modules'),
],

// 不带后缀的引用仅尝试以下值
extension: ['.js']
},

alias: {
utils: path.resolve('src/utils'),
},

... {
// loader优化
rules: {
...,
exclude: /node_modules/,
}
}

}

打包时间

happypack: 并行打包loader;

plugins = [
new HappyPack({
// 需要并行执行的loader
loaders: [ 'babel-loader?presets[]=es2015' ]
})
];

webpack4中使用thread-loader

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

压缩时间

  • webpack3中
    • UglifyJsPlugin单线程压缩
    • ParallelUglifyPlugin多线程压缩
  • webpack4中默认使用terser-webpack-plugin
    module.exports = {
    optimization: {
    minimizer: [
    new TerserPlugin({
    parallel: true,
    }),
    ],
    },
    };

二次打包的时间

cache-loader

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

HardSourceWebpackPlugin,可以代替cache-loader

{
plugins: [
new HardSourceWebpackPlugin({
// Either a string of object hash function given a webpack config.
configHash: function(webpackConfig) {
// node-object-hash on npm can be used to build this.
return require('node-object-hash')({sort: false}).hash(webpackConfig);
},
// lockfile发生变化会重新打包, Either false, a string, an object, or a project hashing function.
environmentHash: {
root: process.cwd(),
directories: [],
files: ['package-lock.json', 'yarn.lock'],
},
// An object.
info: {
// 'none' or 'test'.
mode: 'none',
// 'debug', 'log', 'info', 'warn', or 'error'.
level: 'debug',
},
// Clean up large, old caches automatically.
cachePrune: {
// Caches younger than `maxAge` are not considered for deletion. They must
// be at least this (default: 2 days) old in milliseconds.
maxAge: 2 * 24 * 60 * 60 * 1000,
// All caches together must be larger than `sizeThreshold` before any
// caches will be deleted. Together they must be at least this
// (default: 50 MB) big in bytes.
sizeThreshold: 50 * 1024 * 1024
},
}),
]
}