前段时间在看Vue源码的时候,发现了这样一个API——Window.Performance。当时不知道是什么?查阅了一些资料,大致了解了这个API的作用。让我们来看看什么是Performance。其实光看这个API的名字,我们就可以大致猜到它一定是和性能有关的。看看MDN上关于它的介绍。Performance接口提供对当前页面的性能相关信息的访问。它是HighResolutionTimeAPI的一部分,但通过PerformanceTimelineAPI、NavigationTimingAPI、UserTimingAPI和ResourceTimingAPI得到增强。Performance接口允许访问与当前页面性能相关的信息。它是高分辨率时间API的一部分。但它通过PerformanceTimelineAPI、NavigationTimingAPI、UserTimingAPI和ResourceTimingAPI扩展得到了增强。其实Performance的主要功能就是这些API提供的。光是看上面的内容,你一定还觉得不解,这是什么表现?好了,我们直接打开百度的网页,然后在控制台输出Window.performance(window.performance返回的是performance对象)。Performance对象中有4个属性。我们来看看这4个属性分别代表什么?timing对象提供与浏览器处理相关的各种计时数据。具体如下表名函数(此处所有时间戳均表示UNIX毫秒时间戳)connectEnd浏览器与服务器建立连接时的时间戳,连接建立是指所有握手和认证过程结束connectStartHTTP请求开始发送到服务器时间戳,如果是长连接,相当于fetchStart。domComplete当前网页的DOM结构生成时的时间戳,即Document.readyState属性变为“complete”并触发对应的readystatechange事件时的时间戳。domContentLoadedEventEnd当前网页的DOMContentLoaded事件发生时,也就是DOM结构解析完毕,所有脚本执行完毕的时间戳。domContentLoadedEventStart当前网页的DOMContentLoaded事件发生时,即DOM结构解析完毕,所有脚本开始运行时的时间戳。domInteractive当当前网页的DOM结构结束解析并开始加载嵌入资源时,即Document.readyState属性变为“interactive”并触发对应的readystatechange事件的时间戳。domLoading当当前网页的DOM结构开始解析时,即Document.readyState属性变为“loading”并触发对应的readystatechange事件时的时间戳。domainLookupEnd域查找结束时的时间戳。如果使用长连接,或者从本地缓存中获取信息,则相当于fetchStartdomainLookupStart域查找开始时的时间戳。如果使用持久连接,或者从本地缓存中获取信息,则相当于fetchStartfetchStart。浏览器准备通过HTTP请求获取页面的时间戳。在检查应用程序缓存之前发生。loadEventEnd当前网页加载事件回调结束的时间戳。如果事件未发生,则返回0。loadEventStart当前页面加载事件的回调函数开始的时间戳。如果事件未发生,则返回0。navigationStart当前浏览器窗口的上一个网页关闭并发生unload事件的时间戳。如果没有之前的网页,则等于fetchStartredirectEnd的最后一次重定向,也就是返回Http响应的最后一个字节时的时间戳。如果没有重定向,或者上次重定向不是同源。是0redirectStart第一次重定向开始的时间戳,如果没有重定向,或者最后一次重定向不是同源。0requestStart是浏览器向服务器发送HTTP请求时(或者开始读取本地缓存时)的时间戳。responseEnd浏览器从服务器接收到最后一个字节(或从本地缓存中读取)的时间戳(或在此之前HTTP连接关闭时)responseStart浏览器从服务器接收到它(或从本地缓存中读取)读取)第一个字节的时间戳。secureConnectionStart浏览器和服务器开始安全连接握手的时间戳。如果当前网页不需要安全连接,则返回0。unloadEventEnd如果上一个网页和当前网页属于同一个域,则表示上一个网页的卸载回调结束的时间戳。如果没有上一个网页,或者上一个网页重定向不属于同一个域,则返回值为0。unloadEventStart如果上一个网页和当前网页属于同一个域,则表示卸载事件发生时的时间戳上一个网页的发生。如果没有之前的网页,或者之前的网页跳转不属于同一个域,则返回值为0。理解了上面timing提供的各种属性后,我们就可以计算出网页的某一部分所消耗的具体时间加载页面时,可以精确到千分之一毫秒。例如,计算发送请求到接收数据所需的时间。consttiming=window.performance.timingconstcontactDuration=timing.responseEnd-timing.requestStartnavagationPerformanceNavigation接口提供有关如何导航到当前文档的信息。PerformanceNavigation有两个属性,一个是type,表示如何导航到当前页面,主要有4个值。type=0:表示当前页面是通过点击链接、收藏、表单提交、脚本操作,或者直接在url中输入地址来访问的。type=1:表示当前页面是通过点击刷新或者调用Location.reload()方法访问的。type=2:表示当前页面是通过历史或者前进后退按钮访问的。type=255:通过其他方式访问的另一个属性是redirectCount,表示在到达当前页面之前已经重定向了几次。另一个属性performance.timeOrigin表示性能性能测试的开始时间。高精度时间戳(千分之一毫秒)performance.onresourcetimingbufferfull表示浏览器资源时间性能缓冲区满时触发的回调函数。下面是mdn上关于这个属性的demo。这个demo的主要内容是在缓冲区满的时候调用buffer_full函数。functionbuffer_full(event){console.log("WARNING:ResourceTimingBufferisFULL!");performance.setResourceTimingBufferSize(200);}functioninit(){//如果资源缓冲区已满,则设置回调由chrome浏览器提供。该属性提供了一个可以获取基本内存使用的对象。Performance.mark先看MDN中mark方法的定义mark()方法在浏览器的性能入口缓冲区中创建一个给定名称的时间戳。这段话可以分解成三个关键词。首先是timestamp,其中timestamp指的是高精度时间戳(千分之一毫秒),后面是performanceentrybuffer。性能入口缓冲区是指存放性能实例对象的区域,初始值为空。最后是给定的名字,也就是说每一个生成的时间戳都有一个对应的名字。所以这句话可以理解为,在浏览器的性能入口缓冲区中,根据名称生成一个高精度的时间戳。也就是很多人所说的“点”。Performance.measure也先看一下MDN上measure的定义。measure()方法在浏览器的性能入口缓冲区中的两个指定标记(分别称为开始标记和结束标记)之间创建一个命名时间戳。命名时间戳称为度量。这个定义和上面mark的定义有点类似,核心区别就在这句话。两个指定标记之间。所以measure就是指定两个标记点之间的时间戳。如果mark可以理解为“点”,measure可以理解为“连线”。一个小例子让我们来看一个使用标记和测量的小演示。这个例子也参考了MDN。这是一个简短的解释。//标记起点performance.mark("mySetTimeout-start");//等待1000mssetTimeout(function(){//标记终点performance.mark("mySetTimeout-end");//标记起点和结束点之间的时间戳performance.measure("mySetTimeout","mySetTimeout-start","mySetTimeout-end");//获取所有名为mySetTimeout的度量varmeasures=performance.getEntriesByName("mySetTimeout");varmeasure=measures[0];console.log("setTimeoutmilliseconds:",measure.duration)//清除标记performance.clearMarks();performance.clearMeasures();},1000);结果如图,highprecision时间戳非常精确。(我们知道由于执行队列的原因,setTimeout不会在给定的1000ms后立即执行)PerformanceAPI提供了很多接口,方便测试我们程序的性能。如标记和测量。很多优秀的框架也是使用这个API来进行测试的,比如我最近在看的Vue框架。它经常使用标记和测量来测试程序性能。所以如果你想开发高性能的web程序,了解PerformaceAPI是非常重要的。参考[1]MDNPerformance,Performance[2]UserTimingAPI[3]performanceentrybuffer
