📌
前端优化主要就是做两件事: 1:优化用户体验即减少首屏加载时间,提升交互的流畅度,如表单验证和页面切换
2:优化开发体验:减少构建耗时,自动化完成一些重复工作,解放生产力,脚手架就是代表产物,如WebPack提供最主要的优化手段splikChunksPlugin提取公共代码,按需加载
分析工具
- speed-measure-webpack-plugin,可以测量网页包构建速度,并会输出各个模块编译时长,可以帮我们更好的找到耗时模块
在vue.config.js里面配置
module.exports = {
...,
configureWebpack: () => {
config.plugins.push(
new SpeedMeasurePlugin()
)
}
}
- webpack-bundle-analyzer,这个插件在可视化网页包中输出文件的大小,并且提供了交互式可缩放的树形图
在vue.config.js中配置
module.exports = {
...,
configureWebpack: () => {
config.plugins.push(
new BundleAnalyzerPlugin()
)
}
}, vue-cli3已结内置,在package里面的serve代码命令里面加--report即可
优化
- 按需引入,echart这些实现按需引入
import * as echarts from 'echarts/core'
import {BarChart, LineChart} from 'echarts/charts'
// 引入组件
import {TitleComponent, TooltipComponemt, GridComponent, LegendComponent, MarkPointComponent, ToolboxComponent} from 'echarts/components'
// 引入渲染函数
import {CanvasRenderer} from 'echarts/renderers'
echarts.use([
BarChart, LineChart, TitleComponent, TooltipComponemt, GridComponent, LegendComponent, MarkPointComponent, ToolboxComponent,CanvasRenderer
])
- moment包可以使用day包替换或者移除语言包
module.exports = {
...,
configureWebpack: (config) => {
config.plugins.push(
new MomentLocalesWebpackPlugin()
)
}
}
- 使用缓存,
-
- cache-loader
- hard-source-webpack-plugin,WebPack5内置了
- babel-loader的CacheDirectory标志
以上的缓存都有首次启动时的开销,即他们会让“冷启动”时间会更长,但是二次启动能够节省很多时间。
vue-cli已结内置cache-loader和babel-loader的CacheDirectory标志,我们只需配置hard-source-webpack-plugin插件
module.exports = {
...,
configureWebpack: (config) => {
config.plugins.push(
// 为模块提供中间缓存,缓存路径是:node_modules/.cache/hard-source
// 解决为配置到的配置更改
new HardSourceWebpackPlugin(
root: process.cwd(),
directories: [],
// 配置files的主要原因是解决配置更新,cache不生效了的问题,配置后有包的变化,会重新构建一部分cache
files: ['package.json','package-lock']
))
}
}
- 减小打包体积
-
- 减小js体积,通过terser-webpack-plugin插件来删除注释和压缩js代码,vue-cli默认配置压缩
- 对图片压缩,通过image-webpack-plugin或image-minimizer-webpack-plugin进行图片资源的压缩
- 外部扩展--externals & cdn,externals选项就是用于防止将某些import的包打包到bundle中,即cdn资源,在代码运行时再去请求这个资源
- 删除prefetch,避免占用过多的宽带
- gzip压缩,让后端配置支持,只需配置生产环境,不然开发调试不方便
module.exports = {
...,
chainWebpack: (config) => { config.plugins.delete('prefetch'); config.plugins.delete('preload');}
configureWebpack: (config) => {
config.plugins.push(
new CompressionPlugin({
algorithm: 'gzip', // 请求返回类型里content-encoding: gzip
test: /.js$|.html$|.css/,
threshold: 10240, // 超过10kb进行压缩
minRatio: 0.8, //只有压缩率比小于这个值的资源才会被处理
deleteOriginaAssets: false, //不删除源文件,当压缩文件找不到还可以找到源文件
}))
}
}
- DLLPlugin插件,优化打包事件,将那些比较稳定的库进行打包拆分bundles,下次再打包时就不需要重复进行打包,因此大幅度提升构建的速度,但WebPack4或以上不推荐使用,使用splitChunk来进行拆包
- splitChunks切片和切片原则
1:node_modules 中的文件还是打包进 chunk-vendors,被引用得太多,已经难以改成按需加载,而且变动频率低,可以作为浏览器缓存(304)长期不失效。
2:被引用少且体量大的文件单独分一个chunk。
3:其它公共代码分成多个chunk,这样可以避免从某个入口访问时下载全部公共代码,以及部分代码变动时不会导致全部公共代码的缓存失效。
4:体量很小的异步chunk合并进其它相关异步chunk中,或者合并进入口chunk。
export const chainWebpack = (config: IWebpackChainConfig) => {
config.optimization
.runtimeChunk(false)
.splitChunks({
chunks: 'async',
minSize: 0,
cacheGroups: {
//这里会继承splitChunks下的配置和默认配置,如 上面的 chunks:"all"
//下面的配置优先级更高,会覆盖上面的配置,如 chunks:"initial"
//因为 webpack4 的零配置,会有很多默认配置,所以对于细节和实际未知的项目编译结果时,务必确定并理解默认值的具体逻辑,以排查问题所在。(之前踩过不少坑~)
libs: {
name: 'chunk-libs', //包名称,会和hash值编译生成最终 chunk-libs.8880c0aa.js (hash值会变化,对于缓存优化这里是可以思考的一个点。)
test: /[\/]node_modules[\/]/, // 正则过滤依赖包
priority: 10, //设置包的打包优先级
chunks: 'initial' //all 、async、initial
}
vantUI: {
name: 'chunk-vantUI',
priority: 20,
test: /[\/]node_modules[\/]_?vant(.*)/
},
echarts: {
name: 'chunk-echarts',
priority: 20,
test: /[\/]node_modules[\/]_?echarts(.*)/
},
commons: {
name: 'chunk-commons',
test: resolve('src/components'),
minChunks: 3,
priority: 5,
reuseExistingChunk: true
}
}
})
}
- 其他优化
-
- resolve.alias & resolve.extensions,一个是创建别名,一个是简化后缀,方便开发