前端性能优化

RAIL模型

响应(Response)

动画(Animation)

当动画的帧率是 >= 60帧/秒 的时候,人眼才不会觉得卡顿。此时的理论值为 1000毫秒/60帧 = 16.6 毫秒/帧

浏览器需要大约6毫秒的时间来渲染每一帧,所以,每一帧的准则建议是10毫秒

空闲时间(Idle Time)

最大化闲置时间,增加页面在50毫秒内响应用户输入的几率

加载(Loading)

目标在5秒或更短的时间内加载、解析、渲染,并确保用户可以交互

性能测量

DevTools 网络

单条请求详情

请求详情(edge)

帧率

ctrl + shift + p 开启帧率显示

帧率显示

Performance Timing API

耗时计算

let timing = performance.getEntriesByType('navigation')[0];timing.domInteractive - timing.fetchStart

DNS 解析耗时: domainLookupEnd - domainLookupStart

TCP 连接耗时: connectEnd - connectStart

SSL 安全连接耗时: connectEnd - secureConnectionStart

网络请求耗时 (TTFB): responseStart - requestStart

数据传输耗时: responseEnd - responseStart

DOM 解析耗时: domInteractive - responseEnd

资源加载耗时: loadEventStart - domContentLoadedEventEnd

First Byte时间: responseStart - domainLookupStart

白屏时间: responseEnd - fetchStart

首次可交互时间(TTI): domInteractive - fetchStart

DOM Ready 时间: domContentLoadEventEnd - fetchStart

页面完全加载时间: loadEventStart - fetchStart

http 头部大小: transferSize - encodedBodySize

重定向次数:performance.navigation.redirectCount

重定向耗时: redirectEnd - redirectStart

长任务观察

const observer = new PerformanceObserver((list) => {    for (const entry of list.getEntries()) {        console.log(entry)    }})observer.observe({entryTypes: ['longtask']})

可见性状态监听

网络状况监听

const connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;connection.effectiveType;

元素可见性检测

相较于 Element.getBoundingClientRect() , 后者是在主线程上运行,因此频繁触发、调用可能会造成性能问题

优化全过程

静态资源优化

优化图片 LCP 时间:

长任务优化

  1. 通过 setTimeout 把长任务拆分成多个宏任务
  2. 通过 Promise 的回调函数把长任务拆分为微任务
  3. 通过 requestAnimationFrame 拆分为微任务
  4. 使用 requestIdleCallback 在空闲时间执行长任务
  5. 使用 scheudler 决定任务运行时的优先级

页面渲染技术方案选型

原生 混合开发优化

服务端网络优化

前端全链路监控

渲染优化

布局防抖

事件防抖

绘制

当DOM或CSS发生改动后,就会触发绘制

白屏优化

FCP与FP优化

布局偏移优化

元素偏移的位置距离越远,布局偏移值就越大;影响视口面积越大,其影响比例也就越高,布局偏移值也就越大。CLS 值越小,用户体验越好。

一些常见的布局偏移原因:

  1. 异步加载图片,图片没有初始宽高,导致布局发生抖动
  2. 动态插入的内容,如广告
  3. 动画导致的布局抖动
  4. 自定义字体导致加载字体时的字体闪烁

静态资源优化

图片

优化方法:

HTML

CSS

JavaScript

JavaScript 文件的下载过程会阻塞 DOM 解析

该把CSS放在文档的头部,尽可能的提前加载CSS;把JS放在文档的尾部,这样JS也不会阻塞页面的渲染。CSS会和JS并行解析,CSS解析也尽可能的不去阻塞JS的执行