前端除錯工具詳解(一)

NO IMAGE

原文點選開啟連結

常用的除錯工具有Chrome瀏覽器的除錯工具,火狐瀏覽器的Firebug外掛除錯工具,IE的開發人員工具等。它們的功能與使用方法大致相似。Chrome瀏覽器簡潔快速,功能強大這裡主要介紹Chrome瀏覽器的除錯工具。

開啟 Google Chrome 瀏覽器,通過下面任何一種方式進入開發人員工具:
-點選位於瀏覽器使用者介面右上角的“頁面”下拉選單,“更多工具”→“開發人員工具”。
-右鍵點選網頁上的任一元素,在彈出選單中選擇“審查元素”。
-在 Windows作業系統上,使用 Ctrl Shift I 快捷鍵開啟開發人員工具(或使用 Ctrl Shift J 直接進入 JavaScript 控制檯)。

Chrome一共有8個功能子集。如下圖:

image

每一個圖示點選後都會開啟相應的除錯面板,幫助您獲取各種不同的資訊,如 DOM 樹、資源佔用情況、頁面相關的指令碼等。通過 Ctrl [ 和 Ctrl ] 鍵,可以在這些項之間進行切換。每個模組及其主要功能為:

Element 標籤頁: 用於檢視和編輯當前頁面中的 HTML 和 CSS 元素。
Network 標籤頁:用於檢視 HTTP 請求的詳細資訊,如請求頭、響應頭及返回內容等。
Source 標籤頁:用於檢視和除錯當前頁面所載入的指令碼的原始檔。
TimeLine 標籤頁: 用於檢視指令碼的執行時間、頁面元素渲染時間等資訊。
Profiles 標籤頁:用於檢視 CPU 執行時間與記憶體佔用等資訊。
Resource 標籤頁:用於檢視當前頁面所請求的資原始檔,如 HTML,CSS 樣式檔案等。
Audits 標籤頁:分析頁面載入的過程,進而提供減少頁面載入時間、提升響應速度的方案,用於優化前端頁面,加速網頁載入速度等。
Console 標籤頁:用於顯示指令碼中所輸出的除錯資訊,或執行測試指令碼等。

學習這個章節,最主要的是多動手點點,左擊/右擊,先點看看,進而深入學習。

一.Elements:

在元素(Elements)面板中,可以看到整個頁面的 DOM 樹結構和每個元素的所有屬性(即html和css),同時也可以實時地修改這些元素及其屬性,並可以實時看到修改後的效果。

1.Styles

-點選image,點選頁面上的元素,顯示選中元素的HTML程式碼和樣式;

-編輯HTML:在工具視窗左側是html程式碼,可通過雙擊修改現有標籤的屬性值,也可選中html程式碼片段右擊選擇“Edit as HTML”進行html程式碼的修改;

-編輯屬性:在工具視窗右側顯示的是被選元素的樣式資訊,可以通過雙擊現有屬性來修改該元素的 style 屬性或應用的某個選擇器中的屬性值,也可以通過取消勾選的方式去掉一些屬性,同時頁面實時變化。

-新增屬性:滑鼠雙擊您所想修改的元素的選擇器的空白部分,即可新增屬性。新增任何屬性都必須以分號結束。你也可以直接點選 號,新增新選擇器並進行屬性操作。

jdfw

-可以直接在盒模型上更改margin和padding。

搜尋功能:當工具面板獲得焦點後,快捷鍵ctrl f會開啟搜尋框,鍵入元素關鍵字進行搜尋。

-你還可以對某個元素進行監聽,在JS對元素的屬性或者HTML進行修改的時候,直接觸發斷點,跳轉到對改元素進行修改的JS程式碼處:

image

-拖拽節點, 調整順序。拖拽節點到編輯器:

jdfw

注:畫素大小,可以通過滑鼠的滾輪調整,調整單位1px(百分比調整單位1%);按住ALt,調整單位0.1px;同時按住Shift ALt,調整單位10px。

總之,把可以點的都點一遍。

2.Computed

