webpack性能优化之Tree Shaking

77 阅读2分钟

一、Tree Shaking概念

Tree Shaking:消除未使用过的代码。

原理:依赖于ES模块的静态语法分析(在执行代码之前,也就是编译阶段,就可以确定模块的依赖关系,并生成模块依赖图,然后打包工具依据此来消除无用代码)

主要有两种方案来实现Tree Shaking:

二、usedExports实现

usedExports主要通过标记一些函数是否被使用,然后配合Terser进行优化。

尝试设置usedExports:true

//webpack.config.js
module.exports={
    mode:"development",//这里需要设置development模式,如果是production模式,webpack默认会优化一些
    ....
    
    optimization:{
        usedExports:true,
    }
}

math.js

function foo(n1, n2) {
  return n1 + n2;
}

function mul(n1, n2) {
  return n1 * n2;
}

export { foo, mul };


index.js

import { mul } from "./utils/math.js";

mul(2, 3)//只使用math.js文件中的mul函数

没有配置usedExports打包后

image.png

配置了usedExports打包后

image.png

可以明显看到多了一句/* unused harmony export foo */,用于标记告知Terser在优化时,可以删掉这段代码。

若要实现删除这段冗余代码,还需要配置Terser,配置如下

module.exports={
  mode:"development",
  
    ...
  optimization: {
    // treeshaking
    usedExports: true, //分析哪些模块也没有使用过
    
    // 压缩js,这个minize开启下面的Terser配置才能够生效
    minimize: true,
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          compress: {
            unused: true, //配合上面的usedExports达到treeshaking,表示没用的代码进行压缩删除
          }
        },
      }),
    ]
    }
}

这时候在进行打包

image.png

这里的o函数就是代码压缩后的mul函数,原本的foo相加功能的函数已经被删除了

注意:usedExports:true需要配合Terser来使用,可以将unused设置为false查看,此时tree shaking就不会生效,如下图

image.png

左边的o函数就是原本的foo函数,n函数就是原本的mul函数,设置了unused:false后,就不会进行tree shaking。

三、sideEffects实现

sideEffects用于告知webpack某些文件是否有副作用(不能删除的代码)实现的。

//package.json
{
    ...
    
	"sideEffects":false,	//文件都没有副作用,可以treeshaking
	
	//或者是一个数组,用于告知哪些模块具有副作用,可以保留
	"sideEffects":[
		'*.css'			//有时候css会通过import ”./css/main.css"导入,如果使用了tree shaking,那么css就不会打包进去,这时就需要在这里配置
		“./src/util/format.js”  //format.js文件有副作用不能删除
	]
}