Open linwu-hi opened 1 year ago
随着前端的项目逐渐扩大,必然会带来的一个问题就是性能
尤其在大型复杂的项目中,前端业务可能因为一个小小的数据依赖,导致整个页面卡顿甚至奔溃
一般项目在完成后,会通过webpack进行打包,利用webpack对前端项目性能优化是一个十分重要的环节
webpack
通过webpack优化前端的手段有:
terser是一个JavaScript的解释、绞肉机、压缩机的工具集,可以帮助我们压缩、丑化我们的代码,让bundle更小
terser
JavaScript
bundle
在production模式下,webpack 默认就是使用 TerserPlugin 来处理我们的代码的。如果想要自定义配置它,配置方法如下:
production
TerserPlugin
const TerserPlugin = require('terser-webpack-plugin') module.exports = { ... optimization: { minimize: true, minimizer: [ new TerserPlugin({ parallel: true // 电脑cpu核数-1 }) ] } }
属性介绍如下:
CSS压缩通常是去除无用的空格等,因为很难去修改选择器、属性的名称、值等
CSS
CSS的压缩我们可以使用另外一个插件:css-minimizer-webpack-plugin
css-minimizer-webpack-plugin
npm install css-minimizer-webpack-plugin -D
配置方法如下:
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin') module.exports = { // ... optimization: { minimize: true, minimizer: [ new CssMinimizerPlugin({ parallel: true }) ] } }
使用HtmlWebpackPlugin插件来生成HTML的模板时候,通过配置属性minify进行html优化
HtmlWebpackPlugin
HTML
minify
html
module.exports = { ... plugin:[ new HtmlwebpackPlugin({ ... minify:{ minifyCSS:false, // 是否压缩css collapseWhitespace:false, // 是否折叠空格 removeComments:true // 是否移除注释 } }) ] }
设置了minify,实际会使用另一个插件html-minifier-terser
html-minifier-terser
对文件的大小进行压缩,减少http传输过程中宽带的损耗
http
npm install compression-webpack-plugin -D
new ComepressionPlugin({ test:/\.(css|js)$/, // 哪些文件需要压缩 threshold:500, // 设置文件多大开始压缩 minRatio:0.7, // 至少压缩的比例 algorithm:"gzip", // 采用的压缩算法 })
一般来说在打包之后,一些图片文件的大小是远远要比 js 或者 css 文件要来的大,所以图片压缩较为重要
js
css
module: { rules: [ { test: /\.(png|jpg|gif)$/, use: [ { loader: 'file-loader', options: { name: '[name]_[hash].[ext]', outputPath: 'images/', } }, { loader: 'image-webpack-loader', options: { // 压缩 jpeg 的配置 mozjpeg: { progressive: true, quality: 65 }, // 使用 imagemin**-optipng 压缩 png,enable: false 为关闭 optipng: { enabled: false, }, // 使用 imagemin-pngquant 压缩 png pngquant: { quality: '65-90', speed: 4 }, // 压缩 gif 的配置 gifsicle: { interlaced: false, }, // 开启 webp,会把 jpg 和 png 图片压缩为 webp 格式 webp: { quality: 75 } } } ] }, ] }
Tree Shaking 是一个术语,在计算机中表示消除死代码,依赖于ES Module的静态语法分析(不执行任何的代码,可以明确知道模块的依赖关系)
Tree Shaking
ES Module
在webpack实现Trss shaking有两种不同的方案:
Trss shaking
两种不同的配置方案, 有不同的效果
配置方法也很简单,只需要将usedExports设为true
usedExports
true
module.exports = { ... optimization:{ usedExports } }
使用之后,没被用上的代码在webpack打包中会加入unused harmony export mul注释,用来告知 Terser 在优化时,可以删除掉这段代码
unused harmony export mul
Terser
如下面sum函数没被用到,webpack打包会添加注释,terser在优化时,则将该函数去掉
sum
sideEffects用于告知webpack compiler哪些模块时有副作用,配置方法是在package.json中设置sideEffects属性
sideEffects
webpack compiler
package.json
如果sideEffects设置为false,就是告知webpack可以安全的删除未用到的exports
exports
如果有些文件需要保留,可以设置为数组的形式
"sideEffecis":[ "./src/util/format.js", "*.css" // 所有的css文件 ]
上述都是关于javascript的tree shaking,css同样也能够实现tree shaking
javascript
tree shaking
css进行tree shaking优化可以安装PurgeCss插件
PurgeCss
npm install purgecss-plugin-webpack -D
const PurgeCssPlugin = require('purgecss-webpack-plugin') module.exports = { ... plugins:[ new PurgeCssPlugin({ path:glob.sync(`${path.resolve('./src')}/**/*`), {nodir:true}// src里面的所有文件 satelist:function(){ return { standard:["html"] } } }) ] }
将代码分离到不同的bundle中,之后我们可以按需加载,或者并行加载这些文件
默认情况下,所有的JavaScript代码(业务代码、第三方依赖、暂时没有用到的模块)在首页全部都加载,就会影响首页的加载速度
代码分离可以分出出更小的bundle,以及控制资源加载优先级,提供代码的加载性能
这里通过splitChunksPlugin来实现,该插件webpack已经默认安装和集成,只需要配置即可
splitChunksPlugin
默认配置中,chunks仅仅针对于异步(async)请求,我们可以设置为initial或者all
module.exports = { ... optimization:{ splitChunks:{ chunks:"all" } } }
splitChunks主要属性有如下:
splitChunks
可以通过InlineChunkHtmlPlugin插件将一些chunk的模块内联到html,如runtime的代码(对模块进行解析、加载、模块信息相关的代码),代码量并不大,但是必须加载的
InlineChunkHtmlPlugin
chunk
runtime
const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin') const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { ... plugin:[ new InlineChunkHtmlPlugin(HtmlWebpackPlugin,[/runtime.+\.js/] }
关于webpack对前端性能的优化,可以通过文件体积大小入手,其次还可通过分包的形式、减少http请求次数等方式,实现对前端性能的优化
面试官:说说如何借助webpack来优化前端性能?
一、背景
随着前端的项目逐渐扩大,必然会带来的一个问题就是性能
尤其在大型复杂的项目中,前端业务可能因为一个小小的数据依赖,导致整个页面卡顿甚至奔溃
一般项目在完成后,会通过
webpack
进行打包,利用webpack
对前端项目性能优化是一个十分重要的环节二、如何优化
通过
webpack
优化前端的手段有:JS代码压缩
terser
是一个JavaScript
的解释、绞肉机、压缩机的工具集,可以帮助我们压缩、丑化我们的代码,让bundle
更小在
production
模式下,webpack
默认就是使用TerserPlugin
来处理我们的代码的。如果想要自定义配置它,配置方法如下:属性介绍如下:
CSS代码压缩
CSS
压缩通常是去除无用的空格等,因为很难去修改选择器、属性的名称、值等CSS的压缩我们可以使用另外一个插件:
css-minimizer-webpack-plugin
配置方法如下:
Html文件代码压缩
使用
HtmlWebpackPlugin
插件来生成HTML
的模板时候,通过配置属性minify
进行html
优化设置了
minify
,实际会使用另一个插件html-minifier-terser
文件大小压缩
对文件的大小进行压缩,减少
http
传输过程中宽带的损耗图片压缩
一般来说在打包之后,一些图片文件的大小是远远要比
js
或者css
文件要来的大,所以图片压缩较为重要配置方法如下:
Tree Shaking
Tree Shaking
是一个术语,在计算机中表示消除死代码,依赖于ES Module
的静态语法分析(不执行任何的代码,可以明确知道模块的依赖关系)在
webpack
实现Trss shaking
有两种不同的方案:两种不同的配置方案, 有不同的效果
usedExports
配置方法也很简单,只需要将
usedExports
设为true
使用之后,没被用上的代码在
webpack
打包中会加入unused harmony export mul
注释,用来告知Terser
在优化时,可以删除掉这段代码如下面
sum
函数没被用到,webpack
打包会添加注释,terser
在优化时,则将该函数去掉sideEffects
sideEffects
用于告知webpack compiler
哪些模块时有副作用,配置方法是在package.json
中设置sideEffects
属性如果
sideEffects
设置为false,就是告知webpack
可以安全的删除未用到的exports
如果有些文件需要保留,可以设置为数组的形式
上述都是关于
javascript
的tree shaking
,css
同样也能够实现tree shaking
css tree shaking
css
进行tree shaking
优化可以安装PurgeCss
插件代码分离
将代码分离到不同的
bundle
中,之后我们可以按需加载,或者并行加载这些文件默认情况下,所有的
JavaScript
代码(业务代码、第三方依赖、暂时没有用到的模块)在首页全部都加载,就会影响首页的加载速度代码分离可以分出出更小的
bundle
,以及控制资源加载优先级,提供代码的加载性能这里通过
splitChunksPlugin
来实现,该插件webpack
已经默认安装和集成,只需要配置即可默认配置中,chunks仅仅针对于异步(async)请求,我们可以设置为initial或者all
splitChunks
主要属性有如下:内联chunk
可以通过
InlineChunkHtmlPlugin
插件将一些chunk
的模块内联到html
,如runtime
的代码(对模块进行解析、加载、模块信息相关的代码),代码量并不大,但是必须加载的三、总结
关于
webpack
对前端性能的优化,可以通过文件体积大小入手,其次还可通过分包的形式、减少http请求次数等方式,实现对前端性能的优化参考文献