家好,我是前端西瓜哥。今天我們來了解一下 script 腳本的三種加載方式。
一般的 script 寫法為:
<script src="app.js"></script>
這種寫法有一個問題:它會 阻塞 HTML 的 DOM 構建。
假如我們在 head 元素中使用了 script 腳本,它就會阻止后面元素的渲染,包括 body 元素,此時執行document.querySeletor('body') 拿到的是 null。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
// 拿到 null
console.log(document.querySeletor('body'));
</script>
</head>
<body></body>
</html>
此外,當腳本足夠大,加載執行足夠久時,會導致頁面長時間沒能渲染出完整頁面。
這也是我們將業務代碼腳本放到 body 最下邊的原因,這樣能確保腳本能夠訪問一個完整的 DOM 樹,也不會阻止頁面的渲染。
缺點是,HTML 很長的時候,解析到腳本就會花上一點時間,然后才會請求對應的腳本資源。
不過通常來說,HTML 內容都比較簡單,二者感受不到太大區別,除非你網很卡。
<script defer src="app.js"></script>
defer,“延遲” 之意。這里的延遲,指的是延遲執行腳本,下載則不會被阻塞。
需要注意的是, defer 屬性對內嵌腳本無效。畢竟腳本內容就在 HTML 里了,完全不需要請求資源了好吧。
給 script 標簽添加了 defer 屬性后,腳本不會阻塞 DOM 樹的構建,會先下載資源,然后等待到在 DOMContentLoaded 事件前執行。
DOMContentLoaded 事件的觸發時機為初始 HTML 被構建完成時,此時 CSS、圖片等資源不需要加載完,但我們的腳本要執行完。
如果多個 script 設置了 defer 屬性,這幾個 script 的執行順序和聲明順序相同,即最前面的腳本先執行。并不是誰先下載誰先執行。
實際開發中,我們可以將業務代碼腳本加上 defer 屬性,放到更上層的 head 標簽下。
這也是最新版 HtmlWebpackPlugin 插件的默認引入打包腳本的方式。
<script async src="app.js"></script>
async,“異步” 之意。同樣對內嵌腳本無效。
設置 async 后,腳本一旦被下載好了就會執行,不管什么時機。
適合與執行順序無關的腳本,比如廣告、網站流量分析腳本。
比如插入 Google 分析腳本:
<script async src="//www.google-analytics.com/analytics.js"></script>
還有一種用腳本加載腳本的特殊情況,這里也說一說。
<script>
const script=document.createElement('script');
script.src='app-a.js';
document.body.appendChild(script);
</script>
腳本里創建一個 script 元素,設置好 src,然后加載到 DOM 樹上,接著腳本就會下載和執行了。
創建的 script 元素默認會給 async 設置為 true,即一旦下載好就立即執行。
如果你要加載有依賴關系的多個腳本,就需要將 async 設置為 false。
<script>
const script=document.createElement('script');
// 取消 async 加載方式
script.async=false;
script.src='app-a.js';
document.body.appendChild(script);
const script2=document.createElement('script');
script2.async=false;
script2.src='app-b.js';
document.body.appendChild(script2);
</script>
<script>console.log('我還是所有腳本中最先執行的')</script>
這樣寫,就能保證先執行 app-a.js,再執行 app-b.js
但 它無法做到比 HTML 中其他非動態加載的 script 腳本更早執行,這點需要注意。
script 有三種常見加載模式:
此外還有動態加載的腳本的情況,這種腳本默認為 async 加載形式,可通過將 async 屬性設置為 false 來解除,讓腳本順序執行。
我是前端西瓜哥,歡迎關注我。
前端開發中,我們經常需要知道網頁的DOM(文檔對象模型)是否已經加載完畢。對于初學者來說,這可能聽起來有些復雜,但其實我們可以通過簡單的JavaScript代碼來實現這一目標,而不需要依賴任何框架或庫。本文將帶你一步步了解如何實現這一點。
在講具體方法之前,我們先來了解一下什么是DOM。DOM(文檔對象模型)是網頁的結構化表示,它將HTML文檔表示為一個樹形結構。瀏覽器會解析HTML并生成DOM樹,我們可以使用JavaScript對這個DOM樹進行操作,從而改變網頁的內容和樣式。
要檢查DOM是否準備好,我們主要使用兩個事件:DOMContentLoaded和load。它們的區別在于:
我們可以使用這兩個事件來確定頁面的加載狀態,并結合document.readyState屬性來判斷DOM是否已準備好。
下面是具體的代碼示例:
window.addEventListener("DOMContentLoaded", ()=> {
if (document.readyState==="complete") {
console.log('DOM已完全加載');
} else if (document.readyState==="interactive") {
console.log('DOM已準備好,但資源仍在加載');
}
});
window.addEventListener("load", ()=> {
if (document.readyState==="complete") {
console.log('所有資源已加載完成');
} else if (document.readyState==="interactive") {
console.log('DOM已準備好,但資源仍在加載');
}
});
在這段代碼中,我們使用了window.addEventListener來監聽DOMContentLoaded和load事件。當這些事件觸發時,會執行相應的回調函數。在回調函數中,我們檢查document.readyState屬性的值:
了解DOM的加載狀態對于前端開發非常重要。例如,如果你想在DOM完全加載后執行一些初始化操作,就需要確保這些操作不會在DOM未準備好的情況下執行。通過監聽這些事件,你可以確保在合適的時機執行相應的代碼,提高代碼的穩定性和性能。
在不使用任何JavaScript框架或庫的情況下,我們可以通過監聽DOMContentLoaded和load事件,以及檢查document.readyState屬性的值,來確定DOM是否已準備好。這種方法簡單高效,非常適合初學者學習和使用。
題:構建卓越的用戶體驗:Vue 3中的全面首屏加載優化策略
在當今Web應用的競爭激烈的環境下,首屏加載速度成為吸引用戶和提升用戶滿意度的關鍵。Vue 3作為一款現代化的前端框架,提供了多種全面的首屏加載優化策略,以確保您的應用快速響應、高效加載。本文將詳細探討Vue 3中的全面首屏加載優化策略,從不同角度為您展示如何提升用戶體驗和性能。
1. 異步組件與路由懶加載
按需加載:
*請認真填寫需求信息,我們會在24小時內與您取得聯系。