【JavaScript性能優化】------理解Script標簽的加載和執行


1.script標簽是如何加載的?
當瀏覽器遇到一個 < script>標簽時,瀏覽器會停下來,運行JavaScript代碼,然后再繼續解析、翻譯頁面。同樣的事情發生在使用 src 屬性加載 JavaScript 的過程中。瀏覽器必須首先下載外部文件的代碼,需要占用一些時間,然后解析並運行此JavaScript代碼。此過程中,頁面解析和用戶交互是被完全阻塞的。
2.script標簽該放在何處?
HTML 4 文檔指出,一個< script>標簽可以放在 HTML 文檔的或標簽中,可以在其中多次出現。

 

 這些代碼存在性能問題:在< head>部分加載了三個 JavaScript 文件。因為每個< script>標簽阻塞了頁面的解析過程,直到它完整地下載並運行了外部 JavaScript 代碼之后,頁面 處理才能繼續進行。用戶必須忍受這種可以察覺的延遲。瀏覽器在遇到< body>標簽之前,不會渲染頁面的任何部分。用這種方法把腳本放在頁面的頂端,將導致一個可以察覺的延遲,通常表現為:頁面打開時,首先顯示為一幅空白的頁面,而此時用戶即不能閱讀,也不能與頁面進行交互操作。

可以用一張圖片來表示這些資源的加載過程,紅色箭頭表示js代碼執行所用的時間

 

 

 

可以看到,第一個 JavaScript 文件開始下載,並阻塞了其他文件的下載過程。在 file1.js 下載完之后和 file2.js 開始下載之前有一個延時,這是 file1.js 完全運行所需的時間。每個文件必須等待前一個文件下載完成並運行完之后,才能開始自己的下載過程。當這些文件下載時,用戶面
對一個空白的屏幕。
不過隨着瀏覽器的發展,Internet Explorer 8, Firefox 3.5, Safari 4, 和 Chrome 2 允許並行下載 JavaScript 文件。這表明,當一個< script>標簽正在下載外部資源時,不必阻塞其他< script>標簽。不幸的是,JavaScript 的下載仍然要阻塞其他資源的下載過程,例如圖片。即使腳本之間的下載過程互不阻塞,頁面仍舊要等待所有 JavaScript代碼下載並執行完成之后才能繼續。所以,當瀏覽器通過允許並行下載提高性能之后,該問題並沒有完全解決。腳本阻塞仍舊是一個問題。
因為腳本阻塞其他頁面資源的下載過程,所以推薦的辦法是:將所有< script>標簽放在盡可能接近< body>標簽底部的位置,盡量減少對整個頁面下載的影響。
3.減少外部JavaScript文件的數量
由於每個 HTTP 請求都會產生額外的性能負擔,下載一個 100KB 的文件比下載四個 25KB 的文件要快。當一個大型網站或網頁應用需要多次請求 JavaScript 文件。可以將這些文件整合成一個文件,只需要一個< script>標簽引用,就可以減少性能損失。
4.采用非阻塞腳本
保持 JavaScript 文件短小,並限制 HTTP 請求的數量,只是創建反應迅速的網頁應用的第一步。一個應用程序所包含的功能越多,所需要的 JavaScript 代碼就越大。盡管下載一個大 JavaScript 文件只產生一次 HTTP 請求,卻會鎖定瀏覽器一大段時間。為避開這種情況,需要向頁面中逐步添加 JavaScript,某種程度上說不會阻塞瀏覽器。
非阻塞腳本的秘密在於,等頁面完成加載之后,再加載 JavaScript 源碼。這意味着在window 的 load 事件發出之后開始下載代碼。有幾種方法可以實現這種效果。
1. 使用defer(延時腳本)和async(異步腳本)

 

 

defer 屬性指明元素中所包含的腳本不打算修改 DOM,因此代碼可以稍后執行。注意:defer屬性只對外部腳本有用
一個帶有 defer 屬性的< script>標簽可以放置在文檔的任何位置。對應的 JavaScript 文件將在< script>被解析時啟動下載,但代碼不會被執行,直到 DOM 加載完成。當一個 defer的 JavaScript 文件被下載時,它不會阻塞瀏覽器的其他處理過程,所以這些文件可以與頁面的其他資源一起並行下載。

 

 

async用於異步加載腳本,與defer的區別是:async加載完成后自動執行,defer需要等到頁面完成后(window.onload)才執行, 注意:多個標記為 async 的腳本並不保證按照指定它們的先后順序執行(有可能是file3.js, file2.js, file4.js,取決於誰先返回),以為他們是異步加載的
2. 使用動態腳本元素
< script>元素與頁面其他元素沒有什么不同,所以他可以從文檔中移動、刪除,也可以被創建。一個新的< script>元素可以非常容易地通過標准 DOM 函數創建:

 

 


新的< script>元素加載 file1.js 源文件。此文件當元素添加到頁面之后立刻開始下載。此技術的重點在於:無論在何處啟動下載,文件的下載和運行都不會阻塞其他頁面處理過程。甚至可以將這些代碼放在< head>部分而不會對其余部分的頁面代碼造成影響。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM