前端技术-调试工具(下)

五.Profiles

这个主要是作性能优化的,包括查看CPU执行时间与内存占用等。javascript

例述以下:原文地址:http://www.smashingmagazine.com/2012/06/12/javascript-profiling-chrome-developer-tools/css

你的网站正常运转。如今咱们来让它运转的更快。网站的性能由页面载入速度和代码执行效率决定。一些服务可让你的网站载入更快,好比压缩JS和CDN,可是让代码执行的更快你要作的事情。
代码中很小的改动均可能对性能形成巨大的影响。快速灵活的网站和可怕的“无响应脚本”对话框可能只有几行代码的差异。这篇文章告诉你如何经过用Chrome开发者工具(Chrome Developer Tools)找到这几行关键的代码。html

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

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

+设置一个基线

在开始作性能优化的时候要设置一个基线,来明确这个页面的速度到底怎样。这个基线可让你知道本身是否作了优化并帮助你权衡利弊。
性能分析器(profiler)是chrome开发者工具的一部分,点击小扳手下面的工具菜单就能够打开它。Firebug也有一些性能评测工具,可是webkit内核的浏览器(chrome和safari)在对代码进行性能分析和展现时间线方面是最棒的。Chrome还提供一种很棒的事件跟踪工具,叫作 speed tracer。
在时间线(timeline)标签下开始记录,载入页面而后中止记录,这样就设置了一个基线。(打开chrome开发者工具,点击“时间线”标签,而后点击窗口底部圆形的黑色“记录”图标开始记录)。我记录了三次而后取了平均值,以防个人电脑在第一次测试的时候运行的很慢。程序员

用chrome开发者工具进行JS性能分析

个人平均基线,也就是从第一个请求到页面所有渲染结束所花费的时间是1.25秒。这个时间不是太长,可是对于这样一个小的页面来讲也不算好。我想让代码执行的更快,可是我并不知道是什么让它慢下来的。性能分析器(profiler)帮助我找到缘由。web

+建立一个Profile

时间线(timeline)告诉咱们代码运行花费的时间,可是并无帮助咱们知道代码运行的时候发生了什么。profiler告诉咱们哪些函数的执行占用了大部分时间。让咱们切换到chrome开发者工具的“Profiles”标签页开始性能测试,这里一共提供了三种类型的性能测试。chrome


一、javascript cpu 性能测试
显示javascript占用了多少CPU数据库

二、css选择器性能测试
显示处理CSS选择器占用的CPU编程

三、堆栈快照
显示javascript对象的内存占用状况

咱们想要javascript代码执行的更快,因此咱们进行CPU性能测试。咱们开始性能测试,刷新页面而后中止。

用chrome开发者工具进行JS性能分析

经过性能分析首先知道不少函数在执行。我发现列表最顶端的是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();
}
1
<button id="clickMe" onclick="testColorSorter();">Click me</button>
复制代码

在咱们进行性能分析以前改变应用可能致使意外的结果。这个改动看起来很安全,可是我仍是要从新运行性能检测器来看看我是否是无心中改变了什么。我会开始一次新的性能分析,点击应用中的按钮而后中止。

用chrome开发者工具进行JS性能分析

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

用chrome开发者工具进行JS性能分析

有些事件在我点击按钮以前有触发了,可是我只关注从我点击鼠标到浏览器渲染“颜色排序器”花费的时间。鼠标在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,到了列表的下部。用chrome开发者工具进行JS性能分析

咱们还能够发现占用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=" padding: 0px; line-height: 1.5 !important;"> 
           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=" padding: 0px; line-height: 1.5 !important;"> 
           red + ',' + green + ',' + blue + ')"></div>';
    }
 
    $('#colors').append(colors);
}
复制代码

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

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

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

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

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

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

还有一些性能优化的准则

一、从最慢的部分开始,这样在时间优化上能够获得最大的提高。

二、控制环境。若是你换了电脑或者作了任何大的改动,都要设置新的基线。