顯示的是所選元素的最終樣式(對應JS中的getComputedStyle()方法),Computed Style中的屬性是隻讀的,不能實時修改,所以主要用來檢視元素的最終屬性值。

Event Listeners

顯示了繫結到當前元素的事件監聽函式,而且會顯示事件冒泡或捕獲(即能夠響應此事件的所有元素)。

右擊標籤,審查元素;出現工具欄-》選單 Elements,檢視右側選單-》EventListeners,檢視元素上繫結了哪些事件:

image

預設會列出 All Nodes, 這些包括代理繫結在該節點的父/祖父節點上的事件, 因為在在冒泡或捕獲階段會經過該節點
Selected Node Only 只會列出當前節點上繫結的事件
每個事件會有對應的幾個屬性 handler, isAtribute, lineNumber, listenerBody, sourceName, type, useCapture

image

-handler是處理函式, 右鍵可以看到這個函式定義的位置, 一般 js 庫繫結事件會包一層, 所以這裡很難找到對應handler
-isAtribute 表明事件是否通過 html 屬性(類似onClick)形式繫結的
-useCapture 是 addEventListener 的第三個引數, 說明事件是以冒泡還是捕 順序執行
-右擊handler選擇“Show function definition”可以進入Sources裡js檔案中。

DOM Breakpoints

這個後面再細講。

Properties

image

Properties:顯示當前元素的DOM屬性,按照類的繼承層級排列,越靠下層級越高。最上面是一個HTMLDivElement的例項,第二個是HTMLDivElement的類。第三個,是HTMLElement類,HTMLDivElement類繼承自HTMLDivElement類。接著分別是Element類,Node類,和Object類。如果選擇不同的節點型別,就會出現不同的繼承關係。

這個很有用,可以讓你看到元素具有的方法與屬性,比查API手冊要方便,但要注意某些方法和屬性在IE、FireFox等其他瀏覽器下面的支援情況。

二.Network

image

請求的每個資源在Network表格中顯示為一行,每個資源都有許多列的內容(如紅色區塊1),不過預設情況下不是所有列都顯示出來。

Name/Path: 資源名稱以及URL路徑;
Method: HTTP請求方法;
Status/Text: HTTP狀態碼/文字解釋;
Type: 請求資源的MIME型別;

Initiator解釋請求是怎麼發起的,有四種可能的值:

Parser:請求是由頁面的HTML解析時傳送的;
Redirect:請求是由頁面重定向傳送的;
Script:請求是由script指令碼處理髮送的;
Other:請求是由其他過程傳送的,比如頁面裡的link連結點選,在位址列輸入URL地址。

Size/Content: Size是響應頭部和響應體結合起來的大小,Content是請求內容解碼後的大小。進一步瞭解可以看這裡Chrome Dev Tools – “Size” vs “Content”;
Time/Latency: Time是從請求開始到接收到最後一個位元組的總時長,Latency是從請求開始到接收到第一個位元組的時間;
Timeline: 顯示網路請求的視覺化瀑布流,滑鼠懸停在某一個時間線上,可以顯示整個請求各部分花費的時間。
以上是預設顯示的列,不過我們可以在瀑布流的頂部右鍵,這樣就可以選擇顯示或者隱藏更多的列,比如Cache-Control, Connection, Cookies, Domain等。

我們可以按照上面任意一項來給資源請求排序,只需要單擊相應的名字即可。Timeline排序比較複雜,單擊Timeline後,需要選擇根據Start Time、Response Time、End Time、Duration、Latency中的一項來排序。

紅色區塊2中,一共有6個小功能:

Record Network Log: 紅色表示此時正在記錄資源請求資訊;
Clear: 清空所有的資源請求資訊;
Filter: 過濾資源請求資訊;
Use small resource raws: 每一行顯示更少的內容;
Perserve Log: 再次記錄請求的資訊時不擦出之前的資源資訊;
Disable cache: 不允許快取的話,所有資源均重新載入。

