博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
从一次有趣的实验学习性能优化
阅读量:5932 次
发布时间:2019-06-19

本文共 6051 字,大约阅读时间需要 20 分钟。

从一次实验学习性能优化

Web API之Performance 接口详解

下图是Performance 接口的属性,提供给定页面的与时间相关的性能信息.

performance

  • navigation 包含了页面浏览上下文的导航信息,比如大量获取资源的重定向。

    • redirectCount表示页面加载前经过重定向次数,该接口有同源策略限制,即仅能检测同源的重定向。

    • 返回值应该是0,1,2,255中的一个。分别对应三个枚举值:

      0 : TYPE_NAVIGATE (用户通过常规方式访问页面,比如点一个链接,输入地址等)
      1 : TYPE_RELOAD (用户通过刷新,包括JS调用刷新接口(Location.reload())等方式访问页面)
      2 : TYPE_BACK_FORWARD (用户通过浏览器历史记录访问本页面)
      255: 其他方式

  • memory包含了堆栈使用情况信息,usedJSHeapSize表示所有被使用的js堆栈内存;totalJSHeapSize表示当前js堆栈内存总大小,这表示usedJSHeapSize不能大于totalJSHeapSize。

  • timing包含了页面加载时间相关的性能信息。

    • 重要的参数:

    1. navigationStart:准备加载新页面的起始时间,一般认为是页面最初的时间.一般和fetchStart值相等,和connectEnd中间的时间用于DNS解析,建立TCP连接.

    2. requestStart:返回从服务器、缓存、本地资源等,开始请求文档的时间,一般用于统计网络资源请求的时间.

    3. domLoading:返回当前网页DOM结构开始解析时(即Document.readyState属性变为“loading”、相应的readystatechange事件触发时)的时间,与domComplete对应,用于统计页面渲染时间.

    4. domComplete:返回当前网页DOM结构生成时间,此时页面渲染完成.

    5. DNS查询耗时 :domainLookupEnd - domainLookupStart

    6. TCP链接耗时 :connectEnd - connectStart

    7. request请求耗时 :responseEnd - responseStart

    8. 解析 DOM 树结构的时间:domComplete - responseEnd;

    9. 一般白屏时间:responseStart - navigationStart

    10. 页面总耗时:loadEventEnd/domComplete - navigationStart

一张timing顺序图供参考:

图片描述

