用Chrome开发者工具做JavaScript性能分析

你的网站正常运转。现在我们来让它运转的更快。网站的性能由页面载入速度和代码执行效率决定。一些服务可以让你的网站载入更快,比如压缩和CDN,但是让代码执行的更快你要做的事情。

代码中很小的改动都可能对性能造成巨大的影响。快速灵活的网站和可怕的“无响应脚本”对话框可能只有几行代码的差别。这篇文章告诉你如何通过用Chrome开发者工具(Chrome Developer Tools)找到这几行关键的代码。

设置一个基线

我们来看一个简单的“颜色排序器”应用,这个应用展示了一个由各种颜色构成的网格,你可以拖拽这些颜色进行混合。每一个点都是一个div标签加上一些让它看起来是圆的的CSS。

生成这些颜色是需要技巧的,所以我借助了”Making Annoying Rainbows in Javascript”。

页面载入的很快,但还是花费了一些时间,在渲染之前还闪了一下。是时候对这个页面进行性能分析让它更快了。

在开始做性能优化的时候要设置一个基线,来明确这个页面的速度到底怎样。这个基线可以让你知道自己是否做了优化并帮助你权衡利弊。在这片文章里我们要使用chrome开发者工具。

性能分析器(profiler)是chrome开发者工具的一部分,点击小扳手下面的工具菜单就可以打开它。Firebug也有一些性能评测工具, 但是webkit内核的浏览器(chrome和safari)在对代码进行性能分析和展示时间线方面是最棒的。Chrome还提供一种很棒的事件跟踪工 具,叫做speed tracer。

在时间线(timeline)标签下开始记录,载入页面然后停止记录,这样就设置了一个基线。(打开chrome开发者工具,点击“时间线”标签, 然后点击窗口底部圆形的黑色“记录”图标开始记录)。chrome是很智能的,只有页面开始载入的时候才会开始记录。我记录了三次然后取了平均值,以防我 的电脑在第一次测试的时候运行的很慢。

我的平均基线,也就是从第一个请求到页面全部渲染结束所花费的时间是1.25秒。这个时间不是太长,但是对于这样一个小的页面来说也不算好。

我想让代码执行的更快,但是我并不知道是什么让它慢下来的。性能分析器(profiler)帮助我找到原因。

创建一个Profile

时间线(timeline)告诉我们代码运行花费的时间,但是并没有帮助我们知道代码运行的时候发生了什么。我们可以做一些改动然后不断的测每次代 码运行的时间,但这是盲目的。profiles给我们提供了更好的方法。profiler告诉我们哪些函数的执行占用了大部分时间。让我们切换到 chrome开发者工具的“Profiles”标签页开始性能测试,这里一共提供了三种类型的性能测试。

1、      javascript cpu 性能测试

显示javascript占用了多少CPU

2、      css选择器性能测试

显示处理CSS选择器占用的CPU

3、      堆栈快照

显示javascript对象的内存占用情况

我们想要javascript代码执行的更快,所以我们进行CPU性能测试。我们开始性能测试,刷新页面然后停止。

通过性能分析首先知道很多函数在执行。“颜色排序器”使用了jQuery和jQuery  UI,来处理些管理插件和解析表达式之类的事情。我发现列表最顶端的是decimalToHex和makeColorSorter两个函数。这两个函数占 用了CPU13.2%的时间,这是做优化的好地方。

我们可以点击函数调用旁边的“下一个”箭头来查看完整的函数调用堆栈。展开后,可以看到decimalToHex是被makeColorSorter调用的,makeColorSorter是通过$(document).ready调用的。

代码如下

$(document).ready(function() {

makeColorSorter(.05, .05, .05, 0, 2, 4, 128, 127,121);

makeSortable();

});

弄清楚这两个函数是哪里调用的,也就弄清楚了让颜色可以排序并不是最大的性能问题。通常情况下性能问题都是由多余的排序操作造成的,但是在我的代码中相比与排序增加DOM元素花费了更多时间。

我想要让这些函数执行的更快,但是首先我想要将我的改动区隔开。在页面载入过程中会发生很多事情,我不想要这些影响到我的性能分析。

区隔问题

我做了第二个版本,这个版本中“颜色排序器”在我点击按钮之后才载入,而不是在document ready的时候载入。这就把文档载入的过程分离出去,让我可以只对颜色分类进行性能测试。调完性能之后我可以立刻改回去。

让我们调用新的函数testColorSorter并把它绑定到一个可点击的按钮上。

function testColorSorter() {

makeColorSorter(.05, .05, .05, 0, 2, 4, 128, 127, 121);

makeSortable(); }

<button id=“clickMe” onclick=“testColorSorter();”>Click me</button>

在我们进行性能分析之前改变应用可能导致意外的结果。这个改动看起来很安全,但是我还是要重新运行性能检测器来看看我是不是无意中改变了什么。我会开始一次新的性能分析,点击应用中的按钮然后停止。

我首先注意到decimalToHex函数的载入只占用了4.23%的时间。这是代码执行花费时间最多的地方。我们创建一个新的基线来看看这个方案对代码有多大的优化。

有些事件在我点击按钮之前有触发了,但是我只关注从我点击鼠标到浏览器渲染“颜色排序器”花费的时间。鼠标在390毫秒时点击,渲染事件在726毫秒处被触发。726减去390得到我的基线336毫秒。和第一个基线一样我重复了3次来取平均值。

这时,我知道如何获得并且得到了代码确切的运行时间,我们已经准备好开始解决问题了。

让代码更高效

性能分析器只告诉我们哪个函数造成的问题,所以我们要查看下函数的源码来了解函数做了些什么。

function decimalToHex(d) {

var hex = Number(d).toString(16);

hex = “00”.substr(0, 2 - hex.length) + hex;

console.log(‘converting ’ + d + ‘ to ’ + hex);

return hex;

}

“颜色排序器”中的每一个颜色点都有一个16进制的色彩值,例如#86F01B和#2345FE.这些值表示一种颜色中红,绿,蓝三原色各自的数值。例如的背景色是#2456FE,代表红色的值是36,绿色的值是86,蓝色的是254,每一个数值必须是0到255之间的。

decimalToHex函数把这用RGB值表示的颜色转化为页面中我们使用的16进制颜色。这个函数十分的简单,但是我还是留下了一个可以去掉的调试代码console.log在那里。

decimalToHex 函数还在数字之前加上了补位。这是很重要的一点,因为有些10进制数字对应的是1个16进制数字。比如十进制中的10对应着16进制中的C,但是在CSS 中需要一个两位数。为了让这个进制换算更快速,我们让这段代码不是那么泛化。我知道每个需要补位的数字长度都为1,所以我们可以这样重写这个函数。

function decimalToHex(d) {

var hex = Number(d).toString(16);

return hex.length === 1 ? ‘0’ + hex : hex;

}

第三个版本的“颜色排序器”只有在需要补位的时候才改变字符串,并且不用调用substr函数。有了这个新函数,运行时间是137毫秒。再次对代码进行性能测试,可以发现decimalToHex函数只占用了总时间的%0.04,到了列表的下部。

我们还可以发现占用CPU最多的函数是 jQuery的e.extend.merge。我不知道这个函数的作用,因为代码是压缩过的。我可以使用开发版本的jQuery,但是我发现这个函数是被 makeColorSorter调用的。所以下一步我们先让这个函数执行的更快。

减小改动

“颜色排序器”中的多彩颜色是用过正弦曲线生成的。在光谱中设置一个中心点,然后以一定的偏移来创建这个曲线。这就把颜色变成了一个“彩虹模型”。我们还可以通过改变红绿蓝三原色的使用频率来改变颜色。

function makeColorSorter(frequency1, frequency2, frequency3, phase1, phase2, phase3, center, width, len) {

for (var i = 0; i < len; ++i) {

var red = Math.floor(Math.sin(frequency1 * i + phase1) * width + center);

var green = Math.floor(Math.sin(frequency2 * i + phase2) * width + center);

var blue = Math.floor(Math.sin(frequency3 * i + phase3) * width + center);

console.log(‘red: ’ + decimalToHex(red));

console.log(‘green: ’ + decimalToHex(green));

console.log(‘blue: ’ + decimalToHex(blue));

var div = $(‘<div class=“colorBlock”></div>’); div.css(‘background-color’, ‘#’ +

decimalToHex(red) + decimalToHex(green) + decimalToHex(blue));

$(‘#colors’).append(div);

}

}

我们要去掉console.log函数。这些调用非常的糟糕,因为每次执行都会调用decimalToHex函数,这意味着 decimalToHex函数会被多调用2倍的次数。这个函数大幅度的改变了DOM结构。每次循环,都向id为colors的div中添加一个新的 div。这就让我怀疑这就是e.extend.mergefunction做的事情。用性能分析器做一个小实验就可以搞清楚。

我想要一次把所有的div添加进去,而不是在每个循环中添加一个新的div。创建一个变量来存储数据,然后在最后一次性添加进去。

function makeColorSorter(frequency1, frequency2, frequency3, phase1, phase2, phase3, center, width, len) {

var colors = “”;

for (var i = 0; i < len; ++i) {

var red = Math.floor(Math.sin(frequency1 * i + phase1) * width + center);

var green = Math.floor(Math.sin(frequency2 * i + phase2) * width + center);

var blue = Math.floor(Math.sin(frequency3 * i + phase3) * width + center);

colors += ‘<div class=“colorBlock” style=“background-color: #’ +

decimalToHex(red) + decimalToHex(green) + decimalToHex(blue) + ‘”>

</div>’;

}

$(‘#colors’).append(colors);

}

这个小改动意味着DOM只在添加所有div的时候做一次改变。用时间线进行测试,我们发现从点击到渲染花费了31毫秒。这个dom变动,使得第四个 版本的运行时间降低了86%。我可以再次打开性能分析器(profiler),发现e.extend.merge函数占用了很少的时间,在列表中已经看不 到它了。

我们还可以完全移除decimalToHex函数让代码更快一点。因为CSS支持RGB颜色,所以我们不需要把他们转换到16进制。现在我们可以这样写makeColorSorter函数。

function makeColorSorter(frequency1, frequency2, frequency3, phase1, phase2, phase3, center, width, len) {

var colors = “”;

for (var i = 0; i < len; ++i) {

var red = Math.floor(Math.sin(frequency1 * i + phase1) * width + center);

var green = Math.floor(Math.sin(frequency2 * i + phase2) * width + center);

var blue = Math.floor(Math.sin(frequency3 * i + phase3) * width + center);

colors += ‘<div class=“colorBlock” style=“background-color: rgb(’ + red + ‘,’

+ green + ‘,’ + blue + ‘)“></div>’;

}

$(‘#colors’).append(colors);

}

第五个版本的执行只用了26毫秒而且代码行数从28行减少到18行。

在你的应用中进行Javascript性能分析

实际工作中的应用要比“颜色排序器”复杂的多,但是做性能分析要遵循同样的基本原则

1、      设置一个基线,这样你就知道你是从何处开始的。

2、      把问题从应用的其他代码隔离出来。

3、      在一个可控的环境下进行优化,频繁的使用时间线(timelines)和性能分析器(profiles)

还有一些性能优化的准则

1、      从最慢的部分开始,这样在时间优化上可以得到最大的提升。

2、      控制环境。如果你换了电脑或者做了任何大的改动,都要设置新的基线。

3、      多次分析以防你电脑的异常导致得到不正确的结果。

每个人都想要他的网站更快,你必须开发新的功能,但是新的功能通常会让网站更慢。所以花费时间来做性能优化是有价值的。

性能分析和优化使得最终版颜色分类器的执行时间减少了92%。你的网站可以变快多少?

英文原文:Zack Grossbart,编译:伯乐在线——王筱

文章来源: 伯乐在线

注:相关网站建设技巧阅读请移步到建站教程频道。

时间: 2024-10-19 19:52:18

用Chrome开发者工具做JavaScript性能分析的相关文章

《21天学通HTML+CSS+JavaScript Web开发(第7版)》——2.3 使用Google Chrome 开发者工具

2.3 使用Google Chrome 开发者工具 下载并安装Google Chrome后,启动它并访问http://getbootstrap.com/.Bootstrap是一个通用的网页框架,将在本书后面讨论.就当前而言,它很有用,因为这个网页的源代码易于理解.在Chrome中,选择菜单"更多工具">"开发者工具",这将打开开发者工具,如图2.4所示[1]. 有一个打开开发者工具的快捷键,在Windows中为Ctrl + Shift + I,在OS X中为C

[译] 在 Chrome 开发者工具中调试 node.js

本文讲的是[译] 在 Chrome 开发者工具中调试 node.js, 这篇文章介绍了一种在 Chrome 开发者工具里面开发.调试和分析 Node.js 应用程序的新方法. devtool 最近我一直在开发一个命令行工具 devtool,它可以在 Chrome 的开发者工具中运行 Node.js 程序. 下面的记录显示了在一个 HTTP 服务器中设置断点的情况. 该工具基于 Electron 将 Node.js 和 Chromium 的功能融合在了一起.它的目的在于为调试.分析和开发 Node

为什么chrome开发者工具有时候不能显示出response的内容

问题描述 从网站返回的内容,用Chrome开发者工具调试,发现不能显示返回的内容.但是返回的明明就是一个js文件,为什么查看不了? 解决方案 解决方案二:firefox一切正常解决方案三:引用1楼shingoscar的回复: firefox一切正常 我发现返回的是js代码,你知道怎么调试response返回的js吗?解决方案四:引用2楼sundacheng1989的回复: Quote: 引用1楼shingoscar的回复: firefox一切正常 我发现返回的是js代码,你知道怎么调试respo

Chrome 开发者工具的官方文档及其他前端语言开发文档

以下全部为英文文档: Chrome 开发者工具的文档: https://developers.google.com/chrome-d... JavaScript 文档,语言核心部分可以看 ECMA 规范,非常晦涩:ecma-international.org/publicat... 我一般看 Mozilla 的(需要注意 Chrome 不支持 JavaScript 1.8 的特性):developer.mozilla.org/en/JavaScript DOM API 文档直接看 w3c:w3.

使用chrome开发者工具得到的视频连接并不能用于下载

问题描述 使用chrome开发者工具得到的视频连接并不能用于下载 待下载的是:http://www.cnn.com/studentnews页面上的视频 得到的链接是:http://cnn-f.akamaihd.net/cnn/big/studentnews/2016/04/06/sn-0407.cnn_422499_,512x288_55,640x360_90,768x432_130,896x504_185,1280x720_350,0k.mp4.csmil/bitrate=1?v=3.4.1&

如何更专业的使用Chrome开发者工具

顾名思义Chrome开发工具就是一个工具,它允许Web开发人员可以通过浏览器应用程序干预和操作Web页面,也可以通过这个工具调试和测试Web页面或Web应用程序.有了这个工具,你可以做很多有趣的事情: ◆调试界面的问题 ◆使用断点调试JavaScript代码 ◆优化你的代码 打开开发者工具,你只需要在页面的任意位置右击鼠标,选择检查元素或从右上角菜单中选择"工具>更多工具>开发者工具". 下面示例演示的都是在Google Chrome的Canary浏览器下做的演示. 1.快

使用valgrind的callgrind工具进行多线程性能分析

简介 valgrind是开源的性能分析利器. 根据它的文档,可以用它来检查内存泄漏等问题,还可以用来生成函数的调用图,就这两个功能就足够有吸引力了.本文主要是介绍如何使用valgrind的callgrind工具进行性能分析. 分析过程 使用callgrind工具生成性能分析数据 命令格式如下: 1 valgrind --tool=callgrind ./exproxy 其中 ./exproxy就是我们要分析的程序.执行完毕后,就会在当前目录下生成一个文件.文件名为"callgrind.out.进

《HTML5 2D游戏编程核心技术》——第2章,第2.1节使用开发者工具

第2章 在本书中,我们将从头开始编程实现一款游戏.像所有的游戏开发者一样,在开始之前,我们必须收集原始素材,并熟悉我们的工具.对于大多数游戏来说,下面的原始素材是必备的. 图像 音效 音乐 下面的内容则是可选的,使用它们可以给你的HTML5游戏增色. 网站图标 网页背景 GIF动画 网站图标是一些小的图标,可以在浏览器的地址栏或者标签中显示.网页背景可以是图像,也可以像Snail Bait游戏一样,用CSS画出来.Snail Bait游戏在加载资源时,会显示一个GIF动画. 幸运的是,所有必要的

[译] 使用开发者工具在浏览器中调整设计

本文讲的是[译] 使用开发者工具在浏览器中调整设计, 原文地址:Using DevTools to Tweak Designs in the Browser 原文作者:AHMAD SHADEED 译文出自:掘金翻译计划 译者:bambooom 校对者:gy134340 / avocadowang 使用开发者工具在浏览器中调整设计 让我们来看看使用浏览器的开发者工具做设计工作的几种方式.你会发现一些很方便的隐藏技巧. 使用复选框切换类名 当你在从不同的选择中挑选一个设计时,或者在不手动添加类名的时