好強好強
轉載自:https://www.cnblogs.com/vvjiang/archive/2020/02/27/12370112.html
前言
工欲善其事,必先利其器。
在前端工作中,我們常常使用到Chrome開發者工具去做各種各樣的事情。
但是您真的了解這些開發者工具嗎?
官方文檔還是挺詳細的:chrome-devtools文檔。
但是文檔中仍然會有一些功能沒有描述到或者被一筆帶過。
而我的這篇指南,會略過那些一目了然的功能以及一些容易替代的方案,寫一寫那些您可能不太了解的功能和文檔描述不清的功能。
閱讀本篇文章需要有一定的前端基礎。
媒體查詢功能
Chrome開發者工具不僅可以調試web應用,還可以模擬各種終端設備。
通過激活下圖中紅框部位開啟設備工具欄。
工具欄可以切換模擬各種型號的設備,也可以通過自適應模式(Responsive)來調整視口。
這里通過更多工具中的Show media queries查看媒體查詢:
圖中藍色區塊為最大寬度斷點,黃色區塊為最小寬度斷點。
右鍵相應區塊還可以跳轉到具體的css文件中的媒體查詢代碼。
模擬傳感器(地理位置,手機朝向)
點擊更多工具中的Sensors(傳感器)
在這里可以模擬地理位置,手機朝向
生成頁面全尺寸快照圖片
通過下圖操作,可以生成一張頁面全尺寸的快照。
而它上面那個選項是生成當前視口大小的圖片。
控制台快速獲取元素面板的元素
在元素面板上選中一個元素后:
細心的朋友會發現后面總是會出現一個== $0的提示。
此時在控制台輸入$0,實際上就可以獲取到該元素。
通過這種方式,即使對於那些沒有class和id的元素,我們也可以在控制台快速獲取並使用。
您可能會問:那我要是想在控制台調用多個這樣的元素呢?
選中元素,右鍵,選擇選項:Store as global variable。
此時會將選中的元素存儲在一個臨時變量中,並自動在控制台輸出這個變量的名字。
頁面跳轉到元素面板指定的元素
某些時候頁面元素出現BUG,不知道跑到哪去了,我們需要頁面跳轉到這個元素所在的位置。
如果我們知道它的id或者class,我們可以通過在控制台輸入js命令去跳轉:
document.querySelector('.icon-cool').scrollIntoView()
當然也可以通過我們上面說到的$0做到:
$0.scrollIntoView()
但是有個更簡單的辦法,那就是右鍵元素面板上的指定元素,然后點擊Scroll into view的選項。
DOM斷點
同樣右鍵元素面板上的元素,發現有個Break on的選項,這里可以打DOM斷點。
從上往下依次是子節點改變時斷下,元素屬性改變時斷下,節點移除時斷下。
打下斷點后,在左側會有斷點標識,右側的DOM Breakpoints也會有相應的顯示。
點擊DOM Breakpoints的相應DOM斷點,元素面板也會定位到相應元素。
當js去修改指定元素的DOM結構時,就會在修改的位置斷下。
這種斷點很方便查找到究竟是哪里對頁面元素進行了修改。
元素事件偵聽器
在元素面板選中元素,右側的Event Listeners會顯示該元素上的事件。
如果勾選了Ancestors(祖先),那么會展示祖先節點的事件,通常不需要勾選這個。
點擊事件右側的鏈接可以跳轉到附加事件的代碼。
通常一些js框架或庫(比如jQeury)會將原生DOM事件進行封裝,而這會導致我們通過元素事件偵聽器跳轉到的代碼是這些庫文件的封裝代碼。
不過如果我們勾選了Framework listeners(框架偵聽器),那么就會跳轉到我們使用庫文件事件API的地方,而不是庫文件里。
Framework listeners對於jQuery這樣對事件進行簡單封裝的特別好用,但是對於React這種的話作用有限。
查看當前頁面對css和js使用覆蓋率
通過以下方式打開Coverage選項卡,這個可以查看當前頁面對css和js的使用覆蓋率。
點擊左上角按鈕開始記錄:
如上圖可以單純查看css還是js,或者都查看。
選中單個文件,還可以查看具體是哪些代碼或者css沒有使用到。
記錄期間,我們做各種操作,都會影響到這個使用覆蓋率的變動。
對於現在常用的單頁面應用而言,尤為有效,因為切換頁面實際並沒有改變html,所以這個記錄一直有效。
對於以往采用jQuery的多頁面應用而言,當切換了頁面之后,記錄就重新開始了。
不過不管是單頁面還是多頁面,通過這種方式都是可以查看相應的js和css的使用覆蓋率的,對於優化css和js,刪除無用的廢代碼,以及代碼文件拆分都很有幫助。
使用本地文件調試生產環境網站代碼
我們調試生產環境的BUG,經常需要修改樣式或者js,但是頁面一刷新這些東西就又還原了。
所以這里有個神技,可以將生產環境的引用文件進行本地化,然后修改本地化后的文件進行調試。
首先我們需要打開在Source面板下左側的Overrides選項卡,選擇一個本地文件夾作為覆蓋文件夾。
這里我選擇了一個名為test的文件夾。
然后我們切換到Source面板的Page選項卡,選中某個文件,然后右鍵,選中選項Save for overrides。
此時切回Overrides選項卡,發現test文件夾中已存在相關的js文件。
修改該文件的js內容,再保存,即使刷新之后修改后的內容依然會生效,並且頁面會加載我們修改之后的js文件。
Animation動畫檢查器
通過下圖方式可以打開Animation檢查器:
這個檢查器自動開始監聽頁面上的動畫,但是這個時候動畫已經加載完了,監聽不到,需要我們重新刷新頁面才行。
選中其中的一個動畫,會顯示如下圖的效果:
通過它我們可以查看和調整CSS動畫和過渡的各種效果。
Rendering選項卡(高亮重排重繪合成層,fps和gpu占用,滾動優化,媒體查詢模擬如打印)
Rendering選項卡,顧名思義是做一些渲染相關的事。
通過下圖方式打開Rendering選項卡:
下面是選項卡的界面:
- Paint flashing 高亮頁面重繪區域。
- Layout Shift Regions 高亮布局變動區域(重排)。
-
Layer borders 高亮合成層邊框,對於減少合成層還是挺好用的。
以上三點,如果不太清楚,可以看看這篇好文:瀏覽器渲染詳細過程:重繪、重排和 composite 只是冰山一角。
簡略一點來說,渲染過程就是DOM樹+樣式樹,合成渲染樹,渲染樹加上層疊遮罩之類的再演變為Layer樹,Layer樹再合成為為Graphics Layers即Composite Layer,再丟給GPU進行處理。
-
Scrolling Performance Issues 用於優化滾動性能問題。
這個是用來高亮可能會影響滾動性能的元素,這些元素主要指綁定了scroll事件和touch事件的元素。
scroll大家可能會比較理解,touch的話其實也可以影響滾動性能,最直觀的就是只要我們禁止了某元素上touch的事件中禁止瀏覽器默認行為,那么就不會再觸發scroll事件。
而touch的影響還不止如此,比如將touch-action改為manipulation可以減少移動端瀏覽器在用戶點擊事件的延遲,但是這個東西會影響到滾動時的性能。
當您開Scrolling Performance Issues發現頁面上一堆高亮的touch事件時,可以考慮touch-action:auto來去除。
具體的優化可能得根據實際情況去處理,哪里有問題優化哪里,取得一個平衡即可。
- Highlight ad frames 高亮用於廣告的iframe(試了下,谷歌的推廣廣告識別沒問題,百度的沒測)。
- Hit-test borders 展示點擊測試的區域。(雞肋,請忘記)。
- Emulate CSS media type 模擬媒體查詢是打印還是終端屏幕。
- Emulate CSS media feature prefers-color-scheme 模擬媒體查詢的系統主題,具體參考prefers-color-scheme。
-
Emulate CSS media feature prefers-reduced-momition 模擬媒體查詢的開啟動畫減弱功能,具體參考prefers-reduced-motion。
保留頁面控制台記錄和網絡請求記錄
Chrome的Console面板和Network面板都有Preserve Log這個選項,當勾選了這個選項后,會保留當前選項卡的控制台和請求記錄。
對於涉及到多個頁面間跳轉的問題,這個功能很有幫助。
切換控制台的執行環境(iframe中運行腳本)
Console面板上面有個名為Javascript contexts的選擇器,一般值默認為top。
top表示當前執行環境為當前頁面,而如果想切換到當前頁面各個iframe,就需要進行相應切換。
比如,在博客園首頁,我們可以切換到各個廣告iframe的運行環境。
與此相關的一個功能是,只輸出所選運行環境的打印日志:
點擊右上角齒輪打開控制台設置,勾選Selected context only即可。
控制台的實時表達式
在控制台面板有個眼睛一樣的圖標,名為:Create live express(創建實時表達式)。
點擊它創建一個入上圖紅框所示的小面板。
輸入表達式可以自動監控這個表達式。
比如如果實時表達式為a,如果a的值變動了,那么這個實時表達式的值也會變動。
控制台的API
我這里直接給開發者文檔的地址了,畢竟有點多,建議了解一下,知道有哪些功能即可。
比如monitor(監聽函數執行)和monitorEvent(監聽事件)還是有些用處的。
可重復執行的控制台腳本片段
如果您在調試BUG時總是在控制台多次重復執行大段的相同的JS代碼。
那么您可以考慮用Snippet(片段)。
這個東西雖然作用於控制台,但是卻不是在Console面板,而是在Source面板。
如圖所示,我們通過點擊New snippet新建了一個叫TestSnippet的代碼片段。
然后我們可以點擊右下角的運行或者用Ctrl+Enter在控制台運行這段代碼片段。
XHR/Fetch 斷點
在Sources面板,右側會顯示XHR/fetch Breakpoints。
點擊加號,可以輸入字符,如果輸入mynameis,那么就會在ajax請求或者fetch請求的URI包含mynameis時斷下。
如果不填,那么也會新增一行,表示斷下所有的ajax請求和fetch請求。
事件偵聽器斷點
在Sources面板,右側會顯示Event Listener Breakpoints。
顧名思義,用來給相應事件打斷點的。
這里基本上收錄了所有的事件,連WebAudio,Worker,Timer的都有。
異常斷點
同樣在Sources面板右側會顯示異常斷點的圖標:
激活后可以在各個未捕獲的異常處斷下,激活后還可以通過進一步勾選 Pause on caught exceptions在已捕獲的異常處也斷下。
腳本黑盒化(Blackbox script)
在Source面板,選中某js腳本文件后右鍵,或者在調試的堆棧中右鍵,都會出現一個Blackbox script選項。
點擊這個選項,可以讓我們在調試時認為此腳本總是對的,忽略此腳本,不論是調試過程或者堆棧都不會進入這個腳本。
一般用來黑盒化一些js庫,比如jQuery或者lodash之類的。
網絡面板的截圖功能
Network面板中有個截屏功能,開啟之后再重新加載頁面,就會如下圖顯示各個時間段下的截圖。
雙擊這些縮略圖,可以放大查看當時頁面的具體樣子。
單擊縮略圖,可以顯示當前縮略圖時間點前發送的所有請求。
網絡面板關於網絡請求的一些優化
同域名請求數量限制(HTTP/1.0或HTTP/1.1)
如果網絡請求出現排隊的情況,那么說明是在單個域上提出了太多請求。
在HTTP/1.0或HTTP/1.1連接上,Chrome每個主機最多允許六個同步TCP連接。
想要優化這一點,可以將關鍵請求提前,不關鍵請求延后。
如果都是關鍵請求,那么可以嘗試使用HTTP 2。(在Network面板可以展示Protocol顯示)
如果條件有限,可以將這些請求放在不同的域名上,然后用nginx指向同一個源頭,這樣同樣可以解決這個問題
請求第一個字節的時間過長 Time To First Byte (TTFB)
我們查看一下博客園首頁的請求。
可以看見每個請求后面都有一個綠色的區域,這個綠色區域表示每個請求的Time To First Byte (TTFB),即請求第一個字節的時間。
點開一個具體的請求,看一下:
通常原因是瀏覽器與服務端的請求連接速度很慢,或者服務端的請求響應過慢。
簡單來說,就是網絡連接慢,或者是服務端代碼寫得太辣雞。
如果是網絡連接慢,可以用CDN,或者換個近一些的服務器。
如果是服務端響應慢,那么可以考慮緩存,或者優化接口,那就是服務端的事情了。
內容下載慢
這里直接用Chrome官網的圖片吧:
一般表現於請求的下載時間過長,也就是請求后面跟着的藍條。
原因基本上就是js或者其它的一些資源文件太大了,導致下載過慢。
因為用的是100M的網,所以我比較難找這樣的例子,不過用瀏覽器的模擬3G網的話,其實博客園很多那種二次元風格,自帶一張二次元大背景的博客都會出現這種現象。
這種建議將圖片尺寸壓縮一下。
網絡面板時間分解階段說明
這里列出Timing選項卡可以看到的各個時間階段:
- Queueing(排隊):瀏覽器在以下情況下將請求排隊:
- 有更高優先級的請求。
- 已為該來源打開了六個TCP連接。僅適用於HTTP/1.0和HTTP/1.1。
- 瀏覽器正在磁盤緩存中短暫分配空間
- Stalled:出於Queueing中描述的任何原因,該請求都可能被暫停
- DNS Lookup:瀏覽器正在解析請求的IP地址
- Proxy negotiation:瀏覽器正在與代理服務器協商請求
- Request sent:請求發送時間
- ServiceWorker Preparation:瀏覽器正在啟動service worker
- Request to ServiceWorker:請求發送到service worker的時間
- Waiting (TTFB): 瀏覽器等待第一個字節響應的時間
- Content Download:響應內容下載時間
- Receiving Push:瀏覽器正在通過HTTP/2服務器推送接收此響應的數據
- Reading Push: 瀏覽器正在讀取先前接收的本地數據。
查看請求的依賴關系
各個請求都有着它們各自的依賴關系,最常見的是圖片、js和css依賴html請求。
只有在html請求完畢才會在上面慢慢加載這些資源文件。
同樣以博客園為例:
我們按住Shift,鼠標浮動到analytics.js這個請求上,可以看到www.cnblogs.com那個請求變綠了,collect那個請求變紅了。
這個表示analytics.js這個請求,依賴於www.cnblogs.com,而collect這個請求依賴於analytics.js。
WebSocket消息的監控
如下圖:
我們通過Network面板上的類型篩選到WebSocket請求,點開這個請求,我們可以看到相應的消息。
Audit面板
關於Audit面板這里不講使用方法,主要是太多了。
但是這個東西確實很方便,這里是:參考文檔。
這里要說的是這個東西需要FQ,如果翻不了,可以裝個LightHouse的擴展插件,如果下不了或者不想更新麻煩,有個更好的辦法。
使用微軟的Edge,基於Chromium的那個,然后在它的商店裝個SiteTool的擴展插件即可。
Performance面板性能分析
Performance面板主要是用來分析運行時的性能。加載的用Audit即可。
關於怎么使用這里就太多了,咱們先挑最簡單的一個流程來講。
我們首先看一下一個性能良好的結果圖:
然后我們再將CPU變慢6倍,再看一下性能不好的結果圖:
FPS概覽
對比第一張圖,我們發現第二張圖關於FPS那一行出現了很多紅色,並且綠色的高度明顯降低。
這表示它的FPS值很低,一般給用戶的感受就是很卡。出現了紅色表示會影響到用戶體驗。
CPU概覽
同時我們再對比上面兩張圖,發現第一張圖的CPU那行顏色區域都很低,而第二張圖CPU那塊都占滿了,這表示CPU占用率高。
FPS詳情
我們之前只是對哪個時間段的FPS低有了一個大致的了解,如果我們想要了解具體的情況,我們可以將鼠標浮動到Frames那一行,這樣可以了解到具體的幀的FPS。
同樣點擊選中那一幀,還可以在下方的摘要(Summary)中查看具體的情況。
CPU工作詳情
選中Main那一行,下方的摘要就會顯示主線程CPU各個活動的耗時。
但是即使如此,可能您也只能知道大致是哪個階段出了問題,比如渲染還是腳本執行時間過長。
如果想要快速定位,您可以展開Main查看具體的工作詳情。
在Main那一行的展開詳情中,可能會出現一些紅色的三角符號或者紅色區塊,點擊選中之后會有相應的優化提示,下方摘要也會展示出來。
比如上圖中就是因為強制回流導致的性能瓶頸。
可以看一下摘要中紅框中的鏈接,很方便地告訴了我們到底是哪段代碼出了問題,點擊進去:
我們可以發現是調用了offsetTop導致的回流,然后優化這部分代碼即可。
至於具體的優化我們這里就不講了,關於性能優化可以參考一下:Web Fundamentals的Performance。
關於更多性能面板的介紹可以看下:如何使用Timeline 和 Timeline事件參考。
這里說個小技巧,在Timeline上可以按Ctrl+F,然后搜索事件,這樣可以在大量的事件中快速定位想找的事件。
JavaScript分析器
還是More tools中打開JavaScript Profiler面板,怎么打開這里不講了,操作好多遍了。
然后記錄下頁面一段時間的js執行情況。
我們看到的上圖就是記錄結果,默認是分析模式是Heavy (Bottom Up)。
這個模式下可以看到哪些函數對性能影響最大並能夠檢查這些函數的調用路徑。
分析模式有下面三種:
- Chart。顯示按時間順序排列的火焰圖
- Heavy (Bottom Up)。按照函數對性能的影響列出函數,讓您可以檢查函數的調用路徑
- Tree (Top Down)。顯示調用結構的總體狀況,從調用堆棧的頂端開始。
Heavy (Bottom Up)和Tree (Top Down)比較簡單,這里直接略過。
Chart的火焰圖如下:
火焰圖越高的部分表示函數調用的堆棧越高,但是高度並不代表什么。
這樣看圖肯定是看不出來什么,所以我們需要選中一塊區域放大,如下圖:
色塊越寬表示該函數的執行時間越長,而這個才表示該函數可能需要優化。
鼠標浮動到色塊上可以看到函數執行的具體信息,這里只說幾個重要的點:
- Name。函數的名稱。
- Self time。完成函數當前的調用所需的時間,僅包含函數本身的聲明,不包含函數調用的任何函數。
- Total time。完成此函數和其調用的任何函數當前的調用所需的時間。
- URL。函數在哪個腳本中,並且它的行號。
- Aggregated self time。記錄中函數所有調用的總時間,不包含此函數調用的函數。
- Aggregated total time。函數所有調用的總時間,包含此函數調用的函數。
- Not optimized。如果分析器已檢測出函數存在優化可能,會在此處列出。
點擊相應色塊可以進到具體的函數中查看。
Memory面板
Memory面板主要用來監控頁面的內存使用情況,並解決一些內存泄漏或者頻繁的垃圾回收等問題。
Heap snapshot(堆快照)
使用堆快照一般用來解決內存泄漏的問題。
我們在內存面板Take snapshot之后,可以看到這樣一個畫面:
然后我們在上方輸入Detached,會篩選出下面的結果:
這里可以看看到底是哪些DOM節點沒有釋放。
官網文檔上顯示如果DOM節點沒有被引用,那么應該是紅色的,但是實際上不是如此。
不過這個功能還是有些用處的,選中相應的節點可以看看到底是哪些變量引用了,然后看是否能消除這些變量。
這里得注意圖中的Shallow Size表示對象自身占用內存的大小,Retained Size表示通過保持對其他對象的引用隱式占用的總內存大小,而Distance是對象到GC roots(如window或者DOM樹)的距離。
Allocation instrumentation on timeline(時間線上的內存分配工具)
翻譯起來有點繞口,實際上就是一個用來按時間查看內存分配情況的工具。
我們直接看一下檢測結果:
我們可以看到時間軸上有不少柱子,這些柱子高度會變,表示所在的那個點分配的對象大小。
我們可以看到圖中我們選中的那個時間點分配的內存大概為384byte,旁邊那個100B是一個參照線。
柱子的顏色代表這些對象是否被回收了,藍色代表還存在,灰色代表被回收了。
Application面板
這個面板內容多,但是簡單易懂,本來想着寫點的,太簡單就算了。
主要就是關於存儲和緩存的。
除此之外,就是有個關於PWA的調試,這里可以參考:調試 Progressive Web App。
我對這個涉獵較少,就不班門弄斧了。
Security面板
這個面板主要是看是否https的,有用的時候是有用,沒用的時候是真沒用。
總結
學習Chrome開發者工具不僅能提高我們工具的使用效率,這其中涉及到的很多前端知識點也能令人眼界大開。
在閱讀Chrome的開發者工具文檔時有很多缺失和不同步,這是因為它在不斷地演進,包括我現在提到的一些功能也許在將來有一天就消失或者增強了。
所以我覺得對於這份指南您可以當做一份索引,有所了解,但不必記住,只要在遇到問題的時候能記起來我可以用什么工具來處理就夠了。
希望這篇博客能幫助到您,也希望您能對疏漏之處指正一二。