1. 首屏速度
首屏速度包括 白屏时间 和 渲染页面
- 白屏时间包括资源申请和首屏js执行;
- 资源申请:html文件、css文件、(异步的)js文件
- js执行:例如,页面定义的
const getList = () ={}函数
- 渲染页面包括首屏数据请求和DOM渲染。
- 首屏数据请求:
onMounted(() => getList())拿到数据 - DOM渲染:将数据放在DOM中,可能会引起重排
1.1 白屏时间
1.1.1 资源加载时间
由于前端基本不会涉及到复杂的js计算,因此资源加载时间在整个白屏时间内占比最大。减少资源加载时间,一方面跟网络速度非常有关,在网速一定的情况下,优化资源体积是非常有效的策略。
1.1.1.1 打包工具
采用webpack、vite等打包工具,可以
1.1.1.2 异步加载
将首屏需要用到的资源优先加载,不需要用到的资源,等首屏需要的资源加载完成后再进行加载。 例如:在 src/router/index.js中,配置路由:
export const routes = [
{
path: '/',
redirect: '/project',
},
{
path: '/project',
name: 'project',
redirect: '/project/list',
children: [
{
path: 'list',
name: 'project-list',
component: () => import('../views/project/ProjectList.vue'),
},
],
},
]
() => import('../views/project/ProjectList.vue')就属于异步加载。只有在路由匹配到相应的path时,才会执行回调函数,加载相应的vue文件。
1.1.1.3 安装最新的支持treeshaking的依赖
支持treeshaking当然更好,例如我们常用的lodash,直接import { debounce } from 'lodash';或者import { _ } from 'lodash';就可以导入对应的方法,但是糟糕糟糕糟糕!还是有40k。
1.1.1.4 不使用第三方库
正如刚刚所说,引入一个深拷贝方法,可能就需要40k的体积。例如在项目环境背景下,只需要深拷贝一维数组(且为简单数据类型),使用
arr1 = [...arr]
// 或者
arr1 = arr.slice()
方法,就可以进行深拷贝。而无需引入第三方库。
1.1.1.5 小图片转成base64,大图片异步加载
图片体积比较小的时候,可以将图片格式转化为base64格式,并且包入js中,减少请求资源的次数;在图片体积比较大的时候,就异步加载图片。
// webpack.config.js for Webpack 5
const path = require('path');
module.exports = {
// ... 其他配置 ...
module: {
rules: [
{
test: /\.(png|jpe?g|gif)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 8192, // 8KB 以下的图片会被转换为 base64 格式
},
},
generator: {
filename: 'images/[name].[hash:8][ext]', // 文件名格式
},
},
// ... 其他规则 ...
],
},
// ... 其他配置 ...
};
1.1.2 首屏JS执行
1.2 渲染页面
1.2.1 首屏发送数据请求
1.2.2 DOM渲染
1.3 其它
还有一些收效较小的方法,例如:
- 显示骨架屏(在index.html文件中,加入骨架)
<body>
<div id="app">
<span style="color:pink">祝您2024龙年大吉~</span>
</div>
<script type="module" src="/src/main.js"></script>
</body>
- 将小数据量接口合并到其它接口(接口时间包括三次握手的时间,不够划算)
- 请求并行
- 包含大量dom情况下分批滚动渲染
2.操作速度、渲染速度
2.1 一次性操作大量dom
分批渲染,虚拟滚动,切片渲染等
2.2 不进行进行了复杂度很高的运算
循环中的操作尽量精简(其实意义不大)
2.3 vue和react的渲染性能
使用react相关技术栈