资讯专栏INFORMATION COLUMN

从一次有趣的实验学习性能优化

canger / 2253人阅读

摘要:从一次实验学习性能优化之接口详解下图是接口的属性提供给定页面的与时间相关的性能信息包含了页面浏览上下文的导航信息,比如大量获取资源的重定向。返回当前网页事件的回调函数运行结束时的毫秒时间戳。

从一次实验学习性能优化

Web API之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包含了页面加载时间相关的性能信息。

重要的参数:

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

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

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

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

DNS查询耗时 :domainLookupEnd - domainLookupStart

TCP链接耗时 :connectEnd - connectStart

request请求耗时 :responseEnd - responseStart

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

一般白屏时间:responseStart - navigationStart

页面总耗时: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万个微博签到数据来测试两者的性能差异.

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

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

测试代码:

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个点:
Echarts画10万个点,highcharts画3000个点:]
Echarts多带带画10万个点:
highcharts多带带画3000个点:

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/84059.html

相关文章

  • 2017-07-17 前端日报

    摘要:前端日报精选听说你没来总结个人使用过的移动端布局方法新特性简介用写组件坦然面对应对前端疲劳中文深入理解笔记函数前端架构经验分享系列教程之创建页面元素龙云全栈系列教程之定位页面元素龙云全栈第期与表单验证技术周刊期知乎 2017-07-17 前端日报 精选 听说你没来 JSConf 2017?总结个人使用过的移动端布局方法 - Rni-L - SegmentFaultNode.js v8....

    caiyongji 评论0 收藏0
  • 从自编码器到生成对抗网络:一文纵览无监督学研究现状

    摘要:就在最近,这项技术在流行地无监督学习数据集上实现了非常好的结果。虽然这项工作并不针对无监督学习,但是它可以用作无监督学习。利用替代类别的无监督学习视觉表征使用图像不行来创建非常大的替代类。 如今深度学习模型都需要在大规模的监督数据集上训练。这意味着对于每一个数据,都会有一个与之对应的标签。在很流行的 ImageNet 数据集中,其共有一百万张带人工标注的图片,即 1000 类中的每一类都有 ...

    MageekChiu 评论0 收藏0
  • “信息瓶颈”理论揭示深度学本质,Hinton说他要看1万遍

    摘要:认为,深度神经网络根据一种被称为信息瓶颈的过程在学习,他和两位合作者最早在年对这一过程进行了纯理论方面的描述。另外一些研究人员则持怀疑态度,认为信息瓶颈理论不能完全解释深学习的成功。 利用深度神经网络的机器已经学会了交谈、开车,在玩视频游戏和下围棋时击败了世界冠军,还能做梦、画画,帮助进行科学发现,但同时它们也深深地让其发明者困惑,谁也没有料到所谓的深度学习算法能做得这么好。没有基本的原则指...

    wuyumin 评论0 收藏0
  • 利用遗传算法优化神经网络:Uber提出深度学训练新方式

    摘要:和的得分均未超过右遗传算法在也表现得很好。深度遗传算法成功演化了有着万自由参数的网络,这是通过一个传统的进化算法演化的较大的神经网络。 Uber 涉及领域广泛,其中许多领域都可以利用机器学习改进其运作。开发包括神经进化在内的各种有力的学习方法将帮助 Uber 发展更安全、更可靠的运输方案。遗传算法——训练深度学习网络的有力竞争者我们惊讶地发现,通过使用我们发明的一种新技术来高效演化 DNN,...

    AlienZHOU 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<