好用到掉渣的IE8 Developer Tools--JS效能調校經驗

對我來說,IE8最讓人興奮的新功能非"IE8 Developer Tools"莫屬!! (沒騙你們,我有文章為憑: 1 2 3

上市後,IE8立即取代Firefox成為我開發網頁時的主力測試工具,也開始體驗它的強大威力。

像是可任意下指令的Console視窗我就超愛,把整個網頁玩弄於股掌之間的感覺真好~~

就拿新聞網站為例,先用上次提過的技巧載入jquery-1.3.2.js,用HTML Tab的工具觀察DOM結構,然後可以在Script Tab的Conosle區一行一行下指令,便可邊試邊改,恣意地上下其手(邪笑),享受惡搞的樂趣,哇哈哈哈~~~ (謎之聲: 應該沒人像你這麼無聊吧?)

CSS編輯器可以任意新增Rule、啟用停用Rule的功能也很讚,這點先前已介紹過

如果你跟IE8 Developer Toolbar還不熟,點部落上好幾篇精彩的介紹文可以為你們搭起友誼的橋樑:

IE8 Dev Tools的介紹已經很多了,今天則來談談我這兩天利用它調校Javascript效能的實戰經驗。

故事是這樣的,手上的案子需要寫一個類似Excel試算表的網頁介面,總共有近1500格(120列*12欄)的大表格,每列有兩個欄位可以輸入數字,而任一格修改數字(如紅框所示)後,會影響整個分配結構,全表有大半的欄位都要重算過(如綠框所示)。

開發初期,我用最直覺的寫法,$("..input..").change()時利用$(this).parent().next()之類的技巧去找前後格子讀取數字,重新計算加總,再將結果回寫其中。一開始只有十來列時速度還OK,等到測試極端案例(120列)時,問題就大了。每更改一格的內容平均要等上3-5秒才會完成更新,有時甚至IE8會跳出Slow Script警告,詢問是否要停止執行。

觀察到這種現象,心中已有不祥預感。顫抖著雙手,用未來使用者的標準配備---老爺PC+IE6組合而成的魔王機(由來)做一次測試,果不其然,IE6以從頭到尾CPU 100%的姿態當住不動,連正常關閉程式都沒辦法。

好了,是該調校效能的時候了。永遠記得效能調校的第一步驟-->要能找出效能衡量的明確指標!

IE8 Dev Tools的Profiler可以分析並記錄各個Javascript函數被呼叫的次數以及執行所耗時間,無疑是絕佳的觀察工具。操作的方法是,先按下"Start Profiling"(橘框所在),接著在網頁上進行操作,再按下"Stop Profiling"。每次按下"Stop Profiling",就會產生一份Report,介面上有個下拉選單(藍框處)可以切換多次測試的結果進行比較。

報告結果可以依函數做統計,但我偏好的是"Call Tree"方式(紫框),可像Call Stack一樣,列出函數間彼此呼叫的來龍去脈。一般來說,我們首先關心的是累計執行時間,值愈大代表效能愈差。因此,整個調校的過程就是設法讓這個數字愈來愈小!

Call Tree檢視的好處在於,你可以先鎖定最慢的函數,展開它所呼叫的函數,再找出這些子呼叫中最慢的再展開,一路找下去,很快就能查到效能不彰的根源並加以改善,立竿見影。找到有問題的函數,右方會有函數所在的js檔案URL以及列數,點兩下,IE8 Dev Tools馬上就會在Script Tab開啟該js,並捲到該列程式所在位置,貼心到破錶吧! 當然,要改JS程式內容得回VS2008,修改後重新整理網頁,再做一次同樣動作並用Profiler監測,比較看看修改後累積耗用時間是否明顯下降。

重覆以上的步驟,我終於每次改值重算的時間由4,5秒降到1秒左右,雖不滿意,但可接受了。

應該有人很好奇Javascript程式要怎麼修改才會變快,我想這部份Case by Case,並無通用的簡便法則,有時甚至要違背一般的程式設計準則才能達到目的。(就像設計資料庫Schema時,透過"反正規化"改善查詢效率一樣)

但我還是整理一下本次修改的心得:

  • 原本的設計將數值直接存在td裡,讀寫時都要涉及UI元素的存取,是效能不彰的最大元凶。我後來利用Javascript Object在背後建立出對應表格的完整資料陣列,每次重算時先在物件陣列裡算好,再將結果寫回前端。這樣做較不直覺,且程式複雜許多,但存取UI元素比操作Javascript元件慢上數倍,為了達到預期的效能,似乎是唯一解。
  • 加總最直覺的算法是用for迴圈累加全部的數字,當其中一個值改變時,更快的寫法是將加總值扣掉原值,加上新值,避免重新跑迴圈重算。一樣的,這種設計較不直覺淺顯,但CPU耗用及速度都改善許多。
  • children()比find()快
  • 少用Regular Expression
  • 為每個td取專屬名字, 利用$("#...")找元素
  • 直接存取elem.propName取代$(elem).data("propName")
    非良好慣例,但真的變快很多
  • $(node).text("...")改寫成node.innerHTML = "..."
    因指定的文字內容很單純(純數字),所以可用這種不周全的寫法瓜代。直接寫Javascript不用jQuery,速度變快蠻多,但犠牲了相容性。
  • 不需要串接且會被大量呼叫的Plugin,就把return this.each拿掉

注意: 上述橘色斜體字部分表示非正規建議做法,純粹因加速而走的偏鋒,大家參考時要特別注意,切忌誤用!! (有個比喻,就像賽車都不裝方向燈跟喇叭一樣,是針對特殊情境才有的設計,可別任意仿效改裝你的愛車)

歡迎推文分享:
Published 08 June 2009 04:40 AM 由 Jeffrey
Views: 38,666



意見

# mOMo said on 07 June, 2009 07:18 PM

哈,看到黑暗大這篇的內容,也讓我想起之前一個case的夢彥,當時也是類似像這個Excel表的需求,只不過,是用在計算成績,使用者可以輸入每個球員的成績(高爾夫球),並每輸入一個洞數的成績就要把整個row (tr)作成績運算,也是遇到有點慢的問題,目前最高筆數是350人,也就是350*20的table,想了很多處理方式,不過有一點跟您作的一樣,就是原本的設計將數值直接存在td裡,讀寫時都要涉及UI元素的存取,是效能不彰的最大元凶。我後來利用Javascript Object在背後建立出對應表格的完整資料陣列,每次重算時先在物件陣列裡算好,因為直接操作DOM物件實在慢啊!

# Ted said on 08 June, 2009 12:10 AM

其實IE 6,7也有toolbar做到inspect DOM,跟javascript console,

http://www.debugbar.com/

不過沒有"Slow Script警告"這種功能就是了。

# maxi said on 08 June, 2009 01:55 AM

屌阿!我還沒有學會怎麼用

# 匿名 said on 09 June, 2009 02:08 AM

@@  這個方法不錯,但我還有以下疑慮。

如果把資料copy一份到Javascript裡,資源會不會佔很大?

= =|||  最害怕它用完又不放出來。(~. ~ 又要想Closure)

把IE7升到IE8,使用它的相容模式,是否現在等於在IE7下的效果?

Orz 不然的話,又要開啟VM來測試。

# Jeffrey said on 09 June, 2009 09:08 AM

to 匿名,背後Javascript物件裡多是些number, string的簡單屬性,佔用記憶體不致於大多。相形之下,如果想將資料存在DOM元素上省空間,付出的效率代價有到"致命"的程度。

我用window.myArray的方式來保存,以達到隨時可用的涵蓋性,倒沒用Closure解決。(怕生出一堆黏在函數上的分身)

據我所知,IE8的IE7相容模式,還是不完全等於IE7,但多是一些安全防護相關的特性,細節可以參考這篇: blogs.msdn.com/.../site-compatibility-and-ie8.aspx Differences between IE8 Compatibility View and IE7

# 博士家教中心 said on 23 June, 2009 08:56 AM

感謝你,不然可能完全不會去碰 ie 8,也不會去發現這種有趣的工具了

# walter said on 05 July, 2009 12:35 AM

請問我在 IE8 Profiler 按下 Start Profiling,操作完後再按下 Stop Profiling 後,URL 及 Line Number 都是空的,是否要先做什麼設定呢?謝謝!

# Jeffrey said on 05 July, 2009 02:18 AM

to walter, 若是內建的Javascript函數指令,是不會顯示URL及line number的(如我圖例中的Array.join())。寫在HTML及js中的Javascript自訂函數則會顯示檔案URL及行數,應不需額外設定才是。

# condos in hyde park said on 20 January, 2012 08:27 AM

Hi I like this comment and it is so informational and I am gonna save it. One thing to say the Indepth analysis you have done is greatly remarkable.

# Eden said on 02 June, 2013 09:34 AM

請問 Yahoo!News 會促使 IE8 當機的原因是什麼?

# Jeffrey said on 02 June, 2013 08:22 PM

to Eden, 經常性當機亦或是某個特別操作才會發生? 依經驗,大型入口網站改版時都經過測試,不致與現役瀏覽器版本嚴重不相容,而IE當機問題很高的比例與附加元件(Add-On)有關,建議你停用所有附加元件後瀏覽看看,若停用後正常,即可開始在附加元件中找尋凶手。

如果是某個特殊操作才會當機,可提供給大家幫你驗證或直接反應給Yahoo客服。

# Eden said on 02 June, 2013 09:05 PM

to Jeffrey

Yahoo!News 關於那部份我還是希望你幫忙測試一下

不知道跟我CPU是屬雙核心有沒有關係

因為他是卡在留言版那邊

# Jeffrey said on 03 June, 2013 12:26 AM

to Eden,需要有明確的URL(如果有當機畫面更好),大家才能幫你測試哦~

# Eden said on 03 June, 2013 01:18 AM

to Jeffrey

http://tw.news.yahoo.com

我現在的狀況是只要點選任何一篇新聞都會當機

# Jeffrey said on 03 June, 2013 04:48 AM

to Eden, 我的測試: IE8.0.6001.18702 on Windows XP SP3, 瀏覽tw.news.yahoo.com時,出現JavaScript錯誤(與videoplayer, flash4物件有關),但未出現當機。

# Edrn said on 03 June, 2013 07:04 AM

請問與XP SP2 ,SP3有沒有關係?

# Jeffrey said on 03 June, 2013 05:42 PM

to Eden, 很難說,目前的線索不多,難以論斷。我建議有幾個偵辦方向:

1)手邊如果找得到其他類似的IE8環境,試試是否也有當機問題? 若無,代表屬主機環境的因素造成,可試著找出主機環境間的差異。

2)是否只有Yahoo News會當機,其他任何網站都不會? 若是,則清查Yahoo News用了什麼特殊元件;若有其他網站也有狀況,會當機的網頁有什麼共通點?

3)試著停用IE的所有附加元件(Add-On)再瀏覽,若因此不當機,則逐一啟用附加元件重新驗證,以盤查誰是凶手。

4)試著重設IE[support.microsoft.com/.../zh-tw]看看。

# Eden said on 05 June, 2013 05:43 AM

to Jeffrey

改灌SP3以後問題就解決了,可是到底是為什麼?

# 王王 said on 03 September, 2013 05:20 AM

為什麼要少用regular expression

# Jeffrey said on 03 September, 2013 09:07 AM

to 王王,Regular Expression功能強大,但相對地在執行效能上不如單純的字串搜尋或取代,因此在可以用indexOf()、一般replace()解決的需求,避用RegExp可以提升網頁執行速度。

# maxi said on 08 July, 2014 10:11 PM

但直的變快很多??

還是真的變快很多??

# Jeffrey said on 09 July, 2014 06:05 AM

to maxi, 應為"真的變快很多"。謝謝指正。

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<June 2009>
SunMonTueWedThuFriSat
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011
 
RSS
創用 CC 授權條款
【廣告】
twMVC
最新回應

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication