相信絕大部分的前端是使用Chrome進行開發(fā)的,一方面Chrome瀏覽器確實做得好,更重要的一方面是因為Chrome有一個無法匹敵的調(diào)試工具。用好這個調(diào)試工具可以提高編程效率,幫助快速地定位問題。
01打印
?。?)console.table
最常用的打印是console.log,console.log有時候打印一些復(fù)雜的數(shù)據(jù)結(jié)構(gòu)顯得有點吃力,如打印一個元素是object的數(shù)組:
為了查看每個數(shù)組的元素,必須得一個個展開,就顯得有點麻煩了,其實可以用console.table:
瞬間就變得非常清爽,同時console.table還支持打印對象屬性,如下的Student對象,有name和score兩個屬性:
?。?)console.dir
console.log是側(cè)重于字符串化的打印,而console.dir能遞歸打印對象的所有屬性,如下打印一個dom結(jié)點:
console.log把它的html打印出來了,而console.dir把它的所有屬性打印出來,方便進行檢查。
?。?)打印帶樣式
經(jīng)常會看到有些網(wǎng)站會在控制臺打印一些提示語,并且這些提示語還帶樣式,這個是用%c加上的樣式:
02檢查沒有用的CSS/JS
Chrome 49新增了一個功能,能夠檢查頁面上的CSS/JS沒有用到的比例,如下打開devtools的Coverage標簽欄,然后點記錄按鈕,刷新頁面,頁面加載完之后,點擊停止。就會顯示頁面用到和沒用的CSS/JS占比。沒有用到的用紅色表示,用到的用綠色表示:
可以看到第二個CSS文件有大部份是沒用到的,JS也有很大的比例沒有用到。在上面中間的窗口會把具體沒使用到的代碼標紅,就能知道具體哪些代碼沒有被用到??梢钥吹?,CSS有一半沒有用到,因為有一些是小屏的響應(yīng)式CSS,大屏沒用到。另一些是common-chunk提出來的,所以可以考慮把大小屏的CSS分開(但是不適合于內(nèi)聯(lián)Style),如下用媒體查詢?nèi)ゼ虞d不同的CSS:
link rel=”stylesheet”href=”large.css”media=”screen and (min-width:500px)”
JS也是因為require了比較大的公有模塊導(dǎo)致的,這些模塊比較大,但是只使用了其中小一部分功能,可考慮把大模塊拆細,但是?;毧赡軙黾訌?fù)雜度,所以要權(quán)衡一下。
這些功能可以用Chrome Canary嘗鮮版的使用。
03截全屏的功能
除了Corverage之外,Chrome 49還新增了截全屏的功能:
就不用去裝一個第三方的插件。
04debugger
可以在代碼里面寫一句debugger,一旦運行到dubugger就會自動卡在那里進入調(diào)試模式,使用這個有兩個好處,一個是不用手動去展開文件找到對應(yīng)的位置,因為現(xiàn)在很多人都用第三方的打包,導(dǎo)致跑的代碼和本地的代碼行數(shù)不能保持一致,所以需要去搜索相應(yīng)地代碼,比較麻煩。另外一個好處是:當(dāng)代碼是一個很大的循環(huán)的時候,并且在特定的情況下代碼會掛,由于要循環(huán)好多次,所以有時候不可能在循環(huán)里面打個斷點,然后不斷地跳到下一個斷點直到出現(xiàn)問題。所以這時候怎么辦呢?可以用條件結(jié)合debugger。如下代碼:
var scores = [90,70,58,60, …];var newScores = [88, 55, 60, …];for(var i = 0; iscores.length; i++){ for(var j = 0; jnewScores.length; j++){ if(scores[i] !== newScores[j]){ scores.push(newScores[j]); } }}
發(fā)生了死循環(huán),怎么定位在哪里出了問題呢?方法一在循環(huán)里面打個斷點,一次次執(zhí)行分析,直到發(fā)現(xiàn)問題,方法一有時候挺好用的,可能很快就可以發(fā)現(xiàn)問題了。方法二,發(fā)生死循環(huán)了肯定是i不斷得在變大,但是為什么i不會停止變大,可以加個條件,當(dāng)達到那個條件的時候進入斷點:
if(i1000000){debugger}
如上面第7行,當(dāng)i大于1000000時進入斷點,這個時候檢查一下,發(fā)現(xiàn)scores已經(jīng)變成了一個很大的array了:
所以可以進一步發(fā)現(xiàn)問題。這樣就解決了大循環(huán)里面打斷點調(diào)試的問題。
使用debugger還有一個小技巧——可以解決一個檢查頁面元素的問題。如下圖所示,當(dāng)hover到那個綠色的標簽時,會出來個詳情框:
現(xiàn)在我要檢查這個詳情框,但是我一檢查,鼠標離開了,那個框也消失了,導(dǎo)致檢查不了了,因為觸發(fā)了mouseout事件,那怎么辦呢?假設(shè)這個框是css的hover控制的,那么可以用控制臺的偽類窗口,在:hover那里打個勾,就有hover的效果:
但是這個不是用css的hover實現(xiàn)的,所以沒辦法用這個。這里有一個小技巧,就是用debugger讓頁面卡住了,mouseout事件的響應(yīng)函數(shù)就不會執(zhí)行了。如下,先在左邊的控制臺點一下進入編輯模式,然后把鼠標挪到左邊的頁面的標簽,讓那個框出來,然后再在控制臺輸入debugger回車,這個時候頁面就卡住了,接著就可以愉快地進行檢查了,如下圖所示:
05IOS真機模擬
這個雖然和Chrome沒關(guān)系,但是也可以提一下,Mac的XCode可以開一個ios系統(tǒng),操作如下圖所示,然后可以用Mac的Safari接連這個ios里面的Safari進行檢查:
如下例子調(diào)試iPhone的Safari:
上面右圖彈了一個原生的下拉,因為它是真的ios系統(tǒng),這個的好處就在于不用老是連真機調(diào)試,適合于有Mac但是沒有iPhone的同學(xué),缺點是沒辦法和真機100%一樣,例如它不彈鍵盤,它的輸入是用電腦鍵盤的輸入。不過它是100%的ios系統(tǒng),另外需要裝一個很大的XCode。
06用console.trace追蹤函數(shù)調(diào)用
現(xiàn)在遇到了一個問題,就是點擊X按鈕的時候重復(fù)發(fā)了兩個請求,如下下圖的紅框:
當(dāng)上一次請求還沒完成又要發(fā)一個新的請求的時候,代碼里面會把上一次請求abort掉,所以會看到上一個變紅了:
但是這樣還是會有問題,所以要看一下究竟是在哪里觸發(fā)了兩次請求。由于請求會走一個通用的發(fā)請求的接口,所以可以在那里追蹤一下:
ajax: function(curPage){ console.trace(“search.js ajax”); //other code}
然后控制臺就打印了兩次trace:
分別點開這兩次的代碼,就會發(fā)現(xiàn),兩次觸發(fā)分別是:一次是X的click事件調(diào)的搜索,另外一次是map的zoom_changed觸發(fā)的搜索,知道了調(diào)用的地方就好辦了,就可以做進一步分析,然后去掉其中一個。
另外一個看函數(shù)調(diào)用棧的地方是在右邊的窗口:
調(diào)用棧最多只打印5個,有時候可能會不太夠。
07查看某個函數(shù)綁的事件
控制臺Elements的下面有個Event Listeners,點最后面那個可以看到和它最相關(guān)的事件
其次,用好快捷鍵可以事半功倍,常用的快捷鍵:
F10 下一步
F8 跳到下一個斷點
command/ctrl + ; step into進入函數(shù)執(zhí)行
shift + command/ctrl + ; step out跳出當(dāng)前函數(shù)
一個實例——研究一下鼠標hover的時候它的邊界是怎么畫出來的:
首先定位到mouseover事件,因為它必定是mouseover觸發(fā)的:
一打開發(fā)現(xiàn)代碼是壓縮的:
壓縮的代碼可以點左下角的大括號,進行美化:
然后再用快捷鍵一步步的step over/step into,如果你不用快捷鍵老是一個個去點那個調(diào)試的按鈕還是挺麻煩的。如果不小心過了,就重新來一遍。最后會找到在這個函數(shù)里面畫的邊界:
08Open in Sources Pannel
在sources pannel面板如果要查看某個源文件的時候,需要一步步展開文件夾,這樣比較麻煩,而在network面板里面可以用各種篩選,但是在network里面是不能打斷點的,這個時候可以用右鍵,然后點擊Open in Sources Pannel的功能:
就會在sources面板打印相應(yīng)的文件,然后可以在sources里面進行調(diào)試了。
09模擬斷網(wǎng)做一些出錯處理
devtools還支持模擬網(wǎng)絡(luò)情況,例如可以模擬斷網(wǎng)的情況,突然掛掉了會怎么樣,然后相應(yīng)的做一些出錯處理:
如上圖出錯的時候給一個提示文案,同時恢復(fù)upload按鈕,就可以讓用戶再重新上傳。
10研究重繪
devtools有一個Renders可以用來研究重繪,如下圖右下角,把面板里面的勾都打上:
然后點擊左邊的頁面的菜單按鈕研究重排的情況。右上角黑色的框會顯示當(dāng)前的幀率。左邊變藍的區(qū)域表示需要進行重繪,由于要彈一個蒙層,所以頁面可視區(qū)域進行重繪了。同時可以看到當(dāng)前幀率是59,而且整一個過程幀率基本保持在55以上,因為這個是用transform做的動畫,所以幀率比較高。再來看一個用postion做的動畫:
可以看到幀率跌到了45,并且有相當(dāng)一小段時間幀率是在50以下,所以用postion做的動畫流暢度沒有transform的好。
11用timeline看執(zhí)行時間
如下圖所示,可以查看很多有用的信息:
這個我在《Effective前端6:避免頁面卡頓》有詳細的介紹。
12檢查內(nèi)存泄漏
基本上只要存在一個引用就不會進行GC回收,有些DOM節(jié)點沒有append到DOM,但是存在引用指向它,它就是一個分離的DOM結(jié)點,這個時候發(fā)生了DOM內(nèi)存泄漏,如下面的代碼:
var detached = null;button.on(“click”, function(){ detached = document.(“div”);})
由于閉包里面有一個變量指向一個分離的DOM結(jié)點,所以創(chuàng)建的那個變量指向的內(nèi)存空間不會被釋放掉。這個時候可以拍一張內(nèi)存堆的快照,Chrome會幫你把這些分離DOM結(jié)點用黃色標出來。
先切到Profile標簽,選中Take Heap Snapshot選項,然后點擊Take Snapshot按鈕:
然后就會把當(dāng)前內(nèi)存的使用情況顯示出來:
在搜索框里搜一下detached,出來的結(jié)果里面紅色的表示已經(jīng)分離且沒有引用,而黃色表示已經(jīng)分離且有引用,所以重點是看這些黃色的。展開其中一個分析一下,可以看到這個HTMLDivElement有一個ImageShower里的$imgContainers指向它,所以導(dǎo)致它的內(nèi)存空間不能被釋放。具體看下代碼可以看到這是DOM已經(jīng)刪了,但是圖片懶惰加載里面沒有清掉引用。所以解決辦法是當(dāng)刪掉DOM節(jié)點時,把那個ImageShower里面的變量置為null,或者把整個實例對象置為null。
13查看內(nèi)存消耗
為了查看某個操作的內(nèi)存消耗情況,可以用Record Allocation的功能記錄某個操作內(nèi)存的分配情況。
點了start按鈕之后,進行一個操作,例如彈一個框,然后點擊停止記錄的圖標,就會出來使用情況的分析,如下圖所示:
點開最上面的Object,可以看到這個Object數(shù)組開銷了553K的內(nèi)存(下圖倒數(shù)第二列第一行):
展開其中一個Object,可以看到它是一個jQuery對象,每一個消耗了88Kb:
而總的內(nèi)存可以用Chrome的任務(wù)管理器查看:
可以看到當(dāng)前頁面消耗了193Mb的內(nèi)存。所以如果當(dāng)你覺得頁面的內(nèi)存比較大的時候,或者重復(fù)某個操作之后頁面的內(nèi)存不斷增大,就可以用這種方法分析一下。
14垃圾回收
垃圾回收可以在timeline里面查看,如下圖所示:
藍線那里JS Heap驟降,說明進行了一次垃圾回收,如果發(fā)生得比較頻繁的話,可能會有問題。
15查看連接時間
如下圖所示:DNS解析花了254ms,建立tcp連接花了1.98s,建立https連接花了1.69s,從建立完連接到接收到第一個字節(jié)的數(shù)據(jù)(TTFB,Time To First Byte)等了4.3s,下載時間花了306ms(基于某次實驗)。
另外圖片的優(yōu)先級會低于CSS/JS資源,并且同一個域最多只能同時加載6個資源,所以會有排隊和等待時間,如下圖所示:
本文分析了一些devtools的一些比較好用的功能,結(jié)合自己的項目經(jīng)驗做了些實際的例子說明,希望對大家有幫助。
原文:www.renfed.com/2017/05/02/effectiv-chrome-devtools/
精選文章
↓↓↓