JS的載入和執行

來源:互聯網
上載者:User

標籤:body   安全   總結   內容   指令碼   多個   支援   alt   說話   

從JS的載入和執行談效能最佳化

---高效能JS讀後感(第一章)

從指令碼的"霸道"說起,隨著瀏覽器的進步,js越來越聽話了,所以,我們先說說以前的瀏覽器是怎麼載入js的,以及js如何個霸道法.

1.阻塞的指令碼

在以前,js很霸道.

問:當我們在網頁中使用<script></script>時,到底發生了什麼?

答:無論是內嵌的<script>標籤代碼還是用<script>引入檔案,當瀏覽器解析到<script>元素時,瀏覽器就會去載入js內容,這時,頁面的其他資源的載入和渲染都會停止,可以說<script>元素是老大,當他說話(載入)時,其他人都不敢說(其他資源都會停止載入和渲染),這就是我們常說的js會阻塞資源載入和頁面渲染.這是<script>的霸道(特點).單載入就阻塞了,執行就更不用說了.

所以,我們一般把js放在頁面的底部,</body>之前,這樣當頁面載入到底部的js時,頁面的結構和渲染都完成了,這個時候你阻塞也不影響我頁面的載入.

後來瀏覽器開始進步

當瀏覽器解析到<script>元素時,依舊會阻塞頁面其他資源的載入(比片)和渲染(css的渲染),但是如果頁面有多個<script>,就是說如果我們引入兩份js檔案,那麼這兩份js檔案是可以並行載入的,不用像之前一樣,得第一份載入完再去載入第二份.

瀏覽器繼續進步

2.無阻塞的指令碼

無阻塞指令碼的秘訣在於,在頁面載入完成後才載入js代碼.就是說在window對象的load事件觸發後再下載指令碼.

無阻塞指令碼之延遲的指令碼(這裡的延遲指的是順延強制,而不是消極式載入)

在現在的主流瀏覽器,js的載入已經不會阻塞頁面了,他能夠與其他資源和平共處,就是說他越來越乖巧了,當他在載入時,他允許圖片等其他資源的載入,當然執行的話還是會阻塞的.

如,js與圖片並行載入.(主流瀏覽器)

js的載入說完了,我們說說js的執行.

問:js執行為什麼會阻塞頁面的渲染.

答:js在執行時,一般都會操作DOM,操作DOM就會影響到DOM樹的渲染,所以js的執行肯定會阻塞渲染.

注意:js是單線程,但瀏覽器是多線程,js在執行時,DOM樹在構建,同時渲染樹也在渲染,這個時候如果js構建和瀏覽器即將渲染的是同一個節點怎麼辦?所以,為免衝突,js在執行時,停止渲染.

現在js的載入和執行略懂略懂,那麼問題來了.

問:js放置的最優位置的底部,我現在有一份js必須在head,等頁面結構載入完(window.onload)就馬上執行,就是說我要先載入後執行,那麼我該怎麼辦?

答:用defer,在<script>加上defer屬性

<script type="text/javascript" src="jquery-1.8.3.min.js" defer></script>

defer的功能:指明本元素所含的指令碼不會修改DOM,(即只載入不執行),因此代碼能安全的順延強制.阻塞的指令碼變成延遲的指令碼了.

問:我現在有一份js必須在head,想讓它載入完馬上執行怎麼辦?

答:用async,在<script>加上async屬性

<script type="text/javascript" src="jquery-1.8.3.min.js" async></script>

async的功能:非同步並行載入js,載入完之後立即執行.defer是載入後等頁面載入後再執行,兩者的區別是執行方式的不同.

問:我們什麼時候用defer,什麼時候用async?

答:

1.當js並不需要立馬載入的時候,我們把js放在頁面底部就可以了,不需要用到這兩個屬性.

2.當某段js需要立馬載入時,判斷其是否需要立即執行,需要就用async,不需要立即執行就用defer.

當然,這裡需要強調下,js立即執行,這個時候是會阻塞頁面的渲染的.

也需要考慮到,這兩個屬性的瀏覽器支援情況,在不支援這兩個屬性的瀏覽器上,其實他們是會阻塞頁面的渲染的(不支援的情況下,載入js不阻塞,但是載入完後的js會去立馬執行,這個時候就會阻塞了).

3.DOM樹建立完並不意味著頁面資源載入完,所以在DOM樹建立完,觸發window.onload的時候,中間還是有一點時間的,這個時間就是載入其他資源的時間.(比如說載入js)

4.其實,在不考慮多個js檔案有多個http請求數的情況下,當你把js放在頁面底部的時候,其實已經是一種無阻塞的指令碼了.

總結:(摘自書中內容)

減少js對效能的影響:

1.</body>閉合標籤之前,將所有的<script>標籤放到頁面底部.這能確保在指令碼執行前頁面已經完成了渲染.

2.合并指令碼.頁面的中的<script>標籤越少,載入也就越快,響應也更迅速.無論外鏈檔案還是內嵌指令碼都是如此.

3.有多種無阻塞下載js的方法:(可自行搜尋用法)

  • 使用<script>標籤的defer屬性
  • 使用動態建立的<script>元素來下載並執行代碼
  • 使用XHR對象下載js代碼並注入頁面中

個人覺得,在目前,js模組載入器,js模組打包器都有,解決檔案的依賴關係並且打成一個包是比較容易的,再把打成的包放到</body>,可以減少http請求,也不會阻塞頁面載入和渲染(可以說這是一個無阻塞的指令碼),雖然這個檔案可能很大,但相對於減少了http請求數來說,還是利大於弊的,因為我們一個頁面不打包可能有很多個js,這樣請求數會很多.

當然對於一些庫,我們可以單獨引入,這樣可以緩衝起來,緩衝起來的檔案載入就更快了.

有錯請指出,歡迎交流~

JS的載入和執行

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.