一些废话我们都知道你需要一个标题才能写一篇文章。虽然我们这些搞代码的人一般都喜欢开门见山,但是由于文体的限制和发表载体的要求,有时候还是得想个标题。而起一个标题不亚于起一个函数名或变量名。光是这篇文章,我就有好几个草稿标题,比如:《页面加载指标演进之路》、《Element Timing:一种全新的页面速度指标》、《如何最准确地测量网页加载速度》、《新前端下的页面加载速度》,甚至是《Element Timing In Action》、《三分钟学会测量页面速度》。最后综合考虑读者的承受能力,编辑的意见,还有最重要的:本人文笔薄弱,选择了这么一个很火的,既不会一看就认为是垃圾,也不会被pick被别人。出来仔细挑剔标题。好了废话不多说,直入正题。在远古的DOMReady时代(指10+年前的jQuery时代),我们对网页的开发还仅限于编写静态页面结构,使用JS脚本直接操作DOM,增删一些额外的页面元素。这时候DOMReady就基本可以满足计算页面加载完成时间的需求了。DOMReady(DOM事件中的DOMContentLoaded)表示页面文档完全加载和解析,一般包括HTML文档解析、DOM树的创建、外部链接脚本的加载、外部链脚本的执行和内联脚本的执行,无需等待样式文件、图像文件和子框架页面加载。一般在页面头部放一个时间戳,然后在jQuery的domReady事件中放一个时间戳,我们就可以计算出DOMReady的大概耗时。NavigationTiming在中世纪(指大约10-5年前的Ajax时代),网页的交互形式变得更加多样化。以Gmail为首的富Web应用在极大提升用户体验的同时,也带来了细粒度的网页加载时间记录。需求来了。因此,从2010年开始,WebPerformanceWorkingGroup引入了大量针对Web的时间信息记录,可以通过window对象的performance属性获取。这后来被称为导航计时。NavigationTiming接口提供的数据大致如图所示:基本涵盖了从网页开始网络请求到页面完全加载、资源执行、DOM节点初始化的时间。我们可以直接使用performance.timing轻松获取这些时间来帮助分析页面的加载时间。FP、FCP和LCP在远古时期(指大约5-2年前的React时代),由于各种前端框架(React、Vue等)的兴起,以及Webpack的出现,一款前端搭建神器,让开发网页的难度迅速下降,同时复杂度也暴涨。前端密集型应用程序很受欢迎,在页面上加载脚本所需的时间正在迅速变长。许多网站在体验上采用渐进式加载策略来解决等待脚本执行时白屏时间过长的问题。因此,ProgressiveWebRendering指标诞生了。渐进式网页指标一般有这些:首绘(FP):全称FirstPaint,标记浏览器渲染任何与导航前屏幕内容在视觉上不同的内容的时间点首绘(FCP):全称FirstContentfulPaint,它标记浏览器从DOM呈现第一个内容的点,它可以是文本、图像、SVG甚至
constobserver=newPerformanceObserver((list)=>{letentries=list.getEntries().forEach(function(entry){console.log(entry);});});observer.observe({entryTypes:["element"]});//输出条目内容://{//持续时间:0//元素:p.aimake-site-name//entryType:"element"//id:""//identifier:"text-id"//intersectionRect:DOMRectReadOnly{x:236,y:130,width:144,height:28,top:130,…}//loadTime:0//name:"text-paint"//naturalHeight:0//naturalWidth:0//renderTime:10850.899999976158//startTime:10850.899999976158//url:""//}但需要注意的是,并不是所有的文本节点都可以通过添加elementtiming="ElementTimingAPI来识别,WICG的解释中有一个注释:我们说a文本节点属于最近的b节点的锁定级元素祖先。这意味着一个元素可以有0个或多个关联的文本节点。如果至少有一个文本节点属于并且至少被绘制过一次,我们就说该元素是文本绘制的。因此,一个元素的文本渲染时间戳就是它变成_text-painted_的时间。让文本节点的文本矩形成为该节点在视口中的显示矩形。我们将一个元素的文本矩形定义为包含属于该元素的所有文本节点的文本矩形的几何并集的最小矩形。难以阅读,但其实它想说明的是只有满足以下条件的文本节点才能被记录:必须是块级元素:如、
、、等,也就是说,内联元素比如单个元素,即使加上elementtiming=""属性,也不会被记录为直接子节点一个节点必须包含一个或多个文本节点:比如纯文本、、、等,等块级元素不算,
等图片不算。举几个例子来理解:1
2span1 1/span>
等块级元素不算, 1等图片不算。举几个例子来理解: