chunk-vendors.js 优化
本文介绍先拆分后压缩的方式优化 `chunk-vendors.js`,减少 `FCP` 首屏加载时常
前言
本文介绍先拆分后压缩的方式优化 chunk-vendors.js
,减少 FCP
首屏加载时常
首屏加载可以说是用户体验中最重要的环节
FCP
FCP 定义
FCP
( First Contentful Paint ) 指的是浏览器从响应用户输入网址地址,到首屏内容渲染完成的时间,此时整个网页不一定要全部渲染完成,但需要展示当前视窗需要的内容
FCP长的可能原因
- 网络太差
- 资源文件体积过大
- 同一个资源重复发送请求
- 外部js文件引入或行内js代码放在了前面,导致需要先执行js,进而引起页面渲染阻塞
优化FCP的常用手段
1. 采用路由懒加载 (已经采用)
将
import UserDetails from './views/UserDetails.vue'
替换成
const UserDetails = () => import('./views/UserDetails.vue')
const router = createRouter({
// ...
routes: [
{ path: '/users/:id', component: UserDetails }
// 或在路由定义里直接使用它
{ path: '/users/:id', component: () => import('./views/UserDetails.vue') },
],
})
2. 静态资源本地缓存
合理利用本地缓存localStorage
HTTP缓存, 设置cache-control、Etag和Last-Modified
Service Worker缓存,它是一种利用Service Worker API实现的离线缓存功能,它可以使用户在离线的情况下访问网站内容,从而提高用户体验
3. 尽可能采取按需引入资源 (新采用)
像element UI、Ant Design、ECharts等都是支持按需引入的,不把整个库直接引进来,能有效降低项目体积
4. 避免组件重复打包
在webpack的config文件中,修改CommonsChunkPlugin的配置
minChunks为3表示会把使用3次及以上的包抽离出来,放进公共依赖文件,避免了重复加载组件
CommonsChunkPlugin:{ miniChunks: 3}
5. 对图片资源进行压缩
图片资源是http请求里比较大的一个消耗,应该进行适当的压缩,对于一些icon,可以使用在线字体图标,比如阿里巴巴的矢量图标库
6. 开启Gzip压缩
GZip压缩能把资源体积压缩到只有原本的30%左右,如果项目够大,这个优化效果是非常可观的
7. 使用SSR
服务端渲染,在服务端生成好html字符串,再发送到浏览器,服务端计算速度肯定会比浏览器快,也是减少首屏时间的一个好方法,vue2和Vue3都推荐用Nuxt来实现ssr
更全的优化方案,请参考
量化优化指标
安装 web-vitals
yarn add web-vitals
// 或者
npm install web-vitals
在 App.vue 加入 web-vitals
性能监控指标并打印
import {onLCP, onINP, onCLS, onTTFB} from 'web-vitals/attribution';
// Measure and log LCP as soon as it's available.
onLCP(console.log);
onINP(console.log);
onCLS(console.log);
onTTFB(console.log);
网页的FCP指数降到poor
的水平
chunk-vendors.js 简介
chunk-vendors.js
顾名思义 chunk
(块 / 包) - vendors
(供应商),即为:不是自己写的模块包,也就是/node_modules项目目录的所有模块包,它们称为第三方模块或供应商模块。
chunk-vendors.js 文件大小分析
测试环境
Chrome Dev Tools的 Network
标签页请求 chunk-vendors.js
文件,大小是4.5MB
虽然Time
显示只有793毫秒
生产环境
Chrome Dev Tools的 Network
标签页请求 ‘chunk-vendors.js’ 文件,被拆分成好几个单独的问题,最大的也占1.2MB
加载时间是425毫秒
总结
以上两种情况实在内网本机,访问速度相对快,如果到了外网就跟服务器带宽,性能有关了。文件这么大,加载又慢,我们在这篇文章就介绍两种方案,先拆分再压缩。
方案
1. 拆分
附带还未进行分块分包加载时,打包得到的文件目录
修改 vue.config.js
的 configureWebpack.optimization.splitChunks
选项如下
// 看这里:把chunk-vendors.js进行分包,提升资源加载速度,很有必要
module.exports = {
// 其他配置
configureWebpack: {
plugins: [],
optimization: {
/**
* runtimeChunk可选值有:true或'multiple'或'single'
* true或'multiple'会有每个入口对应的chunk。不过一般情况下
* 考虑到要模块初始化,设置为single就够多数情况下使用啦。
* 详情见官网:https://webpack.docschina.org/configuration/optimization/#optimizationruntimechunk
* */
runtimeChunk: 'single',
/**
* 以前是CommonsChunkPlugin,现在换成optimization.splitChunks。普通项目下方的配置就足够用啦
* 详情见官网:https://webpack.docschina.org/configuration/optimization/#optimizationsplitchunks
* */
splitChunks: {
chunks: 'all', // 可选值:all,async 和 initial。all功能最强大,所以咱们就使用all
maxInitialRequests: Infinity, // 最大并行请求数,为了以防万一,设置无穷大即可
minSize: 20000, // 引入的模块大于20kb才做代码分割,官方默认20000,这里不用修改了
maxSize: 60000, // 若引入的模块大于60kb,则告诉webpack尝试再进行拆分
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/, // 使用正则匹配node_modules中引入的模块
priority: -10, // 优先级值越大优先级越高,默认-10,不用修改
name(module) { // 设定分包以后的文件模块名字,按照包名字替换拼接一下
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]
return `npm.${packageName.replace('@', '')}`
},
},
},
}
}
}
}
打包后的目录如下:
2. 压缩
compression-webpack-plugin 插件压缩
安装 compression-webpack-plugin
yarn add compression-webpack-plugin --save-dev
遇到报错 "compression-webpack-plugin@11.1.0: The engine "node" is incompatible with this module."
安装报错解决方案
方案一:安装与当前项目的node版本适配的 compression-webpack-plugin@6.1.1
,提示安装成功
方案二:升级node版本
未采取
方案三:忽略引擎版本检查
设置 ignore-engines=true
修复版本不兼容的问题。
yarn config set ignore-engines true
未采取
配置 compression-webpack-plugin
修改vue.config.js的configureWebpack.plugins选项,如下:
const CompressionPlugin = require('compression-webpack-plugin'); //引入gzip压缩插件
module.exports = {
// 其他配置
configureWebpack: {
plugins: [
new CompressionPlugin({ //此插件不能使用太高的版本,否则报错:TypeError: Cannot read property 'tapPromise' of undefined
// filename: "[path][base].gz", // 这种方式是默认的,多个文件压缩就有多个.gz文件,建议使用下方的写法
filename: '[path].gz[query]', // 使得多个.gz文件合并成一个文件,这种方式压缩后的文件少,建议使用
algorithm: 'gzip', // 官方默认压缩算法也是gzip
test: /\.js$|\.css$|\.html$|\.ttf$|\.eot$|\.woff$/, // 使用正则给匹配到的文件做压缩,这里是给html、css、js以及字体(.ttf和.woff和.eot)做压缩
threshold: 10240, //以字节为单位压缩超过此大小的文件,使用默认值10240吧
minRatio: 0.8, // 最小压缩比率,官方默认0.8
//是否删除原有静态资源文件,即只保留压缩后的.gz文件,建议这个置为false,还保留源文件。以防:
// 假如出现访问.gz文件访问不到的时候,还可以访问源文件双重保障
deleteOriginalAssets: false
})
]
}
}
打包后,出现了.zip文件,目录列表如下
后端配置之nginx配置
server {
listen 80;
server_name localhost;
location / {
try_files $uri $uri/ /index.html;
root C:/nginx-1.18.0/html/gzip/dist;
index index.html index.htm;
}
location /api/ {
proxy_pass http://localhost:6666/;
}
# 主要是下方的gizp配置哦,直接复制粘贴就可以使用啦,亲测有效哦
gzip on; # 开启gzip压缩
gzip_min_length 4k; # 小于4k的文件不会被压缩,大于4k的文件才会去压缩
gzip_buffers 16 8k; # 处理请求压缩的缓冲区数量和大小,比如8k为单位申请16倍内存空间;使用默认即可,不用修改
gzip_http_version 1.1; # 早期版本http不支持,指定默认兼容,不用修改
gzip_comp_level 2; # gzip 压缩级别,1-9,理论上数字越大压缩的越好,也越占用CPU时间。实际上超过2的再压缩,只能压缩一点点了,但是cpu确是有点浪费。因为2就够用了
# 压缩的文件类型 MIME类型,百度一下,一大把 # css # xml # 识别php # 图片
gzip_types text/plain application/x-javascript application/javascript text/javascript text/css application/xml application/x-httpd-php image/jpeg image/gif image/png application/vnd.ms-fontobject font/x-woff font/ttf;
# text # 早期js # js # js的另一种写法 # .eot字体 # woff字体 # ttf字体
gzip_vary on; # 是否在http header中添加Vary: Accept-Encoding,一般情况下建议开启
}
和后端确认了,nginx配置是开启了gzip压缩的
更多推荐
所有评论(0)