選擇Filter後,就會出現如紅色區塊3所顯示的過濾條件,當我們點選某一內容型別(可以是Documents, Stylesheets, Images, Scripts, XHR, Fonts, WebSockets, Other)後,只顯示該特定型別的資源。在XHR請求中,可以在一個請求上右鍵選擇“Replay XHR”來重新執行一個XHR請求。

有時候我們需要把Network裡面內容傳給別人,這時候可以在資源請求行的空白處右鍵然後選擇Save as HAR with Content儲存為一個HAR檔案。然後可以在一些第三方工具網站,比如這裡重現網路請求資訊。

選定某一資源後,我們還可以Copy as cURL,也就是複製網路請求作為curl命令的引數,詳細內容看 Copying requests as cURL commands

此外,我們還可以檢視網路請求的請求頭,響應頭,已經返回的內容等資訊,如下圖:

image

資源的詳細內容有以下幾個:

HTTP request and response headers
Resource preview: 可行時進行資源預覽;
HTTP response: 未處理過的資源內容;
Cookie names and values: HTTP請求以及返回中傳輸的所有Cookies;
WebSocket messages: 通過WebSocket傳送和接收到的資訊;
Resource network timing: 圖形化顯示資源載入過程中各階段花費的時間。

注:

XPath 是一門在 XML 文件中查詢資訊的語言。XPath 用於在 XML 文件中通過元素和屬性進行導航。比如,

<a href="https://github.com/NUKnightLab/TimelineJS">這裡</a>

這裡a標籤的Xpath為:/html/body/div[2]/p[1]/a,解讀為:html裡面body標籤的第二個div標籤的第一個p標籤下的a標籤。

三.Sources

用於檢視和除錯當前頁面所載入的指令碼的原始檔。

image

-通過左邊的內容源,開啟對應的 JavaScript 檔案,滑鼠點選檔案的行號就可以設定和刪除斷點。新增的每個斷點都會出現在右側除錯區的 Breakpoints 列表中,點選列表中斷點就會定位到內容區的斷點上。如果你有多個檔案、多個斷點的話,利用 Breakpoints 列表中的斷點快速定位非常方便。

-對於每個已新增的斷點都有兩種狀態:啟用和禁用。剛新增的斷點都是啟用狀態,禁用狀態就是保留斷點但臨時取消該斷點功能。在 Breakpoints 列表中每個斷點前面都有一個核取方塊,取消選中就將禁用該斷點。斷點位置的右鍵選單中也可以禁用斷點。也可以在右側功能區上面Chrome 斷點設定 - hanguokai - 韓國愷的部落格按鈕臨時禁用所有已新增的斷點,再點一下恢復原狀態。

-條件斷點:在斷點位置的右鍵選單中選擇“Edit Breakpoint…”可以設定觸發斷點的條件,就是寫一個表示式,表示式為 true 時才觸發斷點。

-很多程式碼是壓縮/混淆過的,點選“{}”可以格式化程式碼,再點一下就取消格式化。。

-在斷點除錯時,可以用滑鼠選擇想要檢視的變數或表示式,然後右鍵選單執行“Evaluate in Console”,就可以看到該表示式的當前的值了。

1.程式碼斷點

設定斷點:在 Sources 面板 js 檔案行號處設定斷點, 這裡除了常規斷點外, 還有個條件斷點(右鍵 conditional breakpoint), 在設定的條件為 true 時才會斷電, 在迴圈中需要斷點時比較有用.
斷點後可以檢視 堆疊, 變數 資訊:

chrome除錯工具常用功能整理

在呼叫堆疊這裡可以切換到堆疊中的任何地方重新執行(右鍵restart frame), 如果想檢視斷點前的資訊時比較有用.

chrome除錯工具常用功能整理

斷點後的變數儲存到全域性
選中變數, 右鍵 Evalute in console
在 console 中選中輸出的內容, 右鍵 store as global variable

chrome除錯工具常用功能整理

2.事件斷點

元素上事件斷點:某一事件/某類事件
devtools 可以檢視某一個元素上繫結了哪些事件: Elements > Event Listeners

chrome除錯工具常用功能整理

3.DOM 斷點

