前端性能优化

前端性能优化

1、提升首屏的加载速度,是前端性能优化中最重要的环节,这里笔者梳理出一些常规且有效的首屏优化建议。

2、目标: 通过对比优化前后的性能变化,来验证方案的有效性,了解并掌握其原理。

路由懒加载

SPA 项目,一个路由对应一个页面,如果不做处理,项目打包后,会把所有页面打包成一个文件,当用户打开首页时,会一次性加载所有的资源,造成首页加载很慢,降低用户体验。

将路由全部改成懒加载:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const routes = [
{
path: '/',
name: 'Home',
// 路由级代码分解
// 这将为该路由生成一个单独的块(home.[hash].js)
// 它在访问路由时是懒加载的。
component: () => import(/_ webpackChunkName: "home" _/ '../views/home.vue'),
},
{
path: '/test',
name: 'test',
component: () => import(/_ webpackChunkName: "test" _/ '../views/test.vue'),
},
];

重新打包后的 home.js 和 app.js 的文件大小会发生变化,通过路由懒加载,能将项目的首页资源大幅度压缩,减少首页白屏时间

组件懒加载

除了路由的懒加载外,组件的懒加载在很多场景下也有重要的作用。

举个 🌰:

home 页面 和 about 页面,都引入了 dialogInfo 弹框组件,该弹框不是一进入页面就加载,而是需要用户手动触发后才展示出来。

home 页面示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
<div class="homeView">
<p>home 页面</p>
<el-button @click="dialogVisible = !dialogVisible">打开弹框</el-button>
<dialogInfo v-if="dialogVisible" />
</div>
</template>
<script>
import dialogInfo from '@/components/dialogInfo';
export default {
name: 'homeView',
components: {
dialogInfo,
},
};
</script>

项目打包后,发现 home.js 和 about.js 均包括了该弹框组件的代码(在 dist 文件中搜索 dialogInfo 弹框组件)。

当用户打开 home 页时,会一次性加载该页面所有的资源,我们期望的是用户触发按钮后,再加载该弹框组件的资源,这种场景下,就很适合用懒加载的方式引入。

弹框组件懒加载:

1
2
3
4
5
6
7
8
9
<script>
const dialogInfo = () => import(/* webpackChunkName: "dialogInfo" */ '@/components/dialogInfo');
export default {
name: 'homeView',
components: {
dialogInfo
}
}
</script>

重新打包后,home.js 和 about.js 中没有了弹框组件的代码,该组件被独立打包成 dialogInfo.js,当用户点击按钮时,才会去加载 dialogInfo.js 和 dialogInfo.css。

最终,使用组件路由懒后,该项目的首页资源进一步减少。

组件懒加载的使用场景

有时资源拆分的过细也不好,可能会造成浏览器 http 请求的增多。

总结出三种适合组件懒加载的场景:

1)该页面的 JS 文件体积大,导致页面打开慢,可以通过组件懒加载进行资源拆分,利用浏览器并行下载资源,提升下载速度(比如首页)。

2)该组件不是一进入页面就展示,需要一定条件下才触发(比如弹框组件)。

3)该组件复用性高,很多页面都有引入,利用组件懒加载抽离出该组件,一方面可以很好利用缓存,同时也可以减少页面的 JS 文件大小(比如表格组件、图形组件等)。

长列表虚拟滚动

首页中有需要渲染长列表的场景,当渲染条数过多时,所需要的渲染时间会很长,滚动时还会造成页面卡顿,整体体验非常不好。

虚拟滚动——指的是只渲染可视区域的列表项,非可见区域的不渲染,在滚动时动态更新可视区域,该方案在优化大量数据渲染时效果是很明显的。

虚拟滚动基本原理:

计算出 totalHeight 列表总高度,并在触发时滚动事件时根据 scrollTop 值不断更新 startIndex 以及 endIndex ,以此从列表数据 listData 中截取对应元素。

虚拟滚动插件

虚拟滚动的插件有很多,比如 vue-virtual-scroller、vue-virtual-scroll-list、react-tiny-virtual-list、react-virtualized 等。

这里简单介绍 vue-virtual-scroller 的使用:

// 安装插件
npm install vue-virtual-scroller

// main.js
import VueVirtualScroller from ‘vue-virtual-scroller’
import ‘vue-virtual-scroller/dist/vue-virtual-scroller.css’

Vue.use(VueVirtualScroller)

// 使用

1
2
3
4
5
6
7
8
9
10
<template>
<RecycleScroller
class="scroller"
:items="list"
:item-size="32"
key-field="id"
v-slot="{ item }">
<div class="user"> {{ item.name }} </div>
</RecycleScroller>
</template>

该插件主要有 RecycleScroller.vue、DynamicScroller.vue 这两个组件,其中 RecycleScroller 需要 item 的高度为静态的,也就是列表每个 item 的高度都是一致的,而 DynamicScroller 可以兼容 item 的高度为动态的情况。


前端性能优化
http://example.com/2023/06/01/前端性能优化/
作者
dinghw
发布于
2023年6月1日
许可协议