一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Chrome開發(fā)者工具不完全指南(四、性能進(jìn)階篇)

 學(xué)以致用善學(xué)用 2016-11-05

前言

  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面板。



  Profiles界面分為左右兩個(gè)區(qū)域,左邊區(qū)域是放文件的區(qū)域,右邊是展示數(shù)據(jù)的區(qū)域。在開始檢測(cè)之前可以看到右邊區(qū)域有三個(gè)選項(xiàng),它們分別代表者不同的功能:
    1.(Collect JavaScript CPU Profile)監(jiān)控函數(shù)執(zhí)行期花費(fèi)的時(shí)間
    2.(Take Heap Snapshot)為當(dāng)前界面拍一個(gè)內(nèi)存快照
    3.(Record Heap Allocations)實(shí)時(shí)監(jiān)控記錄內(nèi)存變化(對(duì)象分配跟蹤)

一、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ù)更清晰一些。

復(fù)制代碼
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>
復(fù)制代碼

 

  在右邊區(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è)文件,單擊可以看到如下界面:

  生存了一個(gè)數(shù)據(jù)表格,它們的意義在上圖中已經(jīng)標(biāo)記出來了。它記錄的是函數(shù)執(zhí)行的時(shí)間以及函數(shù)執(zhí)行的順序。通過右邊區(qū)域的類型選項(xiàng)可以切換數(shù)據(jù)顯示的方式。有正包含關(guān)系,逆包含關(guān)系,圖表類型三種選項(xiàng)。我們可以選擇其中的圖表類型:


  可以看到這個(gè)面板似曾相識(shí),沒錯(cuò),它跟之前的TimeLine面板很像,的確,雖然很像,但功能不一樣,不然也就沒必要重復(fù)做了。從上圖可以看到點(diǎn)擊按鈕執(zhí)行的各個(gè)函數(shù)執(zhí)行的時(shí)間,順序,包含關(guān)系和CUP變化等。你可以在生成文件之后在左邊區(qū)域中保存該文件記錄,下次只需要在區(qū)域2這中點(diǎn)擊load按鈕便可以加載出來。也就是說你可以本地永久地記錄該段時(shí)間內(nèi)的方法執(zhí)行時(shí)間。第一個(gè)功能大概就這么多,比較其他兩個(gè)來說簡(jiǎn)單。

二、Take Heap Snapshot(內(nèi)存快照

  下面我們來介紹一下第二個(gè)功能的用法。第二個(gè)功能是給當(dāng)前網(wǎng)頁拍一個(gè)內(nèi)存快照.選擇第二個(gè)拍照功能,按下 Take Snapshot 按鈕,給當(dāng)前的網(wǎng)頁拍下一個(gè)內(nèi)存快照,得到如下圖。

  可以看到左邊區(qū)域生成個(gè)文件,文件名下方有數(shù)字,表示這個(gè)張快照記錄到的內(nèi)存大小(此時(shí)為3.2M)。右邊區(qū)域是個(gè)列表,它分為五列,表頭可以按照數(shù)值大小手動(dòng)排序。在這張表格中列出的一些列數(shù)字和標(biāo)識(shí),以及表頭的意義比較復(fù)雜,涉及到一些js和內(nèi)存的知識(shí),我們就先從這些表頭開始了解他們。從左到右的順序它們分別表示:
  Constructor(構(gòu)造函數(shù))表示所有通過該構(gòu)造函數(shù)生成的對(duì)象
  Distance 對(duì)象到達(dá)GC根的最短距離
  Objects Count 對(duì)象的實(shí)例數(shù)
  Shallow size 對(duì)應(yīng)構(gòu)造函數(shù)生成的對(duì)象的shallow sizes(直接占用內(nèi)存)總數(shù)
  Retained size 展示了對(duì)應(yīng)對(duì)象所占用的最大內(nèi)存
  CG根!是神馬東西?在google的官方文檔中的建議是CG根不必用到開發(fā)者去關(guān)心。但是我們?cè)谶@里可以簡(jiǎn)單說明一下。大家都知道js對(duì)象可以互相引用,在某個(gè)對(duì)象申請(qǐng)了一塊內(nèi)存后,它很可能會(huì)被其他對(duì)象應(yīng)用,而其他對(duì)象又被另外的對(duì)象應(yīng)用,一層一層,但它們的指針都是指向同一塊內(nèi)存的,我們把這最初引用的那塊內(nèi)存就可以成為GC根。用代碼表示是這樣的:

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根


  用一張官方的圖可以如下表示:



  構(gòu)成這張關(guān)系網(wǎng)的元素有兩種:
  Nodes:節(jié)點(diǎn),對(duì)應(yīng)一個(gè)對(duì)象,用創(chuàng)建該對(duì)象的構(gòu)造方法來命名
  Edges:連接線,對(duì)應(yīng)著對(duì)象間的引用關(guān)系,用對(duì)象屬性名來命名
  從上圖你也可以看到了第二列的表頭Dishtance的意義是什么,沒錯(cuò),它指的就是CG根和引用對(duì)象之間的距離。根據(jù)這條解釋,圖中的對(duì)象5到CG根的距離就是2!那么什么是直接占用內(nèi)存(Shallow size)和最大占用內(nèi)存(Retained size)呢?直接占用內(nèi)存指的是對(duì)象本身占用的內(nèi)存,因?yàn)閷?duì)象在內(nèi)存中會(huì)通過兩種方式存在著,一種是被一個(gè)別的對(duì)象保留(我們可以說這個(gè)對(duì)象依賴別的對(duì)象)或者被Dom對(duì)象這樣的原生對(duì)象隱含保留。在這里直接占有內(nèi)存指的就是前一種。(通常來講,數(shù)組和字符串會(huì)保留更多的直接占有內(nèi)存)。而最大內(nèi)存(Retained size)就是該對(duì)象依賴的其他對(duì)象所占用的內(nèi)存。你要明白這些都是官方的解釋,所以即使你覺得云里霧里也是正常的,官方解釋肯定是官腔嘛。按照鹵煮自己的理解是這樣的:

復(fù)制代碼
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()
復(fù)制代碼

  在dom中也存在著引用關(guān)系:我們通過代碼來看下這種引用關(guān)系:

復(fù)制代碼
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>
復(fù)制代碼

  現(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ù)量。用代碼表示就是這樣的:

復(fù)制代碼
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í)例
復(fù)制代碼


  可以看到構(gòu)造函數(shù)在上面有n個(gè)實(shí)例,那么對(duì)應(yīng)在Objects Count這列里面就會(huì)有數(shù)字n。在這里,ConstructorFunction是我們自己定義的構(gòu)造函數(shù)。那么這些構(gòu)造函數(shù)在哪里呢,聰明的你一定可以猜到就在第一列Constructor中。實(shí)際上你可以看到列表中的Constructor這一列,其中多數(shù)都是系統(tǒng)級(jí)別的構(gòu)造函數(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ì)全局變量來說并不適用。
  roots - constructor中roots的內(nèi)容引用它所選中的對(duì)象。它們也可以是由引擎自主創(chuàng)建的一些引用。這個(gè)引擎有用于引用對(duì)象的緩存,但是這些引用不會(huì)阻止引用對(duì)象被回收,所以它們不是真正的強(qiáng)引用(FIXME)。
  closure - 一些函數(shù)閉包中的一組對(duì)象的引用
  array, string, number, regexp - 一組屬性引用了Array,String,Number或正則表達(dá)式的對(duì)象類型
  compiled code - 簡(jiǎn)單來說,所有東西都與compoled code有關(guān)。Script像一個(gè)函數(shù),但其實(shí)對(duì)應(yīng)了

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    亚洲一区二区三区在线免费| 久久婷婷综合色拍亚洲| 欧美欧美欧美欧美一区| 国产精品熟女在线视频| 午夜国产精品国自产拍av| 在线视频三区日本精品| 日韩一级免费中文字幕视频| 亚洲国产四季欧美一区| 亚洲欧美日韩在线中文字幕| 欧美av人人妻av人人爽蜜桃| 亚洲欧美中文日韩综合| 久久老熟女一区二区三区福利| 情一色一区二区三区四| 国产成人精品视频一区二区三区 | 国产熟女一区二区精品视频 | 亚洲国产婷婷六月丁香| 欧美日韩国产精品第五页| 91精品国自产拍老熟女露脸| 日本91在线观看视频| 九九热这里只有精品视频| 亚洲熟女国产熟女二区三区| 在线日本不卡一区二区| 开心久久综合激情五月天| 欧美日韩国产精品第五页| 白白操白白在线免费观看 | 日本成人三级在线播放| 欧美亚洲三级视频在线观看| 欧美偷拍一区二区三区四区| 99久热只有精品视频免费看| 亚洲av日韩av高潮无打码| 日韩一区二区三区免费av| 国产男女激情在线视频| 少妇被粗大进猛进出处故事| 九九热九九热九九热九九热| 日本和亚洲的香蕉视频| 欧美一区二区口爆吞精| 国产精品视频第一第二区| 国产免费一区二区三区av大片| 九九热精品视频在线观看| 亚洲国产成人一区二区在线观看| 亚洲国产成人久久99精品|