JS延遲載入的方式有很多種,它們的目的都是為了最佳化網頁效能,減少初始載入時間,提升使用者體驗。以下是幾種常見的方式:
1. <script>
標籤的 defer
屬性:
- 告訴瀏覽器立即下載指令碼,但在文件解析完成後、DOMContentLoaded事件觸發之前執行。
- 多個帶有
defer
屬性的指令碼會按照它們在 HTML 中出現的順序執行。 - 適用於不依賴 DOMContentLoaded 事件觸發的指令碼,例如分析指令碼或其他初始化指令碼。
<script src="script.js" defer></script>
2. <script>
標籤的 async
屬性:
- 告訴瀏覽器立即下載指令碼,並在下載完成後儘快執行。
async
指令碼的執行不會阻塞文件解析,但它可能會在 DOMContentLoaded 事件觸發之前或之後執行,執行順序也不保證與它們在 HTML 中出現的順序一致。- 適用於獨立的指令碼,例如廣告指令碼或不依賴其他指令碼的第三方庫。
<script src="script.js" async></script>
3. 動態建立 <script>
標籤:
- 透過 JavaScript 動態建立
<script>
元素並將其新增到文件中。 - 可以完全控制指令碼的下載和執行時機。
- 適用於按需載入指令碼,例如使用者互動後才需要載入的模組。
function loadScript(src) {
const script = document.createElement('script');
script.src = src;
script.onload = () => {
// 指令碼載入完成後的回撥函式
console.log(src + ' loaded');
};
document.head.appendChild(script);
}
// 例如,在某個按鈕點選事件中載入指令碼
const button = document.getElementById('myButton');
button.addEventListener('click', () => {
loadScript('myScript.js');
});
4. 使用 import()
動態匯入 (ES Modules):
- 允許在需要時非同步載入模組。
- 支援更細粒度的程式碼拆分和按需載入。
button.addEventListener('click', async () => {
const { myFunction } = await import('./myModule.js');
myFunction();
});
5. 使用延遲載入庫:
- 一些庫,例如
lozad.js
,可以幫助你輕鬆實現圖片、iframe 和其他資源的延遲載入。 - 它們通常使用 Intersection Observer API 來檢測元素是否進入視口,並在需要時載入資源。
選擇哪種方法取決於你的具體需求:
- 對於不依賴 DOM 的指令碼,
defer
是一個不錯的選擇。 - 對於獨立的指令碼,
async
可以提高頁面載入速度。 - 對於按需載入的指令碼,動態建立
<script>
標籤或使用import()
是更靈活的選擇。 - 對於圖片和其他資源的延遲載入,可以使用專門的延遲載入庫。
總結: 以上這些方法可以幫助你最佳化網站效能,減少頁面載入時間,並提供更好的使用者體驗。 選擇最適合你的方法取決於你的具體需求和專案的複雜性。 記住測試和分析你的網站效能,以確保你選擇的延遲載入策略有效。