[Tool]使用Chrome的Web Developer Tool偵錯

[Tool]使用Chrome的Web Developer Tool偵錯

前言
拜ASP.NET Webform上的server control所賜,讓開發Web page的門檻大大降低,但相對地也帶來了許多『ASP.NET工程師』不了解HTML, CSS與JavaScript。

常見的情況就是:

  1. 什麼處理動作,都要postback回server端,寫server端的code處理。
  2. 要控制Render出來的HTML,都只會透過server control的property來控制。
  3. 只會透過Visual Studio偵錯。


這樣的情況,在現在front-end提供了越來越多fancy的framework或plugin的趨勢下,顯得問題更加嚴重。如果您偵錯JavaScript,還是只會透過alert,或是驗證HTML與CSS的套用,還是只能透過.aspx上的設計模式,那希望這篇文章可以讓您提升到另一個層次。

這篇文章要介紹的工具是Chrome瀏覽器裡內建的web developer tool (與
FireBugFirefox 10.0內建的Web developer tool大同小異),只是介紹Chrome上developer tool的基本功能,也就是可以幫助我們做什麼樣的事情,各個web developer tool的比較,則不在此篇討論範圍。

介紹
當使用Chrome瀏覽某個網頁的時候,按下F12,即會開啟web developer tool的介面。 第一次預設會停在Elements的頁籤,則可以看到這一個網頁的HTML原始碼。

image 

Elements
選下面toolbar上的放大鏡(Inspector),便可以選擇頁面上任何一個區塊,網頁上的DOM即會反白或增加外框,最下面的toolbar則會顯示您選擇的DOM,它所屬的DOM tree階層。舉個例子,當我們選擇<body>時,結果如下:

image 

  • Matched CSS Rules
    在右邊的Matched CSS Rules區塊,是這代表著選取的這個DOM,所有符合的CSS rules有哪些,且現在套用的是哪一個style sheet底下的rule。因為CSS的套用,是有階層順序的,以上圖來說,目前正在套用的rule為Sample.aspx第10行,裡面的body style宣告backgroud-color為purple。其他相符合的css,還包括了Joey.css裡面第2行,宣告body style顏色為red,上面帶著刪除線,代表這個rule沒被套用。而user agent stylesheet,則可以想像成是Chrome browser預設給DOM的一些修飾呈現方式。

    點選CSS rule上的hyperlink,則可以開啟該rule所屬的css設定檔案,例如點選Sample.aspx。這樣可以方便我們直接trace該rule檔案是哪一支,其他相關設定為何。

    image

    在原本的設定中,body的背景色為Sample.aspx上設定的紫色:
    image
    當我們將Sample.aspx的css rule的checkbox取消勾選時,可以看到body的背景色,換套用了Joey.css的紅色,這樣的功能可以很方便地調整樣式設定以及找出css階層的套用順序問題。
    image

    當然,這樣的功能也支援即時的編輯、預覽,甚至還提供了intellisense,例如將red改輸入yel,會出現yellow以及yellowgreen,且網頁上會即時套用樣式。要注意的是,這邊改的css,指的是放在browser裡面本地端的檔案,而非server上的檔案。若需要在client修改,並自動儲存回server端,可以透過chrome-devtools-autosave來達到這樣的需求,簡介請參考:Auto-saving CSS And JavaScript Changes Locally From The Chrome Developer Tools
    image


Scripts
透過web developer tool來協助偵錯JavaScript,這是身為一個web developer一定要會的技能。

當切到Scripts頁籤時,可以看到這個網頁上作用的所有js檔案。

image 

在所有作用的js檔上,如同熟悉的IDE一般,我們可以在js程式碼上設定中斷點,當呼叫到該行時,就可以透過IDE中斷點來進行偵錯,觀察相關的變數、DOM的attribute、event或值。


image 

例如當在text中輸入1234,會觸發CustomValidator的client validation function:SampleValidate(),則js會中斷在剛剛設定的第134行。 
 
1

更讚的是,Call Stack的區塊,直接視覺化的呈現到中斷點時的Call Stack為何。以這例子來說,第134行屬於SampleValidate()這個function,所以在Call Stack中,SampleValidate反白,且標示出在哪一支檔案的第幾行。
image
當點選Call Stack上任一function時,就可以清楚看到目前中斷的程式碼,相關的進入點為何。例如點選ValidateOnChange,這是屬於WebResource.axd上的功能,也是大部分ASP.NET內建JavaScript的檔案。可以看到原生ASP.NET提供的JavaScript function。
image

我們也可以透過將要觀察的部分,選取後按滑鼠右鍵,選Add to watch。或是直接在Watch Expressions上選+按鈕後,輸入要監看的變數,即為加入監看式,就可以該時間點相關的資訊。
image

Button bar的部份,就如同一般IDE偵錯中斷點提供的功能一樣:

  1. Pause Script execution(F8):到下一個中斷點才停止
  2. Step over next function call (F10):跳到下一行
  3. Step into next function call(F11):追進去這個function
  4. Step out of current function(shift+F11):執行完目前的function (跳出這個function)
  5. Deactive/Active all breakpoints:單鍵開關中斷點是否作用,不會取消所有中斷點標示!!

當滑鼠移到js的片段上,也會以類似tooltip的方式,出現即時的監看資訊。
image

除了提供如一般IDE的中斷方式來偵錯JavaScript,Chrome web developer tool更提供了一些相當實用的trigger中斷方式。例如:DOM發生變化時中斷、呼叫某個符合條件的XHR(XmlHttpRequest,也就是ajax)時中斷、發生exception時的中斷等等…

當DOM發生改變時,中斷執行正在改變此DOM的JavaScript
DOM改變有三種情況:

  1. subtree modifications: 該DOM裡面的subtree發生變化時中斷,以便知道是哪段js改變了subtree。
  2. attributes modifications: 該DOM上的attribute發生變化時中斷,以便知道是哪段js改變了這個DOM的attribute。
  3. node removal: 該DOM被移除時中斷,以便知道是哪段js移除了這個DOM。

舉例來說,我們在CustomerValidator的<span>上,掛上hook,來追蹤什麼時候display會從none,改為inline而顯示出error meesage。display是DOM的attribute,所以只需要break on attributes modifications。
image

在DOM Breakpoints區塊上,可以看到我們監聽的DOM,例如CustomValidator1 Render出來的HTML為span#CustomValidator1。
image 

當在text輸入123456時,onchange會觸發驗證,驗證邏輯為當輸入長度大於2時,代表驗證錯誤。而程式碼會停在WebResource.axd裡面,控制Validator顯示的JavaScript。

image 

另外,下方button bar有個{}的按鈕,當JavaScript可能經過壓縮或原本就不適合查看,可以透過這個pretty print按鈕,來進行排版,以便偵錯。例如引用jQuery.min.js,這是壓縮後的js,沒有排版前如下圖:

image

排版後如下圖,雖說因為jQuery.min.js的壓縮是連變數與function都壓縮,但必要偵錯時,排版後還是對偵錯很有幫助。
image 

Exception的處理
Exception的處理也有三種:

  1. 預設:exception不中斷(黑色)
    image
  2. 只要發生exception,不管有沒有handle,都要中斷(藍色)
    image
  3. 當發生未處理的exception時,才要中斷(紫色),同IE的js error發生情況
    image

例如我們寫了2個function,都使用了$a這個未宣告的變數,其中一個function有用try catch處理,另一個則沒有。

有發生exception就要中斷的情況,當點了btnHandleException,程式碼會在發生exception的點中斷:

image 

假如是紫色按鈕,只有發生Unhandled exception時,才會中斷。當點選原本的btnHandleException,則不會中斷,直接alert(沒有中斷)。但是當點了btnUnHandleException時,則會停在131行的$a.error();

image

當發生XHR時中斷
可以設定XHR的request url包含什麼字串時,中斷。若無設定,則代表所有XHR都要中斷。

舉例來說,當document ready時,會呼叫一個Handler.ashx


        $(function () {
            //            console.profile("ajax data");
            $.ajax(
                {
                    url: "Handler.ashx",
                    type: "post",
                    data: { "a": "joey", "b": 1 },
                    format: "json",
                    success: function (data) {
                        alert(data);
                    }
                }
            );
        });

舉例來說,我們只需要在XHR Breakpoints的區塊上,點+,填入Han,這樣只要XHR request的url有包含Han的,都要中斷。(請注意,有分大小寫)
image

