前言
每逢面试,首屏渲染性能优化是一个常见的话题,下面就自己知道的,记录一下
分析打包出来的文件
安装webpack-bundle-analyzer
这个插件,然后使用npm run build --report
输出项目打包情况,直观的比较哪个bundle
文件的大小,有针对性的进行模块化拆分
路由懒加载
在 router.js
文件中,原来的静态引用方式,如
import ShowBlogs from '@/components/ShowBlogs';
routes: [(path: 'Blogs'), (name: 'ShowBlogs'), (component: ShowBlogs)];
经过路由懒加载更改为,如下方式
代码语言:javascript复制routes:[
path: 'Blogs',
name: 'ShowBlogs',
component: () => import('./components/ShowBlogs.vue')
]
如果是在 vuecli 3
中,我们还需要多做一步工作 因为 vuecli 3
默认开启 prefetch
(预先加载模块),提前获取用户未来可能会访问的内容 在首屏会把这十几个路由文件,都一口气下载了
所以我们要关闭这个功能,在 vue.config.js
中设置
// vue.config.js
module.exports = {
chainWebpack: (config) => {
// 移除prefetch插件
config.plguins.delete('prefetch');
// 或者
// 修改它的选项
config.plugin('prefetch').tap((options) => {
options[0].fileBlacklist = options[0].fileBlacklist || [];
options[0].fileBlacklist.push(/myasyncRoute(.) ?.js$/);
return options;
});
},
};
一些 UI 框架按需加载,不要整个的引入
这里以饿了么 ui 为例:
原本的引进方式引进了整个包
代码语言:javascript复制import ElementUI from 'element-ui';
Vue.use(ElementUI);
如果只用了按钮,表单,分页,表格,提示等更改为
代码语言:javascript复制import {
Button,
Input,
Pagination,
Table,
TableColumn,
MessageBox,
} from 'element-ui';
Vue.use(Button);
Vue.use(Input);
Vue.use(Pagination);
Vue.prototype.$alert = MessageBox.alert;
注意 MessageBox
注册方法的区别,虽然用到了alert
,但并不需要引入 Alert
组件
在.babelrc / babel.config.js
文件中添加(vue-cli 3
要先安装 babel-plugin-component
)
plugins: [
[
'component',
{
libraryName: 'element-ui',
styleLibraryName: 'theme-chalk',
},
],
];
gzip 压缩
安装 compression-webpack-plugin
cnpm i compression-webpack-plugin -D
在 vue.congig.js
中引入并修改 webpack
配置
const CompressionPlugin = require('compression-webpack-plugin')
configureWebpack: (config) => {
if (process.env.NODE_ENV === 'production') {
// 为生产环境修改配置...
config.mode = 'production'
return {
plugins: [new CompressionPlugin({
test: /.js$|.html$|.css/, //匹配文件名
threshold: 10240, //对超过10k的数据进行压缩
deleteOriginalAssets: false //是否删除原文件
})]
}
}
注意:在服务器也要做相应的配置,如果发送请求的浏览器支持 gzip
,就发送给它gzip
格式的文件 如果服务器是用express
框架搭建的 只要安装一下 compression
就能使用,其他也类似
const compression = require('compression');
app.use(compression()); // 要放在所有其他中间件注册之前
- 首屏内容可以做静态缓存(
hash
强缓存的一个方案。比如hash cache control: max-age=1
年) - 首屏内联
css
渲染 - 图片懒加载(可以通过给
img
标签上添加loading=lazy
)来开启懒加载模式 - 使用字体图标代替小图片
- 图片尺寸大小控制适当
- 利用好
script
标签的async
和defer
这两个属性,功能独立且不要求马上执行的js
文件,可以加入async
属性,如果是优先级低且没有依赖的js
,可以加入defer
属性 - 前端做一些接口的缓存:缓存的位置有两个: 一个是内存,即赋值给运行时的变量,另一个是
localStorage
,比如签到日历(展示用户是否签到),可以缓存这样的接口到localStorage
,有效期是当天,或者有个列表页,我们总是缓存上次的列表内容到本地,下次加载时,我们先从本地读取缓存,并同时发起请求到服务器获取最新列表 - 页面使用骨架屏(元素进行占位)
- 使用
ssr
渲染:服务器性能一般都很好,那么可以在服务器先把vdom
计算完后,在输出给前端 - 引入
http2.0
,http2.0
对比http1.1
最主要的是提升是传输性能,在接口小而多的时候更加明显 - 选择先进的图片格式:使用
webP
的图片格式来代替现有的jpeg
和png
,当页面图片较多时,这点作用非常明显 - 利用好
http
压缩:即使是最普通的gzip
,也能把文件大小压缩不小
如果您有疑问,欢迎下方留言,一起学习交流~