一、基础概念
首先来探讨一下一个网页为什么会出现白屏:
我们来看下一个网页从白屏到内容展示都经历了哪些过程,如下图所示:
TTFB:Time To First Byte, ⾸字节时间
FP:First Paint, ⾸次绘制,绘制body
FCP:First Contentful Paint,首次有内容的绘制,第一个dom元素绘制完成
FMP:First Meaningful Paint,⾸次有意义的绘制
TTI:Time To Interactive, 可交互时间。整个内容渲染完成
对应如下图:
我们以代码来举例:
FP:仅有⼀一个 div 根节点。
FCP:包含⻚页⾯面的基本框架,但没有数据内容。
FMP:包含⻚页⾯面所有元素及数据。
这与vue的几个生命周期类似,来看一下:
二、长任务
简单来说,任何在浏览器中执行超过 50 ms 的任务,都是 long task。
long task 会长时间占据主线程资源,进而阻碍了其他关键任务的执行/响应,造成页面卡顿。
三、实战
下面我们用代码来监控下FP,FTP,FMP,以及longtask所花费的时间
// const result = window.performance.getEntriesByType("paint"); // 获取fp,fcp
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log(entry);
console.log(entry.name + "执行时间", entry.startTime + entry.duration);
}
});
observer.observe({
entryTypes: ["paint"]
});
// fmp
<div id="app">
111
<script>
performance.mark("text done"); // mark点
</script>
</div>
<!-- <script src="./demo/1.fp&FTP.js"></script> -->
<script>
const perfEntries = performance.getEntriesByType("mark");
for (const entry of perfEntries) {
console.log(entry);
console.log(entry.name + "执行时间", entry.startTime + entry.duration);
}
</script>
// tti
<div id="app">
111
</div>
<script src="./node_modules/tti-polyfill/tti-polyfill.js"></script>
<script>
// window.onload = function name(params) {
// console.log("onload");
// }
// import ttiPolyfill from './path/to/tti-polyfill.js';
ttiPolyfill.getFirstConsistentlyInteractive().then((tti) => { // tti比window.onload要晚
// Use `tti` value in some way.
//统计的数据
console.log(tti);
//navigator.sendBeacon("a.gif?v="+11)
});
</script>
// longtask
const observer = new PerformanceObserver(list => {
list.getEntries().forEach(item => {
// longtask 的类型
console.log(`long task name is: ${item.name}`);
console.log(`long task attribution is:`);
// longtask 的具体信息
console.log(JSON.stringify(item.attribution, null, 2));
});
});
// 仅关注 longtask
observer.observe({ entryTypes: ["longtask"] });