一般是 dom 結構改變時觸發。 有時候我們需要監聽某個 DOM 被修改情況,而不關心是哪行程式碼做的修改(也可能有多處都會對其做修改)。那麼我們可以直接在 DOM 上設定斷點。

image

如圖所見,在元素審查的 Elements Panel 中在某個元素上右鍵選單裡可以設定三種不同情況的斷點:

子節點修改
自身屬性修改
自身節點被刪除

選中之後,Sources Panel 中右側的 DOM Breakpoints 列表中就會出現該 DOM 斷點。一旦執行到要對該 DOM 做相應修改時,程式碼就會在那裡停下來。

對上面元素上事件斷點(mouseover) 後不容易找到業務程式碼, 使用 mutation 斷點, 斷點後配合 call stack 就可以找到業務程式碼了, 如下圖

這種情況使用全域性搜尋(ctrl shift f) 程式碼中 css classname 也能找到業務程式碼, 然後直接斷點也可以。

4.XHR 斷點

右側除錯區有一個 XHR Breakpoints,點選 並輸入 URL 包含的字串即可監聽該 URL 的 Ajax 請求,輸入內容就相當於 URL 的過濾器。如果什麼都不填,那麼就監聽所有 XHR 請求。一旦 XHR 呼叫觸發時就會在 request.send() 的地方中斷。

5.全域性事件斷點

devtools 還可以對事件發生時斷點, 比如 click 發生時斷點, 這個跟 元素上事件斷點 不同, 不會限定在元素上, 只要是事件發生, 並且有 handler 就斷點; 還可以對 resize, ajax, setTimeout/setInterval 斷點.

下面這個圖是 resize 時中斷, 因為庫都代理了, 還需要在斷點處一步一步跟下去才能走到業務程式碼中.

//@ sourceURL 給 eval 出來的程式碼命名

有時候一些非常動態的程式碼是以字串的形式通過 eval() 函式在當前 Javascript context 中建立出來,而不是作為一個獨立的 js 檔案載入的。這樣你在左邊的內容區就找不到這個檔案,因此很難除錯。其實我們只要在 eval 建立的程式碼末尾新增一行 “//@ sourceURL=name“ 就可以給這段程式碼命名(瀏覽器會特殊對待這種特殊形式的註釋),這樣它就會出現在左側的內容區了,就好像你載入了一個指定名字的 js 檔案一樣,可以設定斷點和除錯了。下圖中,我們通過 eval 執行了一段程式碼,並利用 sourceURL 將它命名為 dynamicScript.js ,執行後左側內容區就出現了這個“檔案”,而它的內容就是 eval 的中的內容。

Chrome 斷點設定 - hanguokai - 韓國愷的部落格

還可以看看這個給動態編譯出來的 CoffeeScript 程式碼命名的示例:

var coffee = CoffeeScript.compile(code.value)  "//@ sourceURL="   (evalName.value || "Coffeeeeeeee!");
eval(coffee);

實際上,//@ sourceURL 不僅僅可以用在 eval 的程式碼中,任何 js 檔案、甚至是 Javascript Console 輸入的程式碼都可以用,效果一樣!

幾個常用的斷點快捷鍵:

F8: 繼續執行
F10: step over, 單步執行, 不進入函式
F11: step into, 單步執行, 進入函式
shift F11: step out, 跳出函式
ctrl o: 開啟檔案
ctrl shit o: 跳到函式定義位置
ctrl shift f: 所有指令碼中搜尋

四.TimeLine

用於檢視指令碼的執行時間、頁面元素渲染時間等資訊。

jdfw

可結合Profiles進行JavaScript效能分析。

在開始做效能優化的時候要設定一個基線,來明確這個頁面的速度到底怎樣。在時間線(timeline)標籤下開始記錄,載入頁面然後停止記錄,這樣就設定了一個基線。(開啟chrome開發者工具,點選“時間線”標籤,然後點選視窗底部圓形的黑色“記錄”圖示開始記錄)。chrome是智慧的,只有頁面開始載入的時候才會開始記錄。一般多記錄幾次(約三次)然後取了平均值。