tree shaking
-
什么是tree shaking
- tree shaking是一个计算机术语,表示消除死代码(dead_code)
- 最早的想法起源于LISP,用于消除未调用的代码(纯函数无副作用,可以放心的消除,这也是为什么我们在进行函数式编程的时候,尽量使用纯函数的原因之一)
- 后来tree shaking也被应用于其他的语言,比如javascript dart
-
javascript的tree shaking
- 对javascript进行tree shaking是源自于打包工具rollup
- 这是因为tree shaking依赖于ES Module的静态语法分析(不执行任何代码,可以明确知道模块的依赖关系)
- webpack2正式内置支持了ES2015模块和检测未使用模块的能力
- 在webpack4正式扩展了这个能力,并且通过package.json的sideEffects属性作为标记,告知webpack在编译时,哪里文件可以安全的删除掉
- webpack5中,也提供了对部分commonjs的他tree shaking的支持
-
webpack实现tree shaking
-
usedExports:通过标记某些函数是否被使用,之后通过terser来进行优化
-
将mode设置为development模式
- 为了可以看到 usedExports带来的效果,我们需要设置为 development 模式
- 因为在 production(默认usedExports:true,minimize:true)模式下,webpack默认的一些优化会带来很大影响
-
设置usedExports为true和false对比打包后的代码
-
在usedExports设置为true时,会有一段注释:unused harmony export mul
-
这段注释的意义是什么呢?告知Terser在优化时,可以删除掉这段代码
module.exports = { // 省略其他配置 mode:"development", optimization:{ // 作用是标注出来那些函数没有被使用 usedExports:true,// production模式下默认为true } }
-
-
这个时候,我们将minimize:设置true:
-
usedExports设置为false时,mul函数没有被移除掉
-
usedExports设置为true时,mul函数有被移除掉
module.exports = { // 省略其他配置 mode:"development", optimization:{ // 作用是标注出来那些函数没有被使用 usedExports:true,// production模式下默认为true minimize:true } }
-
-
-
sideEffects:跳过整个模块/文件,直接查看该文件是否有副作用
- sideEffects用于告知webpack compiler哪些模块是有副作用的
- 副作用的意思是这里面的代码有执行一些特殊的任务,不能仅仅通过export来判断这段代码的意义
-
在packagejjson中设置sideEffects的值
- 如果我们将sideEffects设置为false,就是告知webpack可以安全的删除未用到的exports
- 如果有一些我们希望保留,可以设置为数组
-
比如我们有一个formatjs、style.css文件
-
该文件在导入时没有使用任何的变量来接受
-
那么打包后的文件,不会保留format.is、style.css相关的任何代码
-
-
-
css的tree shaking
- 安装 purgecss插件
npm i purgecss-webpack-plugin -D - 配置 purgecss (生产环境)
- 安装 purgecss插件
const path = require('path')
const PurgeCssWebpackPlugin = require('purgecss-webpack-plugin');
// 一般不用单独安装,其他插件已经有安装,可直接使用
const glob = require("glob");
module.exports = {
mode:"production",
plugins:[
new PurgeCssWebpackPlugin({
// 表示匹配src目录下所有文件夹下的所有文件,不包含文件夹
paths:glob.sync(`${path.resolve(__dirname,'../src')}/**/*`,{nodir:true}),
safelist:function(){
return {
standard:["html","body"]
}
}
})
]
}
什么是HTTP压缩
-
HTTP压缩是一种内置在浏览器和客户端之间的,以改进传输速度和带宽利用率的方式
-
常见压缩格式
- compress -UNIX的“compress”程序的方法(历史性原因,不推荐大多数应用使用,应该使用gzip或deflate ) ;
- deflate -基于deflate算法(定义于RFC 1951的压缩),使用zlib数据格式封装;
- gzip-GNU zip格式(定义于RFC 1952),是目前使用比较广泛的压缩算法;
- br-一种新的开源压缩算法,专为HTTP内容的编码而设计,压缩程度很高,但是兼容性不太好;
-
HTTP压缩的流程是什么
-
第一步:HTTP数据在服务器发送前就已经被压缩了;(可以在webpack中完成)
-
第二步:兼容的浏览器在向服务端发送请求时,会告知服务器自己支持哪些压缩格式
-
第三步:服务器在浏览器支持的压缩格式下,直接返回对应的压缩后的文件,并且在响应头告知浏览器
-
-
webpack对文件进行HTTP压缩
- 安装插件
npm i compression-webpack-plugin -D
const CompressionPlugin = require('compression-webpack-plugin'); module.exports = { // 省略其他配置 plugins:[ // 一般情况下使用默认设置即可 new CompressionPlugin({ // 表示只有以css和js结尾的文件才被压缩 test:/\.(css|js)$/i, // 表示以哪种压缩方式进行压缩,默认是gzip algorithm:"gzip", // 表示文件大小大于这个值才被压缩,默认是0 threshold:0, // 表示 压缩后的文件大小/源文件大小小于这个值才会被压缩,默认是0.8 minRatio:0.8 }) ] } - 安装插件
HTML文件中代码压缩
- 我们之前使用了HtmlWebpackPlugin插件来生成HTML的模板,事实上它还有一些其他的配置
- inject:设置打包的资源插入的位置:true、 false 、body、 head
- cache:设置为true,只有当文件改变时,才会生成新的文件(默认值也是true)
- minify: 默认会使用一个插件html-minifier-terser,不需要单独下载