三、屡次分析以防你电脑的异常致使获得不正确的结果。

每一个人都想要他的网站更快,你必须开发新的功能,可是新的功能一般会让网站更慢。因此花费时间来作性能优化是有价值的。

六.Resource

资源面板展现了页面中的全部资源。

image_thumb10_thumb

一、资源面板tab;
二、左侧栏分类列出页面资源。如“框架”、“session存储”,若是前面有箭头点击展开还能够看到更多信息。注意左侧栏的大小是能够调整的;
三、页面资源包括字体、图片、js、css和页面自己。若是页面中有frame或iframe,展开Frames会看到其对应的frame和iframe。页面层次结构更清晰
四、数据库显示页面相关的SQL数据库数据信息;
五、相应IndexedDB 也展现页面的IndexedDB 信息;
六、以键/值 形式列表展现本地存储的数据;
七、以键/值列表显示session存储数据;
八、根据域名列举cookie;
九、显示经过manifest缓存的资源。包括不少信息,如js库文件会显示文件地址、大小和类型;
十、右侧用来显示每一个资源对应的详细信息。

虽然如今由frame组成的页面愈来愈少见了,但查看框架内容的方法仍是有必要了解的。下面截图,是一个由frame组成的页面。

image_thumb12_thumb

+每一个frame都相关的资源都在一个文件夹下,一样点击展开能够了解页面的资源、js、css、图片文件和字体状况。点击选中一个框架,页面中其对应的区域会高亮显示。
注:不会列出系统已有的,如“arial”“Helvetica”等,只会列出浏览器须要下载安装的

+保存和查看资源

image_thumb131_thumb

+cookies

查看某个网站的cookie信息。如http://study.163.com/.

image_thumb17_thumb

[name]-字段名。如字段名为“remember_checked”,其值为1,这可能说明用户在登录的时候选择了记住我;
[value]-字段所对应的值。如“_twitter_sess”所对应的值为一串加密了的session ID;
[domain]-cookie所在的域。上图的“.twitter.com”代表其子域也是能够访问该cookie的;
[path]-跟域相同,设置有效的路径。设置为“/”代表容许所在路径下均可以访问cookie;
[expires]-浏览器能够删除该cookie的日期;
[size]-cookie的大小,单位bytes;
[HTTP]-cookie的访问容许HTTP协议。这能够防止跨站js获取cookie攻击;
[secure]]-只容许加密链接访问cookie,如HTTPS;

+缓存应用

[resource]-资源的完整路径。典型的资源包括静态资源和html文件,manifest文件也属于其中;
[type]-能够改变。Manifest文件的文件类型是Manifest,其余的manifest文件中定义的文件类型为explicit。Fallback类型的文件是那些须要回调资源文件的回调文件;
[size]-资源文件的大小,单位bytes;

七.Audits

用于优化前端页面,加速网页加载速度等。

使用Chrome浏览器对页面性能进行检测,根据测试的结果进行优化。固然这个结果只是参考,在实际的项目中确定有特殊状况存在,并不能为了知足某项测试结果而忽略特定状况的存在。

一、Chrome检测工具

点击Audits而后出现了以下界面,选中重载页面开始检测按钮,而后点击Run按钮,以后就是等待结果。

image_thumb22_thumb

二、检测结果

这个检测结果分为2类,一个是网络,一个是网页性能;

检测结果不只列出了问题,还定位问题在哪里,能够很快入手解决对应的问题。

1)合并JS文件:Combine external JavaScript(总共有29个能够压缩的JS文件)
2)There are multiple resources served from same domain. Consider combining them into as few files as possible.一个域名有多个文件,能够考虑将他们压缩为尽量少的文件。

3)

4)启用gzip压缩:Enable gzip compression
5)Compressing the following resources with gzip could reduce their transfer size by about two thirds (~715 B).启用gzip压缩下降传输大小。

image_thumb26_thumb

6)

image_thumb29_thumb

