JS 中的 performance,测量web应用性能


相关文章:


Web Performance API 允许网页访问某些函数来测量网页和 Web 应用程序的性能

performance 包含如下属性和方法
在这里插入图片描述

  • eventCounts:包含每个事件类型被分派的事件数量

  • memory:只有在chrome才有,提供了基本内存的使用情况

  • navigation:该对象表示在当前给定浏览上下文中网页导航的类型,提供了操作的上下文,包括页面的加载,刷新,重定向次数等等

  • timing:这个对象包括了页面相关的性能信息

  • timeOrigin: 高精度时间戳。目前该属性在实验中。

属性

performance.memory 内存

MDN:“它是 Chrome 添加的一个非标准扩展,这个属性提供了一个可以获取到基本内存使用情况的对象。不应该使用这个非标准的 API。”

performance.memory 包含此刻内存占用的情况,包含3个属性

  • jsHeapSizeLimit:上下文可用堆内存的上限(最大体积,以字节计算);
  • totalJSHeapSize:已分配的堆内存大小(可使用的内存);
  • usedJSHeapSize:当前JS活动对象占用的内存,如果 usedJsHeapSize 大于 totalJsHeapSize 可能存在了内存泄漏,所以不允许大于totalJSHeapSize。

在这里插入图片描述

performance.navigation 页面的来源信息

提供了在指定的时间段里发生的操作相关信息,包括页面是加载还是刷新、发生了多少次重定向等等

有两个属性:

  • redirectCount:表示到达最终页面前,重定向的次数,但是这个接口有同源策略限制,即仅能检测同源的重定向。

  • type:志页面导航类型

    type常数枚举值描述
    TYPE_NAVIGATE0普通进入,包括:点击链接、在地址栏中输入 URL、表单提交、或者通过除下表中 TYPE_RELOAD 和 TYPE_BACK_FORWARD 的方式初始化脚本。
    TYPE_RELOAD1通过刷新进入,包括:浏览器的刷新按钮、快捷键刷新、location.reload()等方法。
    TYPE_BACK_FORWARD2通过操作历史记录进入,包括:浏览器的前进后退按钮、快捷键操作、history.forward()、history.back()、history.go(num)。
    TYPE_UNDEFINED255其他非以上类型的方式进入。

在这里插入图片描述

performance.timing 时间消耗

performance.timing 对象包括了页面相关的性能信息。

在这里插入图片描述

在这里插入图片描述

  • navigationStart:浏览器 unload 前一个页面文档(document)的开始时间节点。如果没有之前的页面,此属性的值等于 fetchStart。

    例如当前在浏览baidu.com,在地址栏输入google.com并回车,浏览器执行的动作依次为:unload 当前文档(baidu.com)—> 请求下一个文档(google.com)。navigationStart 的值就是触发unload当前文档的时间节点。

  • redirectStartredirectEnd: 如果在导航时存在HTTP重定向或等效内容(页面由redirect而来),并且所有重定向或等效内容都来自同一个原点,则 redirectStart 和 redirectEnd 分别代表redirect开始和结束的时间节点,否则值为0。

  • unloadEventStartunloadEventEnd:如果先前文档和当前文档具有相同的来源(同一个域),则 unloadEventStart 和 unloadEventEnd 分别代表浏览器unload先前文档的开始和结束时间节点。否则两者都等于0。

  • fetchStart:是指在浏览器发起任何请求之前的时间值。在fetchStart 和 domainLookupStart 之间,浏览器会检查当前文档的缓存。

  • domainLookupStartdomainLookupEnd:分别代表DNS查询的开始和结束时间节点。如果浏览器没有进行DNS查询(比如使用了cache),则两者的值都等于 fetchStart。

  • connectStartconnectEnd:分别代表TCP建立连接和连接成功的时间节点。如果浏览器没有进行TCP连接(比如使用持久化连接 webscoket、使用缓存或本地资源),则两者都等于 domainLookupEnd。

  • secureConnectionStart:可选。如果页面使用HTTPS,它的值是安全连接握手之前的时刻。如果该属性不可用,则返回 undefined。如果该属性可用,但没有使用HTTPS,则返回0。

  • requestStart:代表浏览器发起请求的时间节点,请求的方式可以是请求服务器、缓存、本地资源等。如果发送请求后传输连接失败,并且浏览器重新打开连接并重新发送请求,则 requestStart 返回新请求的值。

  • responseStartresponseEnd:分别代表浏览器收到从服务器端(或缓存、本地资源)收到响应的第一个字节 和 最后一个字节数据(或关闭传输连接之前,以先到者为准)的时刻。

  • domLoading:当浏览器将 document.readyState 设置为 loading 的时间节点,也就是浏览器开始解析html文档的时间节点。

  • domInteractive:当浏览器将 document.readyState 设置为 interactive 的时间节点。domInteractive 并非 DOMReady,它早于 DOMReady 触发,代表html文档解析完毕(即dom tree创建完成)但是内嵌资源(比如外链css、js等)还未加载的时间点。

  • domContentLoadedEventStart:代表 DOMContentLoaded 事件触发的时间节点。

    MDN:当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完全加载。

  • domContentLoadedEventEnd:代表 DOMContentLoaded 事件完成的时间节点,此刻用户可以对页面进行操作,也就是jQuery中的domready时间。

  • domComplete:html文档完全解析完毕的时间节点。

  • loadEventStartloadEventEnd:分别代表 load 事件触发和结束的时间节点。当未触发load 事件时,值为 0,当未完成 load 事件时 loadEventEnd 为 0 。

相关时间计算

  • 重定向时间:redirectEnd - redirectStart

  • 页面加载耗时:loadEventEnd - navigationStart

  • DNS查询耗时:domainLookupEnd - domainLookupStart

  • TCP链接耗时:connectEnd - connectStart

  • request请求耗时:responseEnd - responseStart

  • 解析dom树耗时:domComplete - domInteractive

  • 白屏时间:domloading - fetchStart

  • domready可操作时间:domContentLoadedEventEnd - fetchStart

  • onload总下载时间:loadEventEnd - fetchStart

方法

performance.now()

  • 该对象表示从某一时刻(通常是 navigationStart 事件发生时刻)开始计算毫秒数,通过两次时间相减可以计算某个操作的间隔时间

  • 语法:const t = window.performance.now()

  • 示例

    const t0 = window.performance.now();
    doSomething();
    const t1 = window.performance.now();
    console.log("doSomething 函数执行了" + (t1 - t0) + "毫秒。")
    
  • 和 JavaScript 中其他可用的时间类函数(比如Date.now)不同的是,window.performance.now()返回的时间戳没有被限制在一毫秒的精确度内,相反,它们以浮点数的形式表示时间,精度最高可达微秒级。

performance.mark()

  • mark() 方法在浏览器的性能缓冲区中使用给定名称添加一个timestamp(时间戳),可以多次重复录入

  • 语法: performance.mark(name)

  • 可以使用 (getEntries(),getEntriesByName() 或者getEntriesByType()) 检索到,获取到对应的Array;

    markperformance entry将具有以下属性值:

    • entryType 为 “mark
    • name 为 mark 被创建时给出的 “name”
    • startTimemark() 方法被调用时的 timestamp
    • duration 为 “0” (标记没有持续时间)
  • 可以使用 performance.clearMarks() 清除

  • 示例

    // 创建一些标记。
    performance.mark("squirrel");
    performance.mark("squirrel");
    performance.mark("monkey");
    performance.mark("monkey");
    performance.mark("dog");
    performance.mark("dog");
    
    // 获取所有的 PerformanceMark 条目。
    const allEntries = performance.getEntriesByType("mark");
    console.log(allEntries.length);
    // 6
    
    // 获取所有的 "monkey" PerformanceMark 条目。
    const monkeyEntries = performance.getEntriesByName("monkey");
    console.log(monkeyEntries.length);
    // 2
    
    // 删除所有标记。
    performance.clearMarks();
    

Performance.measure()

  • 使用 name 名称创建一个从startMark开始到endMark结束的measure(测量),如果说mark可以理解为**“打点"的话,measure就可以理解为"连线”**。

  • 语法:performance.measure(name, startMark, endMark)

  • 计算两个mark之间的时长,创建一个DOMHighResTimeStamp保存在资源缓存数据中,可通过getEntries(),getEntriesByName() 或者getEntriesByType()等相关接口获取。

    • entryType 为字符串 measure
    • name 为 measure 被创建时给出的 “name”
    • startTime 为 measure 方法被调用时的 timestamp
    • duration 为两个 mark 之间的时长
  • 从导航开始测量

    performance.measure('name');
    
  • 导航开始到标记

    performance.measure('name', undefined, 'mark-2');
    
  • 从标记到标记

    performance.measure('name', 'mark-start', 'mark-end');
    

Performance.clearMarks()

  • 将给定的 mark 从浏览器的性能输入缓冲区中移除

  • 语法:

    performance.clearMarks(); // 移除所有mark
    performance.clearMarks(name); // 移除单个mark
    

Performance.clearMeasures()

  • 将给定的 measure 从浏览器的性能输入缓冲区中移除

  • 语法:

    performance.clearMeasures(); // 移除所有measures
    performance.clearMeasures(name); // 移除单个measures
    

Performance.getEntries()

  • 基于给定的 filter 返回一个 PerformanceEntry对象的列表

  • filter 格式为 {name : “measureName”, entryType: “measure”},如果没有传入filter参数,则返回全部 PerformanceEntry对象组成的列表

  • 语法:

    // 取全部:
    entries = window.performance.getEntries();
    entries = window.performance.getEntries(PerformanceEntryFilterOptions);
    
    
    // 取特定:
    entries = performance.getEntries({name: "entry_name", entryType: "mark"});
    
  • example

    function use_PerformanceEntry_methods() {
      log("PerformanceEntry tests ...");
    
      if (performance.mark === undefined) {
        log("... performance.mark Not supported");
        return;
      }
    
      // Create some performance entries via the mark() method
      performance.mark("Begin");
      do_work(50000);
      performance.mark("End");
      performance.mark("Begin");
      do_work(100000);
      performance.mark("End");
      do_work(200000);
      performance.mark("End");
    
      // Use getEntries() to iterate through the each entry
      var p = performance.getEntries();
      for (var i=0; i < p.length; i++) {
        log("Entry[" + i + "]");
        check_PerformanceEntry(p[i]);
      }
    
      // Use getEntries(name, entryType) to get specific entries
      p = performance.getEntries({name : "Begin", entryType: "mark"});
      for (var i=0; i < p.length; i++) {
        log("Begin[" + i + "]");
        check_PerformanceEntry(p[i]);
      }
    
      // Use getEntriesByType() to get all "mark" entries
      p = performance.getEntriesByType("mark");
      for (var i=0; i < p.length; i++) {
        log ("Mark only entry[" + i + "]: name = " + p[i].name +
             "; startTime = " + p[i].startTime +
             "; duration  = " + p[i].duration);
      }
    
      // Use getEntriesByName() to get all "mark" entries named "Begin"
      p = performance.getEntriesByName("Begin", "mark");
      for (var i=0; i < p.length; i++) {
        log ("Mark and Begin entry[" + i + "]: name = " + p[i].name +
             "; startTime = " + p[i].startTime +
             "; duration  = " + p[i].duration);
      }
    }
    
    //entryType,name,initiatorType  Examples
    var p = performance.getEntries();
    
    var ptyps = p.map((ele) => {return(ele.entryType)});
    //Array(94) [ "navigation", "resource", "resource", "resource", "resource", "resource", "resource", "resource", "resource", "resource", … ]
    
    var pnms = p.map((ele) => {return(ele.name)});
    //Array(94) [ "document", "https://csdnimg.cn/public/static/css/avatar.css", "https://csdnimg.cn/public/common/libs/jquery/jquery-1.9.1.min.js", "https://csdnimg.cn/rabbit/exposure-click/main-1.0.5.js", "https://csdnimg.cn/release/phoenix/production/main-e96db8abdf.js", "https://csdnimg.cn/pubfooter/js/tracking-1.0.2.js", "https://csdnimg.cn/public/common/toolbar/js/content_toolbar.js", "https://csdnimg.cn/release/phoenix/production/markdown_views-ea0013b516.css", "https://csdnimg.cn/search/baidu_search-1.1.2.js?v=201802071056&autorun=true&install=true&keyword=%E5%B0%8F%E7%A8%8B%E5%BA%8F%E6%89%A7%E8%A1%8C%E9%A1%BA%E5%BA%8F", "https://csdnimg.cn/release/phoenix/production/main-f869aa95a4.css", … ]
    
    var pityps = p.map((ele) => {return(ele.initiatorType)});
    //Array(94) [ "navigation", "link", "script", "script", "script", "script", "script", "link", "script", "link", … ]
    
    Specifications
    

Performance.getEntriesByName()

  • 基于给定的 nameentry type 返回一个 PerformanceEntry对象的列表。

  • 语法:

    entries = window.performance.getEntriesByName(name, type);
    
    // 如
    const entries = window.performance.getEntriesByName('entry_name', 'mark');
    
  • example

    function use_PerformanceEntry_methods() {
      log("PerformanceEntry tests ...");
    
      if (performance.mark === undefined) {
        log("... performance.mark Not supported");
        return;
      }
    
      // Create some performance entries via the mark() method
      performance.mark("Begin");
      do_work(50000);
      performance.mark("End");
      performance.mark("Begin");
      do_work(100000);
      performance.mark("End");
      do_work(200000);
      performance.mark("End");
    
      // Use getEntries() to iterate through the each entry
      var p = performance.getEntries();
      for (var i=0; i < p.length; i++) {
        log("Entry[" + i + "]");
        check_PerformanceEntry(p[i]);
      }
    
      // Use getEntries(name, entryType) to get specific entries
      p = performance.getEntries({name : "Begin", entryType: "mark"});
      for (var i=0; i < p.length; i++) {
        log("Begin[" + i + "]");
        check_PerformanceEntry(p[i]);
      }
    
      // Use getEntriesByType() to get all "mark" entries
      p = performance.getEntriesByType("mark");
      for (var i=0; i < p.length; i++) {
        log ("Mark only entry[" + i + "]: name = " + p[i].name +
             "; startTime = " + p[i].startTime +
             "; duration  = " + p[i].duration);
      }
    
      // Use getEntriesByName() to get all "mark" entries named "Begin"
      p = performance.getEntriesByName("Begin", "mark");
      for (var i=0; i < p.length; i++) {
        log ("Mark and Begin entry[" + i + "]: name = " + p[i].name +
             "; startTime = " + p[i].startTime +
             "; duration  = " + p[i].duration);
      }
    }
    

Performance.getEntriesByType()

  • 基于给定的 entry type 返回一个 PerformanceEntry对象的列表。

  • 语法:

    entries = window.performance.getEntriesByType(type);
    
    // 如
    const entries = window.performance.getEntriesByName('mark');
    const entries = window.performance.getEntriesByName('measure');
    
  • example

    function usePerformanceEntryMethods() {
      log("PerformanceEntry tests ...");
    
      if (performance.mark === undefined) {
        log("... performance.mark Not supported");
        return;
      }
    
      // Create some performance entries via the mark() method
      performance.mark("Begin");
      doWork(50000);
      performance.mark("End");
      performance.mark("Begin");
      doWork(100000);
      performance.mark("End");
      doWork(200000);
      performance.mark("End");
    
      // Use getEntries() to iterate through the each entry
      var p = performance.getEntries();
      for (var i=0; i < p.length; i++) {
        log("Entry[" + i + "]");
        checkPerformanceEntry(p[i]);
      }
    
      // Use getEntries(name, entryType) to get specific entries
      p = performance.getEntries({name : "Begin", entryType: "mark"});
      for (var i=0; i < p.length; i++) {
        log("Begin[" + i + "]");
        checkPerformanceEntry(p[i]);
      }
    
      // Use getEntriesByType() to get all "mark" entries
      p = performance.getEntriesByType("mark");
      for (var i=0; i < p.length; i++) {
        log ("Mark only entry[" + i + "]: name = " + p[i].name +
             "; startTime = " + p[i].startTime +
             "; duration  = " + p[i].duration);
      }
    
      // Use getEntriesByName() to get all "mark" entries named "Begin"
      p = performance.getEntriesByName("Begin", "mark");
      for (var i=0; i < p.length; i++) {
        log ("Mark and Begin entry[" + i + "]: name = " + p[i].name +
             "; startTime = " + p[i].startTime +
             "; duration  = " + p[i].duration);
      }
    }
    
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

__畫戟__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值