要做前端性能优化,分析和衡量页面内容必不可少,找出网站中需要优化的部分,对症下药。
衡量性能的方式有以下几种:
1.加载时间
2.性能指标
3.长任务卡顿
4.浏览器 Performance 选项卡
1、加载时间
在 window.performance.timing 变量对象中记录了加载页面期间的各种计时信息。比如可以分析 DOM 树构建完成的时间(DOMContentLoaded) 和 页面完整的加载时间(load)。
如下示例,在 DOM 树中增加一个 标签来渲染图片,其中:
-
DOMContentLoadedTime的打印时间近为 28ms,表示 DOM 树构建完成的时间; -
loadTime的打印时间近为 221ms,它会在页面所有资源( 图片资源)加载完成后执行。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
</head>
<body>
<img src="https://client-static.xstudyedu.com/prod/live-matches-front/assets/section_calendar_content-6853bfff.png" alt="" />
<script>
window.onload = () => {
const {
// 开始发起 HTTP 请求文档的时间
fetchStart,
// DOMContentLoaded 事件发生的时间
domContentLoadedEventStart,
// window.onload 事件发生的时间
loadEventStart,
} = performance.timing;
// DOM 树构建完成后触发 DOMContentLoaded 事件
const DOMContentLoadedTime = domContentLoadedEventStart - fetchStart;
console.log(`DOMContentLoaded 的执行时间:${DOMContentLoadedTime}ms`);
// 页面完整的加载时间
const loadTime = loadEventStart - fetchStart;
console.log(`页面完整的加载时间:${loadTime}ms`);
};
</script>
</body>
</html>
2、性能指标
分析以用户为中心的性能指标,包含 FP(首次像素绘制)、FCP(首次内容绘制)、FMP(首次有意义绘制)、LCP(页面中最大的元素加载时间)等。
一般在客户端渲染单页面应用中,为了优化首屏渲染白屏时间,会重点关注 FCP(首次内容绘制) 性能指标。该绘制时长越短,说明白屏时间越少,用户打开网站的使用体验就越好。
说明:
FCP 首次内容绘制是指用户在页面中看到了有效内容。比如在 React 框架中,初始时会有一个空 id=root div 元素,此时不会计算 FCP,只有等 id=root 经过 ReactDOM render 以后,页面呈现了文本等有效内容,这时会计算出 FCP。
JS 可以通过 PerformanceObserver 观察 event type paint来获取 FCP 指标。如下示例,初始放置一个空 div,在 1s 以后给 div 中添加有效内容(模拟框架渲染),FCP 指标会在这时生成。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<style>
/* 设置背景图,生成 FP 指标 */
#root {
height: 100px;
background: #eee;
}
</style>
</head>
<body>
<div id="root"></div>
<script>
// 模拟框架渲染,1s 后在页面呈现有效内容
setTimeout(() => {
root.innerHTML = "content";
}, 1000);
window.onload = function () {
const observer = new PerformanceObserver(function (list) {
const perfEntries = list.getEntries();
for (const perfEntry of perfEntries) {
if (perfEntry.name === "first-paint") {
const FP = perfEntry;
console.log("首次像素 绘制时间:", FP?.startTime); // 674ms(div 设有背景图,会在元素渲染时生成 FP 指标)
} elseif (perfEntry.name === "first-contentful-paint") {
const FCP = perfEntry;
console.log("首次有效内容的绘制 绘制时间:", FCP?.startTime); // 1174ms
observer.disconnect(); // 断开观察,不再观察了
}
}
});
// 观察 paint 相关性能指标
observer.observe({ entryTypes: ["paint"] });
};
</script>
</body>
</html>
3、页面卡顿
当一段代码的执行占用主线程时间过长时,用户在页面上的交互就会出现卡顿,我们可以通过监控这类长任务,针对性地进行优化。
如下示例,点击按钮执行一个 1000ms 长任务,我们可以使用 PerformanceObserver 观察 event type longtask 并设置阈值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
</head>
<body>
<button id="longTaskBtn">执行longTask</button>
<script>
// 默认长任务
const longTaskBtn = document.getElementById("longTaskBtn");
function longTask() {
const start = Date.now();
console.log("longTask开始 start");
while (Date.now() < 1000 + start) {}
console.log("longTask结束 end,耗时:", Date.now() - start);
}
longTaskBtn.addEventListener("click", longTask);
</script>
<script>
// 观察长任务
new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
// 设定卡顿阈值:执行时长大于 500 ms
if (entry.duration > 500) {
console.log("执行的长任务耗时:", entry.duration);
}
});
}).observe({ entryTypes: ["longtask"] });
</script>
</body>
</html>
4、浏览器 Performance 选项卡
除了上述通过代码进行度量性能外,还可以在 浏览器控制台 - Performance 选项卡 中查看和分析页面性能。其中包含 FCP 性能指标、页面内容绘制 的耗时统计 等。

根据以上指标分析,就可以做出相对应的优化部分