前言 Profiles面板功能的作用主要是監(jiān)控網(wǎng)頁中各種方法執(zhí)行時(shí)間和內(nèi)存的變化,簡(jiǎn)單來說它就是Timeline的數(shù)字化版本。它的功能選項(xiàng)卡不是很多(只有三個(gè)),操作起來比較前面的幾塊功能版本來說簡(jiǎn)單,但是里面的數(shù)據(jù)確很多,很雜,要弄懂它們需要花費(fèi)一些時(shí)間。尤其是在內(nèi)存快照中的各種龐雜的數(shù)據(jù)。在這篇博客中鹵煮將繼續(xù)給大家分享Chrome開發(fā)者工具的使用經(jīng)驗(yàn)。如果你遇到不懂的地方或者有不對(duì)的地方,可以在評(píng)論中回復(fù)鹵煮,文章最后鹵煮會(huì)最后把秘籍交出來。下面要介紹的是Profiles。首先打開Profiles面板。
一、Collect JavaScript CPU Profile(函數(shù)收集器) 首先來關(guān)注第一個(gè)功能,(Collect JavaScript CPU Profile)監(jiān)控函數(shù)執(zhí)行期花費(fèi)的時(shí)間。講道理不如舉例子,為了更清楚地了解它的功能概況,我們可以編寫一個(gè)測(cè)試列子來觀察它們的作用。這個(gè)列子簡(jiǎn)單一些,使得我們分析的數(shù)據(jù)更清晰一些。 DOCTYPE html>html>head>title>title>head>body>button id='btn'> click mebutton>script type='text/javascript'>function a() {console.log('hello world');}function b() {a();}function c() {b();}document.getElementById('btn').addEventListener('click', c, true);script>body>html>
在右邊區(qū)域中選擇Collect JavaScript CPU Profile 選項(xiàng),點(diǎn)擊下方的Start按鈕(也可以點(diǎn)擊左邊的黑色圓圈),這時(shí)候Chrome會(huì)開始記錄網(wǎng)頁的方法執(zhí)行,然后我們點(diǎn)擊界面的按鈕來執(zhí)行函數(shù)。最后再點(diǎn)擊右邊區(qū)域的Stop按鈕(或者左邊的紅色圓圈),這時(shí)監(jiān)控就結(jié)束了。左邊Profiles會(huì)列出一個(gè)文件,單擊可以看到如下界面:
二、Take Heap Snapshot(內(nèi)存快照) 下面我們來介紹一下第二個(gè)功能的用法。第二個(gè)功能是給當(dāng)前網(wǎng)頁拍一個(gè)內(nèi)存快照.選擇第二個(gè)拍照功能,按下 Take Snapshot 按鈕,給當(dāng)前的網(wǎng)頁拍下一個(gè)內(nèi)存快照,得到如下圖。 var obj = {a:1};obj.pro = { a : 100 };obj.pro.pro = { b : 200 };var two = obj.pro.pro;//這種情況下 {b:200} 就是被two引用到了,{b:200}對(duì)象引用的內(nèi)存就是CG根
function a() { var obj = [1,2,.......n]; return function() { //js作用域的原因,在此閉包運(yùn)行的上下文中可以訪問到obj這個(gè)對(duì)象 console.log(obj); }}//正常情況下,a函數(shù)執(zhí)行完畢 obj占用的內(nèi)存會(huì)被回收,但是此處a函數(shù)返回了一個(gè)函數(shù)表達(dá)式(見Tom大叔的博客函數(shù)表達(dá)式和函數(shù)聲明),其中obj因?yàn)閖s的作用域的特殊性一直存在,所以我們可以說b引用了obj。var b = a();//每次執(zhí)行b函數(shù)的時(shí)候都可以訪問到obj,說明內(nèi)存未被回收 所以對(duì)于obj來說直接占用內(nèi)存[1,2,....n], 而b依賴obj,所obj是b的最大內(nèi)存。b() 在dom中也存在著引用關(guān)系:我們通過代碼來看下這種引用關(guān)系: html> body> div id='refA'> ul> li>a>a>li> li>a>a>li> li>a id='#refB'>a>li> ul> div> div>div> div>div> body>html>script> var refA = document.getElementById('refA'); var refB = document.getElementById('refB');//refB引用了refA。它們之間是dom樹父節(jié)點(diǎn)和子節(jié)點(diǎn)的關(guān)系。script> 現(xiàn)在,問題來了,如果我現(xiàn)在在dom中移除div#refA會(huì)怎么樣呢?答案是dom內(nèi)存依然存在,因?yàn)樗籮s引用。那么我把refA變量置為null呢?答案是內(nèi)存依然存在了。因?yàn)閞efB對(duì)refA存在引用,所以除非在把refB釋放,否則dom節(jié)點(diǎn)內(nèi)存會(huì)一直存在瀏覽器中無法被回收掉。上圖:
所以你看到Constructor這一列中對(duì)象如果有紅色背景就表示有可能被JavaScript引用到但是沒有被回收。以上只是鹵煮個(gè)人理解,如果不對(duì)頭,請(qǐng)你一定要提醒鹵煮好即時(shí)更新,免得誤人子弟!接著上文,Objects Count這一列是什么意思呢?Objects Count這一列的意義比較好理解,從字面上我們就知道了其意義。就是對(duì)象實(shí)例化的數(shù)量。用代碼表示就是這樣的: var ConstructorFunction = function() {};//構(gòu)造函數(shù)var a = new ConstructorFunction();//第一個(gè)實(shí)例var b = new ConstructorFunction();//第二個(gè)實(shí)例.......var n = new ConstructorFunction();//第n個(gè)實(shí)例
global property - 全局對(duì)象(像 ‘window’)和引用它的對(duì)象之間的中間對(duì)象。如果一個(gè)對(duì)象由構(gòu)造函數(shù)Person生成并被全局對(duì)象引用,那么引用路徑就是這樣的:[global] > (global property > Person。這跟一般的直接引用彼此的對(duì)象不一樣。我們用中間對(duì)象是有性能方面的原因,全局對(duì)象改變會(huì)很頻繁,非全局變量的屬性訪問優(yōu)化對(duì)全局變量來說并不適用。 |
|