故事是這樣的,工作專案有個大量使用JavaScript的重量級網頁,稍做修改後在工作機的IE10 @ Windows 2008 R2測試耗時居然超過10秒,比起Chrome慢上N倍,本以為這又是你知道我知道獨眼龍也知道的"IE特色",後來才發現事情沒想像單純。

同事用IE9 @ Win7執行相同網頁,速度較Chrome慢,但至少比我的電腦快了一倍以上,我才意識到"有茶包!!"。測了IE10 @ Win8筆電,IE9 @ Win7 VM,確認只有這台Windows 2008R2 IE10慢得像烏龜。

開啟IE Dev Tool的Profiler功能測錄Script執行過程,追到一段Kendo UI執行4萬多筆資料DataBinding的邏輯,呼叫了15萬次以上jQuery.isPlainObject函數及jQuery.type,耗時1.5秒,是速度如龜的根源:

對照筆電上的IE10,同樣的執行次數卻只要210ms,而且筆電CPU是i5,不如工作機是i7,速度卻快上N倍,很不合理。

抽絲剝繭,組出了一個可重現問題的迷你測試:

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
<script>
  var ary = [];
for (var i = 0; i < 42207;  i++) 
    ary.push({ a:"00000",b:"TEXT",c:1,t:"0000 TEXT" });
var st = new Date();
for (var i = 0; i < ary.length; i++) {
    var b = jQuery.isPlainObject(ary[i]);
}
alert(new Date() - st);
</script>  
</body>
</html>

這個測試在問題IE執行要耗時400ms以上,而一般的IE大概都在50ms以下,在Facebook專頁PO文請大家幫測,得到很多回饋(特此感謝!),只有兩位跟我一樣遇到慢郎中,大部分的人都是50ms以內,由此推測應是環境問題使然。

整個晚上茶包在腦中打轉,半夢半醒之間腦海還繼續精簡測試Script(我的大腦是一個IDE嗎?),自己都覺好笑。一早就睡不著爬起來,繼續將Script精簡到完全不用jQuery,純粹只呼叫一個永遠return true的函數5萬次(程式如下),猜猜怎麼了? 問題IE要耗時100ms以上,正常IE只要---0ms!!! 這個差異可大了。

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<script>
function testType( obj ) {
  return true;
}  
var obj = {a:"A"};
var st = new Date();
for (var i = 0; i < 50000; i++) {
  testType(1);
}
alert(new Date() - st);
</script>  
</body>
</html>

試過關閉所有Add-On(外掛),速度不見改善。但我做了個很關鍵的對照測試,用另一個帳號登入問題IE所在的Windows 2008 R2,開IE測試速度是正常的,由此可斷定IE本質沒問題,問題出在沾到髒東西或不正確的設定。

於是我打閞IE的進階設定選項全力進攻,試著開關不同設定,終於找出關鍵:

關鍵居然在Disable script debugging(停用指令碼偵錯)設定,停用指令碼偵錯,問題IE的執行速度立刻變成0ms;而在正常IE啟用指令碼偵錯,速度就立刻上升到近100ms。至此,困擾我近24小時的茶包懸案終告偵破!!

知道這個設定N年了,第一次發現它對執行效能影響這麼大!! 當然,連續執行同一個JavaScript函數十萬次的情境並不常見,所以在實務上它對效能的干擾並不會像我的案例被如此放大。但有一點不會錯: 如果你希望你的IE快一點,平時請保持"停用指令碼偵錯"狀態(注意: 勾選起來是停用),需要偵錯時再調整。


Comments

# by Bryan

原本選項的描述就是Disable,不勾選不就變成啟用了嗎?

# by Jeffrey

to Bryan, 是的,不勾選"停用指令碼偵錯"等於"啟用指令碼偵錯",好繞口呀! 不知道為什麼不改成"Enable script debugging"還比較直覺?

# by 小賤健

我一直以為打勾是[停用指令碼偵錯]的意思欸@@

# by Jeffrey

to 小賤健,原文寫得不好,好多人提醒有語意不清的疑慮,已修改成【如果你希望你的IE快一點,平時請保持"停用指令碼偵錯"狀態(注意: 勾選起來是停用),需要偵錯時再調整。】,希望有所改善。謝謝大家指正。

# by Scott

哇! 重要的訊息, 借分享

Post a comment