JavaScript優(yōu)化專題之Loading and Execution加載和運(yùn)行
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)行了多長(zhǎng)時(shí)間,那么在瀏覽器空閑下來響應(yīng)用戶輸入之前的等待時(shí)間就有多長(zhǎng)。
從基本層面說,這意味著<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)格和行為所依賴的部分放在一起,首先加載他們,使得頁面可以得到正確的外觀和行為。例如:
<html> <head> <title>Script Example</title> <– Example of inefficient script positioning –> <script type=”text/javascript” src=”file1.js”></script> <script type=”text/javascript” src=”file2.js”></script> <script type=”text/javascript” src=”file3.js”></script> <link rel=”stylesheet” type=”text/css” href=”styles.css”> </head> <body> <p>Hello world!</p> </body> </html>
雖然這些代碼看起來是無害的,但它們確實(shí)存在性能問題:在<head>部分加載了三個(gè)JavaScript 文件。因?yàn)槊總€(gè)<script>標(biāo)簽阻塞了頁面的解析過程,直到它完整地下載并運(yùn)行了外部JavaScript 代碼之后,頁面處理才能繼續(xù)進(jìn)行。用戶必須忍受這種可以察覺的延遲。
請(qǐng)記住,瀏覽器在遇到<body>標(biāo)簽之前,不會(huì)渲染頁面的任何部分。用這種方法把腳本放在頁面的頂端,將導(dǎo)致一個(gè)可以察覺的延遲,通常表現(xiàn)為:頁面打開時(shí),首先顯示為一幅空白的頁面,而此時(shí)用戶即不能閱讀,也不能與頁面進(jìn)行交互操作
Internet Explorer 8, Firefox 3.5, Safari 4, 和Chrome 2 允許并行下載JavaScript 文件。這個(gè)好消息表明,當(dāng)一個(gè)<script>標(biāo)簽正在下載外部資源時(shí),不必阻塞其他<script>標(biāo)簽。不幸的是,JavaScript 的下載仍然要阻塞其他資源的下載過程,即使腳本之間的下載過程互不阻塞,頁面仍舊要等待所有JavaScript代碼下載并執(zhí)行完成之后才能繼續(xù)。所以,當(dāng)瀏覽器通過允許并行下載提高性能之后,該問題并沒有完全解決,腳本阻塞仍舊是一個(gè)問題。
因?yàn)槟_本阻塞其他頁面資源的下載過程,所以推薦的辦法是:將所有<script>標(biāo)簽放在盡可能接近<body>標(biāo)簽底部的位置,盡量減少對(duì)整個(gè)頁面下載的影響。例如:
<html> <head> <title>Script Example</title> <link rel=”stylesheet” type=”text/css” href=”styles.css”> </head> <body> <p>Hello world!</p> <– Example of recommended script positioning –> <script type=”text/javascript” src=”file1.js”></script> <script type=”text/javascript” src=”file2.js”></script> <script type=”text/javascript” src=”file3.js”></script> </body> </html>
此代碼展示了所推薦的<script>標(biāo)簽在HTML 文件中的位置。盡管腳本下載之間互相阻塞,但頁面已經(jīng)下載完成并且顯示在用戶面前了,進(jìn)入頁面的速度不會(huì)顯得太慢。
以上就是關(guān)于javascript優(yōu)化內(nèi)容中的Loading and Execution加載和運(yùn)行的相關(guān)介紹,希望對(duì)大家的學(xué)習(xí)有所幫助。
相關(guān)文章
深入學(xué)習(xí)JavaScript ES8中的函數(shù)式編程
函數(shù)式編程已經(jīng)成為現(xiàn)代JavaScript開發(fā)中的一種主要范式,它提供了一種更清晰、更模塊化、更可維護(hù)的代碼編寫方式,本文將深入探討ES8中的一些關(guān)鍵特性,并演示如何使用這些特性進(jìn)行函數(shù)式編程實(shí)踐,有需要的可以參考下2023-09-09
原生js實(shí)現(xiàn)Flappy Bird小游戲
這篇文章主要為大家詳細(xì)介紹了原生js實(shí)現(xiàn)Flappy Bird小游戲,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12
原創(chuàng)javascript小游戲?qū)崿F(xiàn)代碼
javascript小游戲?qū)崿F(xiàn)代碼,喜歡用javascript實(shí)現(xiàn)游戲效果代碼的朋友可以參考下。2010-08-08
JavaScript設(shè)計(jì)模式之單例模式原理與用法實(shí)例分析
這篇文章主要介紹了JavaScript設(shè)計(jì)模式之單例模式原理與用法,結(jié)合實(shí)例形式分析了單例模式的原理、命名空間的使用、閉包、惰性單例形式以及單例模式的基本應(yīng)用,需要的朋友可以參考下2018-07-07
JavaScript?Array.from及其相關(guān)用法詳解(示例演示)
Array.from方法是ES6引入的一個(gè)靜態(tài)方法,用于從類數(shù)組對(duì)象或可迭代對(duì)象創(chuàng)建一個(gè)新的數(shù)組實(shí)例,本文將詳細(xì)介紹Array.from的基本用法、實(shí)際場(chǎng)景中的應(yīng)用,以及它如何與其他JavaScript特性相結(jié)合提升代碼的簡(jiǎn)潔性和可讀性,感興趣的朋友一起看看吧2025-03-03