重新載入網頁後,因為對Handler.ashx發出XHR,js就會中斷。
image 

可以點一下Call Stack上Sample.aspx的(anonymous function),就可以看到這個XHR是我們剛剛的JavaScript $.ajax()發動的。
image 

Console的功能
因為XHR發動是非同步的,往往許多要追蹤的資訊都在XHR的過程中miss掉,所以這個tool也提供了一個好功能,在Console的頁籤中,滑鼠右鍵,可以將Log XMLHttpRequests打勾。

image

再重新載入頁面一次,可以看到Console幫忙記錄了這次XHR的call stack相關資訊。
image 

當點選XHR的url link的時候,會直接跳到Network頁籤,顯示整個頁面載入時的相關記錄。

image

再點入Handler.ashx時,則可以看到更詳細的資訊。例如:Preview/Response,可以看到XHR的回應。
image

更重要的是可以在Headers中,看到XHR發動時,Request的相關資訊,例如送了哪些資料給server端。在每個分類,也提供了很貼心的設計,可以看到原始的資訊,或是tool幫你解析完的資訊。
image

用Console.log來取代alert偵錯
使用方式相當簡單,在js中寫下console.log(你的obj); 就像echo的作用一樣,會把這個obj dump log起來。

舉例來說,使用alert來呈現資訊,如果alert是個物件、function,則只會出現[object Object]

image

但如果是使用console.log(),就可以在Console頁籤底下看到相關的資訊。
image 

在Console頁籤底下,可以即時執行任何我們想執行的JavaScript,例如:輸入$('input'),可以得到所有的input元素。

image
例如輸入$(':button').hide(),可以看到網頁上的button都隱藏,且列出所有受影響的DOM。
image 

console還有個特別的API: console.profile()。就像Stopwatch的使用方式,透過console.profile("profile name")來開始記錄profile,透過console.profileEnd()來結束記錄。例如在$.ajax()前後加上profile記錄。


            console.profile("ajax data");
            $.ajax(
                {
                    url: "Handler.ashx",
                    type: "post",
                    data: { "a": "joey", "b": 1 },
                    format: "json",
                    success: function (data) {
                        alert(data);
                    }
                }
            );
            console.profileEnd();

執行後在Console的log可以看到記錄:
image

開啟Profiles的頁籤,則可以看到我們記錄的profile。上面可以看到每一個function所花費的時間跟比例。
image

console所提供的API,Firebug上有的,Chrome都有支援,請參考:這邊

Resources與Audits則類似YSlow的功能,有針對下載各類檔案size與比例的呈現,以及簡單的peformance和寫法建議(例如壓縮、Cache與js擺放位置等等…),這邊就不贅述了。

最後,該tool在右下角有提供Setting的功能,讓developer可以統一設定一些選項,例如要不要關閉網頁Cache,要不要log XHR,Color format要以哪種方式呈現等等…

image

結論
沒想到林林總總的把大部分功能run了一遍,原本只是想簡單介紹js偵錯而已。

但從這烙烙長的說明與擷圖,相信讀者已經對Chrome的web developer tool可以對我們有哪些幫助一清二楚了。不要再透過alert來偵錯js,不要再透過Visual Studio來偵錯js。熟悉一下web developer tool,您才對得起web developer這個職務內容。

Reference

  1. Chrome Developer Tools: Overview
  2. Chrome Developer Tools: Breakpoints

或許您會對下列培訓課程感興趣:

  1. 2019/3/15(五)~2019/3/17(日):C#進階設計 201903 第一梯次(台北)
  2. 2019/5/4(六)~2019/5/5(日):Clean Coder: DI 與 AOP 進階實戰 201905 第一梯次(台北)
  3. 2019/5/18(六):【單元測試實戰營】第六梯次(台北)
  4. 2019/5/19(日):【極速開發】第七梯次(台北)
  5. 2019/6/15(六)~2019/6/16(日):工程實踐與流程規範導入實務 201906 第一梯次(台北)
  6. 2019/7/27(六)~2019/7/28(日):演化式設計:測試驅動開發與持續重構 第六梯次(台北)

想收到第一手公開培訓課程資訊,或想詢問企業內訓、顧問、教練、諮詢服務的,請洽 Facebook 粉絲專頁:91敏捷開發之路