IE:執行超過500W條JScript引擎語句出現提示。
Firefox:執行超過10秒出現提示。
Safari:執行超過5秒出現提示。
Opera:無論執行多久都不會出現提示,最有耐性。
Chrome:執行超過約8秒(估計值)出現提示。
註:當彈出類似alert的強制回應對話方塊的時候,是不計時。
在Web開發的時候,經常會遇到的一種情況就是瀏覽器提示指令碼已耗用時間過長,停止還是繼續,無論你選擇什麼,相信你都會想盡一切辦法讓這個對話方塊遠離你的使用者們。可你是否知道,這些不同的瀏覽器究竟是如何判斷,哪些指令碼處於“失控”狀態嗎?本文作者,就從Internet Explorer、Firefox、Safari、Chrome和Opera五種瀏覽器,分析了這個情況出現的原因。
【原文標題】What determines that a script is long-running?
【原文作者】Nicholas C. Zakas
以下是對原文的翻譯:
Web開發人員經常遇到並必須及時處理的問題就是“提示指令碼已耗用時間過長的提示框”(或者稱為“失控指令碼提示”),這些令人討厭的對話方塊會在你的指令碼 執行時間過長的時候出現。對於Web開發人員的基本準則就是,無論什麼時候,都不要讓使用者看到這些對話方塊,因為這會給人一種代碼缺乏結構化的印象,更簡單的 說,你的代碼負擔太重了。
用Brendan Eich(JavaScript的發明人)的話來講,如果JavaScript啟動並執行時間需要用秒來計算,一定是什麼地方搞錯了。我個人可以忍受的上限可 能更小一些,不論什麼指令碼,在任何時間、任何瀏覽器上執行,都不應該超過100毫秒。如果實際執行的時間長於這個底限,一定要將進程分解成若干更小的代碼 段。
另外,其實很少有人真正意識到究竟是什麼原因導致指令碼在不同的瀏覽器中已耗用時間過長,連我自己都沒有深究過。所以我決定坐下來好好研究一下,我們究 竟會在什麼情況才會看到那個討厭的對話方塊。判斷指令碼是否失控,無外乎就兩種方法。一種是根據執行了多少條語句,一種是判斷指令碼執行花費的時間。各個瀏覽器 判斷指令碼失控的具體方法會有略微的不同。
Internet Explorer
Internet Explorer判斷一個指令碼是否失控,主要通過JScript引擎執行語句的總數來判斷。預設情況下,這個上限是500萬條語句,這個值是可以通過註冊表修改的。當你的指令碼執行的語句數量超過這個限制,你就會看到下面的視窗。
這個對話方塊提示:“這個頁面上有一段指令碼導致Internet Explorer運行緩慢,如果你繼續運行,你的電腦可能會變為無響應狀態”。要不是追求技術上的準確性,這樣說確實有點過了。對話方塊有兩個選項,要麼 停止指令碼執行,要麼允許指令碼繼續運行。當這個對話方塊顯示的時候,指令碼已經被完全停止了。如果你選擇繼續運行指令碼,就會重新計算當前執行的語句數,也就是 說,如果這個數值再次達到上限時,你會再次看到這個對話方塊。
Firefox
Firefox是根據指令碼引擎持續執行代碼的時間來判斷一段指令碼是否失控。預設的上限是10秒,可以通過about:config頁面來修改這個值。這裡需要注意的是,當彈出類似alert的強制回應對話方塊的時候,是不計時的。當瀏覽器執行指令碼的時間達到這個上限,Firefox就會顯示類似下面的對話方塊:
Firefox的對話方塊提示:“這個頁面的一段指令碼目前運行忙,或者這段指令碼已經停止回應。你可以停止執行這段指令碼,並在調試器中開啟這段指令碼,或 者保持這段指令碼繼續運行”。更清楚的描述了遇到的問題,並且沒有IE說的那麼恐怖。在這個對話方塊上可以執行三種操作:停止指令碼執行、調試指令碼或者讓指令碼繼 續運行。和Internet Explorer一樣,當運行指令碼繼續運行以後,對持續運行指令碼時間的統計就會重設。調試指令碼按鈕,只有在你安裝了Firebug,並在該頁面啟用了調試 的時候才會出現。執行調試指令碼操作後,可以顯示執行時間過長的程式碼片段的具體位置。
Safari
Safari同樣根據指令碼引擎持續執行指令碼的時間來判斷,當我對Webkit的原始碼進行反覆研究後,發現預設的逾時時間是5秒,一旦達到這個上限,就會給出下面的對話方塊提示:
對話方塊提示:“在頁面url上的指令碼讓Safari失去響應,你是要繼續運行指令碼還是終止指令碼”。同樣的,對於使用者來說,也不是什麼可怕的提示。在Safari中,可以關閉失控指令碼的檢測功能。
Chrome
Chrome在跟蹤技術上有點狡猾,失控指令碼檢測功能似乎和tab的事故控制(crash control)關聯到一起。我仔細看了原始碼,卻沒有找到具體的限制,但基本確定的是,這個限制是以時間為基礎的,估計在10秒左右(要麼是5秒,要麼 是10秒,總要和Safari或者Firefox看齊麼)。我正在聯絡Chrome項目組中的朋友,看看能不能得到確定的資訊。儘管如此,如果網頁中存在 失控的指令碼,使用者還是會看到下面的對話方塊:
毫無疑問,Chrome的提示比起其他瀏覽器來說,顯得都更加嚴重。點擊“Wait”按鈕,指令碼會繼續運行,直到達到下一個上限為止,也可以點擊“Kill pages”,直接關閉該頁面在記憶體中的所有資訊,並用一個空白頁取而代之。
Opera
Opera的情況比較有趣:他貌似沒有針對失控指令碼的相應限制。我運行了幾個很長的測試,甚至花了幾分鐘,而在這個過程中,瀏覽器一直可以正常響應,這很出我的意料之外。我不是很確定,對於現在的情況來說,這個方法是好是壞,但至少它生效了,不是嗎?
一些建議
無論你的使用者使用什麼瀏覽器,都不應該在任何時候看到類似的提示。在你的網站或者Web應用程式作為產品發布之前,做一些常規的效能測試是非常有必要的。在這方面有很多工具可以加以利用,比如Firebug's profiler(只支援Firefox)、YUI Profiler (支援全部瀏覽器)或者Internet Explorer 8's Profiler。 你應該毫不猶豫地將那些執行時間超過100毫秒的指令碼找出來,哪怕這些指令碼只是在某些瀏覽器上運行不暢,這些指令碼包含了一些需要執行很長時間的程式碼片段,而 這些代碼應該通過效能偵查工具進行重新評估。確保你不是使用Chrome作為測試的底線,因為Chrome在執行JavaScript的速度上比其他瀏覽 器要高出一個數量級(和Firefox 3.1還有最新的WebKit Nightly相當)。最好使用Internet Explorer作為測試的底線,然後再測試其他瀏覽器,因為無論什麼時候,IE的JavaScript引擎都是最慢的,當在IE上修複問題以後,十有八 九在其他瀏覽器上也可以正常運行了。