Skip to main content

性能优化之首屏加载优化

首屏时间(First Contentful Paint),指浏览器从响应用户输入地址,到首屏内容渲染完成的时间,此时整个网页不一定要全部渲染完成,但要展示当前视窗需要的内容,首屏加载可以说是用户体验中最重要的环节。

一、首屏时间计算

DOMContentLoaded 事件在 HTML 文档完全加载和解析后触发。计算首屏时间如下:

document.addEventListener('DOMContentLoaded', (event) => {
console.log('first contentful painting', event);
});

输出:

Performance 可以获取到当前页面中与性能相关的信息,可用于计算白屏时间:

performance.timing.responseStart - performance.timing.navigationStart

二、首屏加载慢的原因

  • 网络延时问题
  • 资源文件体积是否过大
  • 资源是否重复发送请求
  • 加载脚本时渲染内容堵塞

三、首屏优化常用方法

  • 减小入口文件体积
  • 静态资源本地缓存
  • 引用库的按需加载
  • 图片资源的压缩
  • 启用 gzip 压缩
  • 使用 SSR 服务端渲染

1、减小入口文件体积

常用的手段是路由懒加载,把不同路由对应的组件分割成不同的代码块,等路由被请求时会单独打包路由,使入口文件变小,提高加载速度:

举个例子:

在 Vue Router 配置路由时,采用动态加载路由懒加载的形式:

src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../components/Home.vue'
import About from '../components/About.vue'

const routes = [
{
path: '/',
component: Home,
component: () => import('../components/Home.vue')
},
{
path: '/about',
component: About,
component: () => import('../components/About.vue')
}
]

const router = createRouter({
history: createWebHistory(),
routes
})

export default router

以函数的形式加载路由,这样就可以把各自的路由文件分别打包,只有在解析给定的路由时,才会加载路由组件。

2、静态资源本地缓存

后端返回的资源,可以:

  • 采用 HTTP 缓存,设置 Cache-Control,Last-Modified,Etag 等响应头;
  • 采用 Service Worker 离线缓存;
  • 合理利用 localStorage。

3、引用库的按需加载

4、图片资源的压缩

页面上使用到的 icon,可以使用在线字体图标或雪碧图,以减轻 HTTP 请求压力。

对于体积较大的图片,可以单独进行压缩。

5、启用 gzip 压缩

工作原理:

  1. 浏览器请求 url,并在请求头中设置属性 accept-encoding:gzip,表明浏览器支持 gzip;
  2. 服务器收到浏览器发送的请求后,会返回压缩后的文件,并在响应头中加上 content-encoding: gzip,如果没有压缩文件,服务器会返回未压缩的请求文件;
  3. 浏览器接收服务器的响应,根据 content-encoding: gzip 响应头使用 gzip 策略去解压资源,通过 content-type 内容类型决定怎么编码读取该文件的内容。

启用方法:

6、使用 SSR 服务端渲染

四、更多方案

页面渲染优化优化 HTML 代码
  • JS 外链放在底部
  • CSS 外链放在顶部
  • 减少 DOM 数量
优化 JS、CSS 代码
  • 使用 webworker
  • 长任务分片执行
  • 减少重排、重绘
  • 降低 CSS 选择器复杂性
优化动画效果
  • 使用 requestAnimationFrame
  • 使用 transform 和 opacity 来实现动画
  • 使用硬件加速提升性能
资源加载优化减少资源大小
  • 代码压缩
  • Gzip
  • 图片压缩
  • 代码拆分
减少 HTTP 请求
  • HTTP 强缓存
  • Service Worker
  • 本地存储(localStorage 等)
  • 合并请求(nginx-http-concat 模块)
提高 HTTP 请求响应速度
  • CDN
  • HTTP 弱缓存
  • DNS Prefetch
  • HTTP2
优化资源加载时机
  • 按需加载
  • 懒加载
  • 预加载