js的非同步載入你真的懂嗎

来源:https://www.cnblogs.com/LHLVS/archive/2019/04/11/10691232.html
-Advertisement-
Play Games

面試高頻之js的非同步載入 講這個問題之前, 我們從另一個面試高頻問題來切入, 我們的web頁面從開始解析到頁面渲染完成都經歷了什麼 ? 1 , 創建document對象, 開始解析頁面, 此時document.readyState = 'loading' 2 , 遇到link標簽引入的css文件, ...


面試高頻之js的非同步載入

講這個問題之前, 我們從另一個面試高頻問題來切入,

我們的web頁面從開始解析到頁面渲染完成都經歷了什麼 ? 

 

1  ,  創建document對象, 開始解析頁面,    此時document.readyState = 'loading'

 

2 ,     遇到link標簽引入的css文件, 創建線程並非同步載入css,繼續解析文檔

 

3,    遇到script標簽引入的外部腳本 ,  如果script標簽的屬性設置了defer或者async  則  創建線程非同步載入js , 否則同步載入js(阻塞了dom的解析)  , 繼續解析文檔 (async腳本載入完就執行)

4 ,   遇到img等要載入資源的標簽, 正常解析dom 標簽  ,  非同步載入src ,    繼續解析文檔

5 ,    文檔解析完畢 ,  document.readyState = 'interactive' , 所有defer腳本按順序執行,並且document會觸發 DOMContentLoaded事件 , 標志著程式從同步腳本執行階段轉化成事件驅動階段

6 , 當所有async 腳本 載入並執行 完畢 , img 載入完畢  ,  document.readyState = 'complete' ,  window 觸發  load  事件  。

7      從此   以非同步響應的方式處理用戶輸入, 網路事件等 。。。。。。

 

ok , 光說沒用, 我們來看看真相是否只有一個。。。

 

document.onreadystatechange = () => {
    console.log(document.readyState)
};
document.addEventListener('DOMContentLoaded', () => {
    console.log('DOMContentLoaded')
});
window.onload = () => {
    console.log('load')
};

 註意一點, DOMContentLoaded 事件 只能用  addEventListener 來綁定

結果是這樣:

按順序列印出來了 。。。 

 

上文我們提到只有設置了defer /async 的 script 腳本 才能非同步載入  , 

註意defer 有些低版本瀏覽器不相容,

async是W3C的標準,但只能在引入外部js文件時使用,

當然,我們最常用的是把script標簽放在body 後面 ,這樣就不會阻塞dom解析

 

還有一種情況, 動態添加的script腳本也是非同步載入的, 基於此 我們來封裝一個 非同步載入script腳本的函數

function loadScript (url, callback) {  // 傳入url , 和要執行的回調函數
    const script = document.createElement('script');
    script.type = 'text/javascript';  // 創建一個script標簽
    if (script.readyState) {   // 做相容
        script.onreadystatechange = () => {  // readyState變化觸發
            if (script.readyState === 'complete' || script.readyState === 'loaded') { // 相容
                callback();  // 載入完執行回調
            }
        }
    } else {
        script.onload = () => {
            callback();  // 載入完執行回調
        }
    }
    script.src = url;
    document.head.appendChild(script);  // 插入head中
}

以上就是 js 非同步載入 的 全部內容了, 歡迎小伙伴們補充

 

 

 

 

    


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 公司的網頁代碼需要測試,因後端擋板工具問題只能在瀏覽器里進行。但是在瀏覽器里打開時比在客戶端打開時少了一些必要的參數(放在PJF里)。需要在初始化時放進去。不可能把所有頁面改一下吧。最後我發現所有頁面都載入了sealUtils.js工具函數。於是我寫了一個自執行函數在放在sealUtils.js前。 ...
  • fullpage 全屏插件 全屏滾動效果,原生js也很好實現,主要是用 mousewheel 滑鼠滾輪滾動事件, 來判斷上滾動還是下滾動,之後設置每次滾動的高度為屏幕的高度即可。但是,雖然效果簡單,但是相容性很差,要做很多相容處理及比較麻煩啦! fullPage.js 是一個基於 jQuery 的插 ...
  • 盒子模型 1. 盒子模型的概念 2. 高和寬的設置 3. 邊框的設置 4. 內邊距的設置 5. 外邊距的設置 6. 盒子的計算 7. 元素顯示的方式 盒子模型: border邊框,margin外邊距,padding內部距,content內容,width寬度。 高度: height: 長度值|百分比| ...
  • 使用插件 formidable > npm i formidable 後臺代碼 import formidable from 'formidable' 輸出結果: 圖片存儲地方: Node.js的Formidable模塊的使用 1) 創建Formidable.IncomingForm對象 var f ...
  • 這篇隨筆繼續來認識HTML標簽。這次隨筆主要是對<table>標簽的認識和最近我學習到的一些標簽來和大家分享。 一、<table>標簽 <table>標簽的作用主要是定義HTML表格,<table>內也分頭<thead>和主體<tbody>,而簡單的HTML表格由table元素以及一個或者多個tr, ...
  • import React, { Component } from 'react' import ReactDOM from 'react-dom' class App extends Component { constructor(props) { super(props); this.state ... ...
  • 示例代碼托管在: "http://www.github.com/dashnowords/blogs" 博客園地址: "《大史住在大前端》原創博文目錄" 華為雲社區地址: "【你要的前端打怪升級指南】" [TOC] 一. 任務說明 使用原生 繪製水球圖,這將是一個非常有意思的挑戰任務。水球圖是一種常見 ...
  • 本篇文檔主要是利用echarts實現可拖動節點的折現圖,在echarts中找到了一個demo,傳送門:https://echarts.baidu.com/examples/editor.html?c=line-draggable,但是不是用vue寫的,並且在改寫為vue組件的過程中遇到了很多問題,在 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...