卤煮在前面已经向大家介绍了Chrome开发者工具的一些功能面板,其中包括ElementsNetworkResources基础功能部分和Sources进阶功能部分,对于一般的网站项目来说,其实就是需要这几个面板功能就可以了(再加上console面板这个万精油)。它们的作用大多数情况下是帮助你进行功能开发的。然而在你开发应用级别的网站项目的时候,随着代码的增加,功能的增加,性能会逐渐成为你需要关注的部分。那么网站的性能问题具体是指什么呢?在卤煮看来,一个网站的性能主要关乎两项,一是加载性能、二是执行性能。第一项可以利用Network来分析,我以后会再次写一篇关于它的文章分享卤煮的提高加载速度的经验,不过在此之前,我强烈推荐你去阅读《web高性能开发指南》这本书中的十四条黄金建议,这是我阅读过的最精华的书籍之一,虽然只有短短的一百多页,但对你的帮助确实无法估量的。而第二项性能问题就体现在内存泄露上,这也是我们这篇文章探讨的问题——通过Timeline来分析你的网站内存泄露。

  虽然浏览器日新月异,每一次网站版本的更新就意味着JavaScript、css的速度更加快速,然而作为一名前端人员,是很有必要去发现项目中的性能的鸡肋的。在众多性能优化中,内存泄露相比于其他性能缺陷(网络加载)不容易发现和解决,因为内存泄露设计到浏览器处理内存的一些机制并且同时涉及到到你的编写的代码质量。在一些小的项目中,当内存泄露还不足以让你重视,但随着项目复杂度的增加,内存问题就会暴露出来。首先内存占有过多导致你的网站响应速度(非ajax)变得慢,就感觉自己的网页卡死了一样;然后你会看到任务管理器的内存占用率飙升;到最后电脑感觉死了机一样。这种情况在小内存的设备上情况会更加严重。所以,找到内存泄露并且解决它是处理这类问题的关键。

  在本文中,卤煮会通过个人和官方的例子,帮助诸位理解Timeline的使用方法和分析数据的方法。首先我们依然为该面板区分为四个区域,然后对它们里面的各个功能进行逐一介绍:

  

  虽然Timeline在执行它的任务时会显得花花绿绿让人眼花缭乱,不过不用担心,卤煮用一句话概括它的功能就是:描述你的网站在某些时候做的事情和呈现出的状态。我们看下区域1中的功能先:

  

  在区域1主题是一个从左到右的时间轴,在运行时它里面会呈现出各种颜色块(下文中会介绍)。顶部有一条工具栏,从左到右,一次表示:

  1、开始运行Timeline检测网页。点亮圆点,Timline开始监听工作,在此熄灭圆点,Timeline展示出监听阶段网站的执行状态。

  2、清除所有的监听信息。将Timeline复原。

  3、查找和过滤监控信息。点击会弹出一个小框框,里面可以搜索或者显示隐藏你要找的信息。

   4、手动回收你网站内内存垃圾。

  5、View:监控信息的展示方式,目前有两种,柱状图和条状图,在展示的事例中,卤煮默认选择条状图。

  6、在侦听过程中希望抓取的信息,js堆栈、内存、绘图等。。。。

  区域2是区域1的完全版,虽然他们都是展示的信息视图,在在区域2种,图示会变得更加详细,更加精准。一般我们查看监控视图都在区域2种进行。

  区域3是展示的是一些内存信息,总共会有四条曲线的变化。它们对应表示如下图所示:

  

  区域4中展示的是在区域2种某种行为的详细信息和图表信息。

  在对功能做了简单的介绍之后我们用一个测试用例来了解一下Timeline的具体用法。

<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
div{
height: 20px;
widows: 20px;
font-size: 26px;
font-weight: bold;
}
</style>
</head>
<body>
<div id="div1">
HELLO WORLD0
</div>
<div id="div2">
HELLO WORLD2
</div>
<div id="div3">
HELLO WORLD3
</div>
<div id="div4">
HELLO WORLD4
</div>
<div id="div5">
HELLO WORLD5
</div>
<div id="div6">
HELLO WORLD6
</div>
<div id="div7">
HELLO WORLD7
</div>
<button id="btn">click me</button>
<script type="text/javascript">
var k = 0;
function x() {
if(k >= 7) return;
document.getElementById('div'+(++k)).innerHTML = 'hello world'
}
document.getElementById('btn').addEventListener('click', x); </script>
</body>
</html>

  新建一个html项目,然后再Chrome中打开它,接着按F12切换到开发者模式,选择Timeline面板,点亮区域1左上角的那个小圆圈,你可以看到它变成了红色,然后开始操作界面。连续按下button执行我们的js程序,等待所有div的内容都变成hello world的时候再次点击小圆圈,熄灭它,这时候你就可以看到Timeline中的图表信息了,如下图所示:

  

  在区域1中,左下角有一组数字2.0MB-2.1MB,它的意思是在你刚刚操作界面这段时间内,内存增长了0.1MB。底部那块浅蓝色的区域是内存变化的示意图。从左到右,我们可以看到刚刚浏览器监听了4000ms左右的行为动作,从0~4000ms内区域1中列出了所有的状态。接下来我们来仔细分析一下这些状态的具体信息。在区域2种,滚动鼠标的滚轮,你会看到时间轴会放大缩小,现在我们随着滚轮不断缩小时间轴的范围,我们可以看到一些各个颜色的横条:

  

  在操作界面时,我们点击了一次button,它耗费了大约1ms的时间完成了从响应事件到重绘节目的一些列动作,上图就是在789.6ms-790.6ms中完成的这次click事件所发生的浏览器行为,其他的事件行为你同样可以通过滑动滑轮缩小区域来观察他们的情况。在区域2种,每一种颜色的横条其实都代表了它自己的独特的意义:

  

  每次点击都回到了上面的图一样执行若干事件,所以我们操作界面时发生的事情可以做一个大致的了解,我们滑动滚轮把时间轴恢复到原始尺寸做个总体分析:

  

  可以看到,每一次点击事件都伴随着一些列的变化:html的重新渲染,界面重新布局,视图重绘。很多情况下,每个事件的发生都会引起一系列的变化。在区域2种,我们可以通过点击某一个横条,然后在区域4种更加详细地观察它的具体信息。我们以执行函数x为例观察它的执行期的状态。

  

  随着在事件发生的,除了dom的渲染和绘制等事件的发生之外,相应地内存也会发生变化,而这种变化我们可以从区域3种看到:

  

  在上文中已经向大家做过区域3的介绍,我们可以看到js堆在视图中不断地再增长,这时因为由事件导致的界面绘制和dom重新渲染会导致内存的增加,所以每一次点击,导致了内存相应地增长。同样的,如果区域3种其他曲线的变化会引起蓝色线条的变化,这是因为其他(绿色代表的dom节点数、黄色代表的事件数)也会占有内存。因此,你可以通过蓝色曲线的变化形势来确定其他个数的变化,当然最直观的方式就是观察括号中的数字变化。js内存的变化曲线是比较复杂的,里面参杂了很多因素。我们所列出来的例子实际上是很简单的。目前相信你对Timeline的使用有了一定的认识,下面我们通过一些Google浏览器官方的实例来更好的了解它的作用(因为观看示例都必须翻墙,所以卤煮把js代码copy出来,至于简单的html代码你可以自己写。如果可以翻墙的同学就无所谓了!)

  (官方测试用例一) 查看内存增长,代码如下:

  

var x = [];

function createSomeNodes() {
var div,
i = 100,
frag = document.createDocumentFragment();
for (;i > 0; i--) {
div = document.createElement("div");
div.appendChild(document.createTextNode(i + " - "+ new Date().toTimeString()));
frag.appendChild(div);
}
document.getElementById("nodes").appendChild(frag);
}
function grow() {
x.push(new Array(1000000).join('x'));
createSomeNodes();//不停地在界面创建div元素
setTimeout(grow,1000);
}

  

  通过多次执行grow函数,我们在Timeline中看到了一张内存变化的图:

  

  通过上图可以看出js堆随着dom节点增加而增长,通过点击区域1中顶部的垃圾箱,可以手动回收一些内存。正常的内存分析图示锯齿形状(高低起伏,最终回归于初始阶段的水平位置)而不是像上图那样阶梯式增长,如果你看到蓝色线条没有回落的情况,并且DOM节点数没有返回到开始时的数目,你就可以怀疑有内存泄露了。

  下面是一个用异常手段展示的正常例子,说明了内存被创建了又如何被回收。你可以看到曲线是锯齿型的上下起伏状态,在最后js内存回到了初始的状态。(官方示例二)   js代码如下:

  

var intervalId = null, params;

function createChunks() {
var div, foo, i, str;
for (i = 0; i < 20; i++) {
div = document.createElement("div");
str = new Array(1000000).join('x');
foo = {
str: str,
div: div
};
div.foo = foo;
}
} function start() {
if (intervalId) {
return;
}
intervalId = setInterval(createChunks, 1000);
} function stop() {
if (intervalId) {
clearInterval(intervalId);
}
intervalId = null;
}

 

  执行start函数若干次,然后执行stop函数,可以生成一张内存剧烈变化的图:

 

  还有很多官方实例,你可以通过它们来观察各种情况下内存的变化曲线,在这里我们不一一列出。在这里卤煮选择试图的形式是条状图,你可以在区域1中选择其他的显示方式,这个全靠个人的爱好了。总而言之,Timeline可以帮助我们分析内存变化状态(Timeline直译就是时间轴的意思吧),通过对它的观察来确定我的项目是否存在着内存泄露以及是什么地方引起的泄露。图表在展示上虽然很直观但是缺少数字的精确,通过示图曲线的变化我们可以了解浏览器上发生的事件,最主要的是了解内存变化的趋势。而如果你希望进一步分析这些内存状态,那么接下来你就可以打开Profiles来干活了。这将是我们这个系列的下一篇文章要介绍的。