navigationStart:当前浏览器窗口的前一个网页关闭,发生unload事件时的Unix毫秒时间戳。如果没有前一个网页,则等于fetchStart属性。                   unloadEventStart:如果前一个网页与当前网页属于同一个域名,则返回前一个网页的unload事件发生时的Unix毫秒时间戳。如果没有前一个网页,或者之前的网页跳转不是在同一个域名内,则返回值为0。             unloadEventEnd:如果前一个网页与当前网页属于同一个域名,则返回前一个网页unload事件的回调函数结束时的Unix毫秒时间戳。如果没有前一个网页,或者之前的网页跳转不是在同一个域名内,则返回值为0。redirectStart:返回第一个HTTP跳转开始时的Unix毫秒时间戳。如果没有跳转,或者不是同一个域名内部的跳转,则返回值为0。redirectEnd:返回最后一个HTTP跳转结束时(即跳转回应的最后一个字节接受完成时)的Unix毫秒时间戳。如果没有跳转,或者不是同一个域名内部的跳转,则返回值为0。fetchStart:返回浏览器准备使用HTTP请求读取文档时的Unix毫秒时间戳。该事件在网页查询本地缓存之前发生。domainLookupStart:返回域名查询开始时的Unix毫秒时间戳。如果使用持久连接,或者信息是从本地缓存获取的,则返回值等同于fetchStart属性的值。domainLookupEnd:返回域名查询结束时的Unix毫秒时间戳。如果使用持久连接,或者信息是从本地缓存获取的,则返回值等同于fetchStart属性的值。          connectStart:返回HTTP请求开始向服务器发送时的Unix毫秒时间戳。如果使用持久连接(persistent connection),则返回值等同于fetchStart属性的值。          connectEnd:返回浏览器与服务器之间的连接建立时的Unix毫秒时间戳。如果建立的是持久连接,则返回值等同于fetchStart属性的值。连接建立指的是所有握手和认证过程全部结束。  secureConnectionStart:返回浏览器与服务器开始安全链接的握手时的Unix毫秒时间戳。如果当前网页不要求安全连接,则返回0。           requestStart:返回浏览器向服务器发出HTTP请求时(或开始读取本地缓存时)的Unix毫秒时间戳。         responseStart:返回浏览器从服务器收到(或从本地缓存读取)第一个字节时的Unix毫秒时间戳。       responseEnd:返回浏览器从服务器收到(或从本地缓存读取)最后一个字节时(如果在此之前HTTP连接已经关闭,则返回关闭时)的Unix毫秒时间戳。     domLoading:返回当前网页DOM结构开始解析时(即Document.readyState属性变为“loading”、相应的readystatechange事件触发时)的Unix毫秒时间戳。     domInteractive:返回当前网页DOM结构结束解析、开始加载内嵌资源时(即Document.readyState属性变为“interactive”、相应的readystatechange事件触发时)的Unix毫秒时间戳。           domContentLoadedEventStart:返回当前网页DOMContentLoaded事件发生时(即DOM结构解析完毕、所有脚本开始运行时)的Unix毫秒时间戳。          domContentLoadedEventEnd:返回当前网页所有需要执行的脚本执行完成时的Unix毫秒时间戳。         domComplete:返回当前网页DOM结构生成时(即Document.readyState属性变为“complete”,以及相应的readystatechange事件发生时)的Unix毫秒时间戳。       loadEventStart:返回当前网页load事件的回调函数开始时的Unix毫秒时间戳。如果该事件还没有发生,返回0。   loadEventEnd:返回当前网页load事件的回调函数运行结束时的Unix毫秒时间戳。如果该事件还没有发生,返回0。
  • performance的方法:

    • performance.now()返回当前网页自从performance.timing.navigationStart到当前时间之间的微秒数(毫秒的千分之一)。精度可以达到100万分之一秒。利用performance.now方法,可以得到某种操作消耗的准确时间。

    performance.mark('mark')     performance.mark('markEnd')     performance.measure('name', 'mark', 'markEnd')     // 清除指定标记     performance.clearMarks('mark');       // 清除所有标记     performance.clearMarks();
    • performance.mark()用于标记某个时间点。使用该方法参数(即标记时间点),再调用 performance.measure(name, nameStart, nameEnd);即可测得某两个时间点之间的耗时.

    var start = performance.now();     // 被测代码     var end = performance.now();     console.log('耗时:' + (end - start) + '微秒。');
    • performance.getEntries() 资源测速:该方法以数组形式,返回请求的时间统计信息(脚本文件、样式表、图片文件等等),有多少个请求,返回数组就会有多少个成员。单位是微秒(microsecond)

    // 统计样式,脚本,图片请求数和消耗时间  var imgResource = {    count: 0,    time: 0  };  var cssResource = {    count: 0,    time: 0  };  var scriptResource = {    count: 0,    time: 0  };  performance.getEntries().forEach(item => {    if (item.initiatorType === 'img') {      imgResource.count++;      imgResource.time += item.duration    } else if (item.initiatorType === 'link') {      cssResource.count++;      cssResource.time += item.duration    } else if (item.initiatorType === 'script') {      scriptResource.count++;      scriptResource.time += item.duration    }  });

Canvas和svg

  • Canvas基于像素,提供2D绘制函数,是一种HTML元素类型,依赖于HTML,通过脚本绘制图形;绘制即时模式图形,适合像素处理,动态渲染和大数据量绘制.

  • SVG基于矢量,提供一系列图形元素(Rect, Path, Circle, Line …),还有完整的动画,事件机制,能独立使用,也可以嵌入到HTML中.SVG 是一个保留在内存中模型中的保留模式图形模型,而内存中模型可通过重新呈现的代码结果进行操作,更适合用来做动态交互.

实际对比:Echarts和Highcharts

Echarts基于Canvas,而Highcharts基于SVG,本次实验利用10万个微博签到数据来测试两者的性能差异.

  1. 一开始在两个单独文件中分别使用Echarts和Highcharts来绘制几百个点,发现由于网络,引入的库不同,二者时间不具有对比性.因此转而在同一页面中绘制.

  2. 将所有依赖在head中引入,分别封装两个绘图函数,用ajax从远程获取数据,在回调函数中绘图并且统计时间,从而分析性能差异.

  3. 测试代码:

Echarts函数

function renderEchart(weiboData) {  var timeStart = window.performance.now().toFixed(4);  $('.eRender span:eq(0)').html($('.eRender span:eq(0)').html() + timeStart);  var myChart = echarts.init(document.getElementById('main')); myChart.setOption(option);  var timeEnd = window.performance.now().toFixed(4);  console.log(timeEnd - timeStart);  $('.eRender span:eq(1)').html($('.eRender span:eq(1)').html() + timeEnd);  $('.eRender span:eq(2)').html($('.eRender span:eq(2)').html() + (timeEnd - timeStart).toFixed(4) + 'ms');}

Highcharts函数

function renderHchart(hda) {  var timeStart = window.performance.now().toFixed(4);  $('.hRender span:eq(0)').html($('.hRender span:eq(0)').html() + timeStart);  var H = Highcharts,    map = H.maps['cn/china'],    chart;  var colors = Highcharts.getOptions().colors;  new Highcharts.Map('container',params)  var timeEnd = window.performance.now().toFixed(4);  console.log(timeEnd - timeStart);  $('.hRender span:eq(1)').html($('.hRender span:eq(1)').html() + timeEnd);  $('.hRender span:eq(2)').html($('.hRender span:eq(2)').html() + (timeEnd - timeStart).toFixed(4) + 'ms');}

4.测试结果:由于svg无法画出10万个点(浏览器会卡死),画3000点就需要7s.所以下面svg最多只画3000个点.

画100个点:100点
Echarts画10万个点,highcharts画3000个点:]图片描述
Echarts单独画10万个点:图片描述
highcharts单独画3000个点:图片描述

总结:实验结果很容易预测,canvas肯定比基于dom的svg性能好得多,而且如果使用webGL,利用显卡加速,性能会进一步提升.但是测试中遇到很多有价值的问题,例如如何利用js获取页面性能信息,从而做出优化策略,如何控制变量排除干扰因素使得测试更具有说服力.实验中对performance以及面板的深入了解也使得我对页面整个渲染流程有了更深的认识.

转载地址:http://dputx.baihongyu.com/

你可能感兴趣的文章
BitBucket引入灾难恢复和合并策略
查看>>
Node.js 2017企业用户调查结果发布
查看>>
InfoQ中文站2015年度优秀社区编辑评选揭晓
查看>>
GitHub贡献第一的公司是谁?微软开源软件列表
查看>>
中国在两年内赶超美国AI?李开复:不一定
查看>>
埃森哲、亚马逊和万事达卡抱团推出的区块链项目有何神通?
查看>>
Node 7.6默认支持Async/Await
查看>>
.NET Core如何为项目提供高性能解决方案?
查看>>
你以为AlphaGo只是下围棋厉害?不,它还能用来优化金融交易策略参数
查看>>
HashMap源码分析
查看>>
compass watch 报CompatibilityError 解决方案
查看>>
Payara基金会发布全面支持MicroProfile 2.0的5.183版Payara Server和Payara Micro
查看>>
函数式编程语言时代已经来临
查看>>
Yarn将用TypeScript重写,Flow惨遭亲爹抛弃!
查看>>
Visual Studio 2017 15.7预览版发布
查看>>
Python数据科学平台Anaconda的最新发布中增加了Microsoft VS Code
查看>>
利用媒体云实现差异化
查看>>
Imperva开源域目录控制器,简化活动目录集成
查看>>
保Cloudera弃Hortonworks,新平台将支持五大云供应商
查看>>
斩获BAT等7家Offer!GitHub 4万Star项目作者的面试经历
查看>>