1.基本指标介绍首先,前端性能指标一般分为以下几类:FirstPaint(FP)FirstContentfulPaint(FCP)YesTimetoInteractive(TTI)LargestContentfulPaint(LCP)FirstMeaningPaint(FMP)FP是时间轴上的第一个“时间点”,指的是浏览器响应用户输入URL地址到浏览器开始显示内容的时间,简单来说就是时间浏览器首次更改。FCP(全称“Fi??rstContentfulPaint”,译为“FirstContentfulPaint”)是指浏览器响应用户输入的网址,在其上绘制文字、图片(含背景图片)、非白画布或SVG页面第一次。在做FCP的时候,有的文章说FCP是首屏渲染事件,其实是错误的。TTI,译为“InteractiveTime”,表示网页第一次完全交互的时间点。交互态是指页面上的UI组件是交互的(可以响应按钮的点击或者在文本框中输入文本等),不仅如此,此时主线程已经达到了“流畅”的程度,而主线程的任务都不会超过50毫秒。在一般的管理体系中,TTI是一个非常重要的指标。FMP(全称“Fi??rstMeaningfulPaint”,译为“首次有效绘画”,意思是页面“主要内容”开始出现在屏幕上的时间点。它曾经是我们衡量用户加载的主要指标经验。本质上是通过一个算法来猜测某个时间点可能是FMP,但是最好的情况下准确率只有77%,这个指标在lighthouse6.0中被废弃了,取而代之的是LCP指标。LCP(全称“LargestContentfulPaint")表示视口“内容”的最大可见元素开始出现在屏幕上的时间点。2.性能介绍性能对象专门用于性能监控,内置了一些前端需要的性能参数。2.1.performance.now()方法performance.now()返回performance.navigationStart到当前的毫秒数。performance.navigationStart是浏览器访问的初始时间测量点,下面会介绍。2.2.performance.timing2.3.performance.getEntries()方法当浏览器获取到一个网页时,它会向网页中的每个对象(脚本文件、样式表、图像文件等)发送一个HTTP请求。performance.getEntries()方法以数组的形式返回一个PerformanceEntry的列表,这些请求的时间统计信息,有多少个请求,返回的数组会有多少个成员。name:资源名称,为资源的绝对路径或调用mark方法自定义的名称startTime:开始时间duration:加载时间entryType:资源类型,不同的entryType类型数组中的对象结构不同!详见initiatorType:谁发起请求,详见:值描述mark通过mark()方法添加到数组中的对象paint通过measure()方法添加到数组中的对象measurefirst-contentful-paint第一个contentdrawingresource所有资源的加载时间是最有用的。三、指标计算方法3.1.第一个屏幕和白色屏幕。.Whitescreen:白屏时间(FirstPaint):指的是从浏览器响应用户输入的URL地址到浏览器开始显示内容的时间。一个比较简单的方法是在body标签之前获取当前时间——performance.timing。navigationStart,或者直接获取两个关于paintinperformance的数据,可以直接作为白屏数据,这两个数据一般相差不大。FirstpaintFP包括任何用户定义的背景绘制,这是像素首次绘制到屏幕的时刻。FirstContentPaintFCP是浏览器将第一个DOM渲染到屏幕的时候。该指标报告浏览器首次呈现任何文本、图像、画布或SVG的时间。也可以采用其他计算方式:白屏时间=页面开始显示的时间点-请求开始的时间点。Firstscreen:首屏时间:指从浏览器响应用户输入网址到渲染首屏内容的时间,获取元素页面显示前的当前时间-performance.timing.navigationStart.首屏时间=首屏内容渲染结束时间点-开始请求时间点首屏的计算方法有很多种,很多文章中使用的方法也不尽相同。就是performance.timing.loadEventEnd-performance.timing.navigationStart但是时间差应该不会很大,它用来从加载dom的时间减去请求开始或者刷新url的时间。3.2.TTI关于TTI,可以先了解一下Google提出的性能模型RAIL:1.Response:输入延迟时间(从tap到draw)小于100毫秒。用户点击一个按钮(例如,打开导航)。2.动画:每一帧工作(从JS到绘制)在不到16毫秒内完成。用户滚动页面、拖动手指(例如,打开菜单)或观看动画。拖动时,应用程序会根据手指位置做出响应(例如,拉动以刷新、滑动轮播)。该指示器仅适用于拖动的持续阶段,不适用于开始阶段。3.空闲:主线程JS工作被分成不大于50ms的块。用户没有与页面交互,但主线程应该足以处理下一个用户输入。4.加载:页面可以在1000ms内准备好。用户加载页面并看到关键路径内容。我们可以通过domContentLoadedEventEnd粗略估算一下:TTI:domContentLoadedEventEnd-navigationStartGoogleLabs也提供了一个更方便准确的计算tti-polyfil的api包:importttiPolyfillfrom'./path/to/tti-polyfill.js';ttiPolyfill。getFirstConsistentlyInteractive(opts).then((tti)=>{//Use`tti`valueinsomeway.});3.3.LCP之前我们也有推荐的性能指标,比如:FMP(FirstMeaningfulPaint)和SI(SpeedIndex)可以帮助我们在firstrender之后捕捉到更多的loadingperformance,但是这些太复杂了,不好解释,而且经常出错,无法确定主要内容何时加载。根据W3CWeb性能工作组的讨论和Google的研究,事实证明,衡量页面主要内容何时可见的更准确、更简单的方法是查看具有最大“可绘制区域”的元素何时可见开始渲染。所谓绘图区域,可以理解为各个元素在屏幕上的“占用区域”。如果元素超出屏幕,或者元素被截断,截断的部分不计算在内,只有真正显示在屏幕上才算数。图像元素的面积计算方法略有不同,因为图像可以通过CSS放大或缩小显示,也就是说图像有两个区域:“渲染区域”和“真实区域”。在LCP的计算中,图片的绘制区域会得到一个较小的值。例如:当“渲染区域”小于“真实区域”时,“绘制区域”就是“渲染区域”,反之亦然。在页面的加载过程中,是线性的,元素是一个一个渲染到屏幕上,而不是瞬间渲染到屏幕上,所以“渲染区域”最大的元素是随时变化的。如果你使用PerformanceObserver来抓取LCP,你会发现每当出现“渲染区域”更大的元素时,就会抓取到一个新的性能入口。如果删除了一个元素,LCP算法将不再考虑该元素,如果删除的元素恰好是具有最大“可绘制区域”的元素,则使用新的最大“可绘制区域”元素创建一个新的性能条目。这个过程会一直持续到用户第一次滚动页面或第一次用户输入(鼠标点击、键盘按键等),即一旦用户与页面交互,就停止上报新的性能条目。上面两张图,页面加载过程中变化最大的元素。在第一张图中,新的内容被添加到DOM中,这个元素成为最大的元素。在第二张图中,布局发生了变化,之前在窗口中的元素被移出了窗口。可以直接使用PerformanceObserver抓取LCP:constobserver=newPerformanceObserver((entryList)=>{constentries=entryList.getEntries();constlastEntry=entries[entries.length-1];constlcp=lastEntry.renderTime||lastEntry.loadTime;console.log('LCP:',lcp);});observer.observe({entryTypes:['largest-contentful-paint']});LCP并不完美且容易出错,它会在用户交互后失败停止捕获,您可能会得到错误的结果。如果有轮播占大页,也会出问题,会继续更新LCP。LCP还有一个现成的计算工具库web-vitals:import{getLCP}from'web-vitals';//MeasureandlogthecurrentLCPvalue,//anytimeit'sreadytobereported.getLCP(console.log);