Chrome开发者工具不完全指南:(三、性能篇)的更多相关文章

  1. Chrome开发者工具不完全指南(六、插件篇)

    本篇是Chrome开发者工具的结尾篇,最后为大家介绍几款功能强大的插件.在chrome商店里面有很多插件,没事建议大家去逛逛.不过需要FQ,所以诸位请自备神器.一.皮肤插件 首先是大家期盼已久,翘首以 ...

  2. Chrome开发者工具不完全指南

    Chrome开发者工具不完全指南(一.基础功能篇) Chrome开发者工具不完全指南(二.进阶篇) Chrome开发者工具不完全指南:(三.性能篇) Chrome开发者工具不完全指南(四.性能进阶篇) ...

  3. (转)Chrome开发者工具不完全指南(一、基础功能篇)

    本篇转载自卖烧烤夫斯基,并做了小部分的修改. 原文地址:Chrome开发者工具不完全指南(一.基础功能篇) 原作者:卖烧烤夫斯基 就算你不是一名前端开发工程师,相信你也不会对Chrome浏览器感到陌生 ...

  4. Chrome开发者工具不完全指南(四、性能进阶篇)

    前言 Profiles面板功能的作用主要是监控网页中各种方法执行时间和内存的变化,简单来说它就是Timeline的数字化版本.它的功能选项卡不是很多(只有三个),操作起来比较前面的几块功能版本来说简单 ...

  5. Chrome开发者工具不完全指南(五、移动篇)

    前面介绍了Chrome开发者工具的大部分内容工具,现在介绍最后两块功能Audits和Console面板.一.Audits Audits面板会针对目前网页提出若干条优化的建议,这些建议分为两大类,一类是 ...

  6. Chrome开发者工具不完全指南(二、进阶篇)

    上篇向大家介绍完了基础功能篇,这次分享的是Chrome开发工具中最有用的面板Sources.  Sources面板几乎是我最常用到的Chrome功能面板,也是在我看来决解一般问题的主要功能面板.通常只 ...

  7. Chrome开发者工具不完全指南(一、基础功能篇)

    就算你不是一名前端开发工程师,相信你也不会对Chrome浏览器感到陌生.根据最新的一份(2015/06)的浏览器市场占有率报告,Chrome近乎占有浏览器天下的半壁江山.简单.快捷使它成为了新时代人们 ...

  8. Chrome开发者工具详解(三)之浏览器调试完后如何清除所有的断点

  9. Chrome开发者工具使用指南

    前言 工欲善其事,必先利其器. 在前端工作中,我们常常使用到Chrome开发者工具去做各种各样的事情. 但是您真的了解这些开发者工具吗? 官方文档还是挺详细的:chrome-devtools文档. 但 ...

随机推荐

  1. VS2012 还原默认设置

    恢复默认设置的2种方法 如果VS出现问题或设置变乱,可以通过恢复默认设置使之回到安装成功时的状态,从而解决出现的问题.VS恢复默认设置的方法有2种,分别是:通过"导入和导出设置"实 ...

  2. Tween Animation----Translate位置移动动画

    布局: 在res/下新建一个anim文件夹用来保存动画xml文件 新建一个translate文件 代码: <?xml version="1.0" encoding=" ...

  3. Redis——学习之路二(初识redis服务器命令)

    上一章我们已经知道了如果启动redis服务器,现在我们来学习一下,以及如何用客户端连接服务器.接下来我们来学习一下查看操作服务器的命令. 服务器命令: 1.info——当前redis服务器信息   s ...

  4. Format

    strTimeZone := Format('%s ~ %s',[formatdatetime('yyyy-mm-dd',dtpStartTime.DateTime), formatdatetime( ...

  5. leanote个人版安装

    https://github.com/leanote/leanote/wiki/Leanote-%E4%BA%8C%E8%BF%9B%E5%88%B6%E7%89%88%E8%AF%A6%E7%BB% ...

  6. vim配置及快捷键

    vim+python http://codingpy.com/article/vim-and-python-match-in-heaven/ vim+c++ http://jikaichen.com/ ...

  7. 2016-2017 ACM-ICPC Northwestern European Regional Programming Contest (NWERC 2016)

    A. Arranging Hat $f[i][j]$表示保证前$i$个数字有序,修改了$j$次时第$i$个数字的最小值. 时间复杂度$O(n^3m)$. #include <bits/stdc+ ...

  8. java基础学习总结-接口

    原文链接:http://www.cnblogs.com/xdp-gacl/p/3651121.html 一.接口的概念 JAVA是只支持单继承的,但现实之中存在多重继承这种现象,如"金丝猴是 ...

  9. shell命令获取最新文件的名称

    最近有一个需求,在部署游戏战场服时,从程序包到部署需要做一些本地化的操作,手工操作费时费力,故写一个shell脚本,一键部署. 遇到的问题是每次要部署最新的程序包,因此需要shell命令获取最新的文件 ...

  10. Java反编译代码对齐

    使用反编译的代码作为jar包源码进行调试时,经常会遇到的情况是反编译后的源码之在注释里包含行号,但是与代码所在行经常对应不上.这个时候,就有必要对代码进行对齐了. ​ public class Reo ...