前端的性能优化
# 前端性能指标
load(Onload Event),它代表页面中依赖的所有资源加载完的事件。
DCL(DOMContentLoaded),DOM 解析完毕。
FP(First Paint),表示渲染出第一个像素点。FP 一般在 HTML 解析完成或者解析一部分时候触发。
FCP(First Contentful Paint),表示渲染出第一个内容,这里的 “内容” 可以是文本、图片、canvas。
FMP(First Meaningful Paint),首次渲染有意义的内容的时间,“有意义” 没有一个标准的定义,FMP 的计算方法也很复杂(建议不使用,或者结合产品经理讨论使用)。
LCP(largest contentful Paint),最大内容渲染时间。
# 体验优化
从用户角度而言,优化能够让页面加载得更快、对用户的操作响应得更及时,能够给用户提供更为友好的体验。
- 首屏渲染优化,请求少、加载体积小、善用缓存
- 动画优化,避免某些动画造成页面的卡顿
- 优化用户的操作感官,提升视觉反馈,比如 hover 小手,让用户一眼就知道是否可操作
- 长列表复用 dom,优化滚动效果及页面卡顿现象,减少页面一次性渲染的数量
- 骨架屏的使用
- 组件的预加载,懒加载
# 提升页面性能
减少 http 请求 和 冗余数据
组件,路由懒加载
配置 Nginx 优化
优化 Webpack 打包机制
使用 CDN
预渲染
SSR
图片转 base64
后台分布式部署,负载均衡
# 首页加载优化(减少白屏时间)
- cdn 分发:通过在多台服务器部署相同的副本,当用户访问时,服务器根据用户跟哪台服务器地理距离小或者哪台服务器此时的压力小,来决定哪台服务器去响应这个请求。
后台在业务层的缓存:数据库查询缓存是可以设置缓存的,这个对于高频率的请求很有用。值得注意的是,接口也是可以设置缓存的,比如获取一定时间内不会变的资源,设置缓存会很有用。 - 静态文件缓存方案:这个最常看到。现在流行的方式是文件 hash + 强缓存 的一个方案。比如 hash + cache control:max-age=1 年。
- 前端的资源动态加载:
a. 路由动态加载,最常用的做法,以页面为单位,进行动态加载。
b. 组件动态加载(offScreen Component),对于不在当前视窗的组件,先不加载。
c. 图片懒加载 (offScreen Image),同上。值得庆幸的是,越来越多的浏览器支持原生的懒加载,通过给 img 标签加上 loading=“lazy” 来开启懒加载模式。 - 利用好 async 和 defer 这两个属性:如果是独立功能的 js 文件,可以加入 async 属性。如果是优先级低且没有依赖的 js,我们可以加入 defer 属性。
- 渲染的优先级:浏览器有一套资源的加载优先级策略,也可以通过 js 来自己控制请求的顺序和渲染的顺序。一般我们不需要这么细粒度的控制,而且控制的代码也很不好写。
- 前端做一些接口缓存:前端也可以做接口缓存,缓存的位置有两个,一个是内存,即保存给变量,另一个是 localStorage。比如用户的签到日历(展示用户是否签到),我们可以缓存这样的接口到 localStorage ,有效期是当天。或者有个列表页,我们总是缓存上次的列表内容到本地,下次加载时,我们先从本地读取缓存,并同时发起请求到服务器获取最新列表。
- 页面使用骨架屏:意思是在首屏加载完成之前,通过渲染一些简单元素进行占位。骨架屏虽然不能提高首屏加载速度,但可以减少用户在首屏等待的急躁情绪。这点很有效,在很多成熟的网站都有大量应用。
- 使用 SSR 渲染:服务器性能一般都很好,那么可以先在服务器先把 vdom 计算完成后,再输出给前端,这样可以节约的时间为:计算量 / (服务器计算速度 - 客户端计算速度) 。第二个是服务器可以把首屏的 ajax 请求在服务端阶段就完成,这样可以省去和客户端通过 tcp 传输的时间。
- 引入 http2.0:http2.0 对比 http1.1,最主要的提升是传输性能,特别是在接口小而多的时候。
- 选择先进的图片格式:使用 JPEG 2000,JPEG XR,and WebP 的图片格式来代替现有的 jpeg 和 png ,当页面图片较多时,这点作用非常明显。把部分大容量的图片从 BaseLine JPEG 切换成 Progressive JPEG (理解这两者的差别)也能缩小体积。
- 利用好 http 压缩:使用 http 压缩的效果非常明显。