一、在文檔的<head>元素中包含所有JavaScript文件
必須等到全部JavaScript代碼都被下載苦酱、解析和執(zhí)行完成之后给猾,才能開始呈現(xiàn)頁面的內容。這無疑會導致瀏覽器在呈現(xiàn)頁面時出現(xiàn)明顯的延遲敢伸,特別是比較龐大的腳本池颈,將會極大的影響用戶體驗。
為了避免這個問題躯砰,一般把全部JavaScript引用放在<body>元素后面。這樣在解析包含的JavaScript代碼之前脯爪,頁面的內容將完全呈現(xiàn)在瀏覽器中。
二尚揣、延遲腳本:設置defer屬性
腳本會延遲到整個頁面都解析完畢后再運行掖举, 相當于立即下載,但延遲執(zhí)行塔次。延遲腳本按照出現(xiàn)的先后順序執(zhí)行。
<script src="test.js" defer></script>
部分瀏覽器會忽略這個屬性藕溅,因此把延遲腳本放在底部仍然是最佳的選擇继榆。
三、異步腳本:設置async屬性
與defer類似集币,async只適用于外部腳本文件翠忠,并告訴瀏覽器立即下載文件。但與defer不同的是偶妖,標記為async的腳本并不保證按照指定它們的先后順序執(zhí)行政溃。
如果不考慮低版本的IE瀏覽器:
使用async屬性即可實現(xiàn)異步加載态秧,即便將加載js的代碼放置于<head>中也沒有影響。
<script src="test.js" async></script>
如果要兼容所有瀏覽器:
如果要兼容老舊的瀏覽器愤诱,實踐表明可使用用來動態(tài)注入腳本的腳本加載器捐友。
比如可以使用require.js等實現(xiàn)異步加載。
還有一種方法科吭,就是將引入js的代碼放置于body底部,并帶上async屬性谣殊。這雖然在老舊瀏覽器中不會異步加載腳本牺弄,但它只阻塞了body結束標簽之前的DOM解析,這就大大降低了其阻塞影響势告。而在現(xiàn)代瀏覽器中咱台,腳本將在DOM解析器發(fā)現(xiàn)body尾部的script標簽才進行加載,此時加載屬于異步加載吵护,不會阻塞CSSOM(但其執(zhí)行仍發(fā)生在CSSOM之后)。