7)浏览器缓存:Leverage browser caching 
8)The following resources are missing a cache expiration. Resources that do not specify an expiration may not be cached by browsers。资源没有指定过时时间,浏览器可能不会缓存。

网页性能部分
1)优化样式和脚本的顺序:Optimize the order of styles and scripts (4)

2)把CSS放到head中:Put CSS in the document head (3)
CSS in the document body adversely impacts rendering performance.

3)删除没用的CSS:Remove unused CSS rules (44)
44 rules (19%) of CSS not used by the current page.

4)Use normal CSS property names instead of vendor-prefixed ones (3)

应用:本身Css代码的审核;下载复制别人代码,去除无用的Css样式。可使用FireFox的Dust-Me selectors去除无用的Css样式。

八.Console

1.console.log

你们都会用log,但鲜有人很好地利用console.error , console.warn 等将输出到控制台的信息进行分类整理。
他们功能区别不大,意义在于将输出到控制台的信息进行归类,或者说让它们更语义化。
各个所表明的语义以下:

console.log:普通讯息
console.info:提示类信息
console.error:错误信息
console.warn:警示信息

当合理使用上述log方法后,能够很方便地在控制台选择查看特定类型的信息。

image_thumb33_thumb

若是再配合console.group 与console.groupEnd,能够将这种分类管理的思想发挥到极致。这适合于在开发一个规模很大模块不少很复杂的Web APP时,将各自的log信息分组到以各自命名空间为名称的组里面。

image_thumb37_thumb

console.log第一个参数能够包含一些格式化的指令好比%c,给hello word加了很炫的样式(全是纯CSS用来控制样式的):

若是还不够过瘾,那我们来log一些图片:

jdfw_thumb5_thumb1

除此,console.table 更是直接以表格的形式将数据输出,不能赞得太多!

var data = [{'品名': 'X', '数量': 4}, {'品名': 'Y', '数量': 3}];
console.table(data);

image_thumb41_thumb

2.console.assert

当你想代码知足某些条件时才输出信息到控制台,那么你大可没必要写if或者三元表达式来达到目的,cosole.assert即是这样场景下一种很好的工具,它会先对传入的表达式进行断言,只有表达式为假时才输出相应信息到控制台。

image_thumb45_thumb

3.console.count

除了条件输出的场景,还有常见的场景是计数。
当你想统计某段代码执行了多少次时也大可没必要本身去写相关逻辑,内置的console.count能够很地胜任这样的任务。

image_thumb50_thumb

4.console.dir

将DOM结点以JavaScript对象的形式输出到控制台
而console.log是直接将该DOM结点以DOM树的结构进行输出,与在元素审查时看到的结构是一致的。不一样的展示形式,一样的优雅,各类体位任君选择反正就是方便与体贴。

image_thumb63_thumb

5.console.time & console.timeEnd

输出一些调试信息是控制台最经常使用的功能,固然,它的功能远不止于此。当作一些性能测试时,一样能够在这里很方便地进行。
好比须要考量一段代码执行的耗时状况时,能够用console.time与 console.timeEnd来作此事。

这里借用官方文档的例子:

image_thumb60_thumb

固然,咱们也能够选择本身写代码来计时:

image_thumb59_thumb

6.console.profile & console.timeLime

当想要查看CPU使用相关的信息时,可使用console.profile配合 console.profileEnd来完成这个需求。
这一功能能够经过UI界面来完成,Chrome 开发者工具里面有个tab即是Profile。

与此相似的功能还有console.timeLine配合 console.timeLineEnd,它的做用是开始记录一段时间轴,一样能够经过Chrome开发者工具里的Timeline 标签来进行相应操做。

因此在我看来这两个方法有点鸡肋,由于均可以经过操做界面来完成。但至少他提供了一种命令行方式的交互,仍是多了种姿式供选择吧。

7.console.trace

堆栈跟踪相关的调试可使用console.trace。这个一样能够经过UI界面完成。当代码被打断点后,能够在Call Stack面板中查看相关堆栈信息。

上面介绍的都是挂在window.console这个对象下面的方法,统称为Console API,接下来的这些方法确切地说应该叫命令,是Chrome内置提供,在控制台中使用的,他们统称为Command Line API。

$

彷佛美刀老是被程序员及各类编程语言所青睐「你看看PHP代码就知道PHPer有多爱钱了」,在Chrome的控制台里,便_命令返回最近一次表达式执行的结果,功能跟按向上的方向键再回车是同样的,但它能够作为一个变量使用在你接下来的表达式中:

image_thumb66_thumb

上面的使0~45DOMDOM便0会返回最近一次点选的DOM结点,以此类推,$1返回的是上上次点选的DOM节点,最多保存了5个,若是不够5个,则返回undefined。

另外值得一赞的是,Chrome 控制台中原生支持类jQuery的选择器,也就是说你能够用$加上熟悉的css选择器来选择DOM节点

image_thumb69_thumb

(selector)DOM(selector)是原生JavaScript document.querySelector() 的封装。
同时另外一个命令$$(selector)返回的是全部知足选择条件的元素的一个集合,是对document.querySelectorAll() 的封装。

copy

经过此命令能够将在控制台获取到的内容复制到剪贴板。

copy(document.body);

keys & values

这是一对基友。前者返回传入对象全部属性名组成的数据,后者返回全部属性值组成的数组。具体请看下面的例子:

image_thumb71_thumb

monitor & unmonitor

monitor(function),它接收一个函数名做为参数,好比function a,每次a被执行了,都会在控制台输出一条信息,里面包含了函数的名称a及执行时所传入的参数。

而unmonitor(function)即是用来中止这一监听。

jdfw_thumb11_thumb1

debug & undebug

debug一样也是接收一个函数名做为参数。当该函数执行时自动断下来以供调试,相似于在该函数的入口处打了个断点,能够经过debugger来作到,同时也能够经过在Chrome开发者工具里找到相应源码而后手动打断点。
而undebug 则是解除该断点。

而其余还有好些命令则让人没有说的欲望,由于好些均可以经过Chrome开发者工具的UI界面来操做而且比用在控制台输入要方便。

移动设备模式

如今不少的网页都要适配移动端,Chrome的移动设备模式对开发者来讲无疑是一个很大的惊喜。

点击image_thumb_thumb,能够模拟各类各样的移动设备

image_thumb7_thumb

拖动模拟屏幕的标记的两块东西能任意调节设备屏幕大小

顶部橙色部分的选项,这个是选择各类要模拟的设备

下面的是当前设备的显示屏像素

image_thumb1
去掉前面的勾,或者点击这个删除的按钮,网页将会回到你如今的浏览器显示大小

image_thumb2[1]
点这个还能快速切换横屏竖屏

image_thumb3
这个是当前模拟的设备的像素比,例如:iPhone3GS是一、iphone4是二、iPhone6是3....

image_thumb4
若是你在操做的时候遇到这个警告,那么你须要刷新下网页才能看到实际的显示效果

image_thumb6

这里的这个Fit是若是你选择的模拟设备像素的显示范围超过了你的浏览器框框,那么就会根据你当前的显示器高度和宽度自适应的缩放显示比例。去掉勾选就是实际像素的显示了。

image_thumb7[1]

而后咱们来看看右边蓝色的部分 第一个Network是用来模拟网络环境的。你能够模拟各类网络环境以测试网页的加载速度,甚至能够模拟断网的状态...

image_thumb8_thumb

移动设备模式暂时就介绍到这里。

---------------------------------------------------

就像开始说的,最主要的是本身多打开调试工具多点点,相信用多了就会熟悉。

转载需注明转载字样,标注原做者和原博文地址。

前端技术-调试工具(上)

更多阅读:

http://segmentfault.com/a/1190000000683599

http://www.ibm.com/developerworks/cn/web/1410_wangcy_chromejs/

相关文章
相关标签/搜索