JavaScript 在瀏覽器中的性能,可認(rèn)為是開發(fā)者所要面對(duì)的最重要的可用性問題。此問題因JavaScript的阻塞特征而復(fù)雜,也就是說,當(dāng)JavaScript 運(yùn)行時(shí)其他的事情不能被瀏覽器處理。事實(shí)上,大多數(shù)瀏覽器使用單進(jìn)程處理UI 更新和JavaScript 運(yùn)行等多個(gè)任務(wù),而同一時(shí)間只能有一個(gè)任務(wù)被執(zhí)行。
JavaScript運(yùn)行了多長時(shí)間,那么在瀏覽器空閑下來響應(yīng)用戶輸入之前的等待時(shí)間就有多長。
從基本層面說,這意味著<script>標(biāo)簽的出現(xiàn)使整個(gè)頁面因腳本解析、運(yùn)行而出現(xiàn)等待。不論實(shí)際的JavaScript 代碼是內(nèi)聯(lián)的還是包含在一個(gè)不相干的外部文件中,頁面下載和解析過程必須停下,等待腳本完成這些處理,然后才能繼續(xù)。這是頁面生命周期必不可少的部分,因?yàn)槟_本可能在運(yùn)行過程中修改頁面內(nèi)容。
典型的例子是document.write()函數(shù),例如:
<html><head><title>Script Example</title></head><body><p><script type=”text/javascript”>document.write(“The date is ” + (new Date()).toDateString());</script></p></body></html>
當(dāng)瀏覽器遇到一個(gè)<script>標(biāo)簽時(shí),正如上面HTML 頁面中那樣,無法預(yù)知JavaScript 是否在<p>標(biāo)簽中添加內(nèi)容。因此,瀏覽器停下來,運(yùn)行此JavaScript 代碼,然后再繼續(xù)解析、翻譯頁面。同樣的事情發(fā)生在使用src 屬性加載JavaScript 的過程中。瀏覽器必須首先下載外部文件的代碼,這要占用一些時(shí)間,然后解析并運(yùn)行此代碼。此過程中,頁面解析和用戶交互是被完全阻塞的。
HTML 4 文檔指出,一個(gè)<script>標(biāo)簽可以放在HTML 文檔的<head>或<body>標(biāo)簽中,可以在其中多次出現(xiàn)。傳統(tǒng)上,<script>標(biāo)簽用于加載外部JavaScript 文件。<head>部分除此類代碼外,還包含<link>標(biāo)簽用于加載外部CSS 文件和其他頁面中間件。也就是說,最好把風(fēng)格和行為所依賴的部分放在一起,首先加載他們,使得頁面可以得到正確的外觀和行為。例如: