瀏覽器的事件循環機制

瀏覽器內核的線程

  1. GUI渲染線程:
    • 負責頁面渲染,解析HTML,CSS構成DOM樹等,
    • 當頁面重繪(Repaint)或者由於某種操作引起迴流(reflow)都會調起該線程
    • GUI渲染線程和js引擎線程互斥,當JS引擎線程在工作的時候,GUI渲染線程會被掛起,GUI更新被放入在JS任務隊列中,等待JS引擎線程空閒時立即被執行。
  2. JS引擎線程
    • 也成爲JS內核,負責處理Javascript腳本程序。(例如v8引擎)
    • JS引擎線程負責解析Javascript腳本,運行代碼。
    • JS引擎一直等待着任務隊列中任務的到來,然後加以處理,一個Tab頁(renderer進行)中無論什麼時候都只有一個JS線程在運行JS程序。
    • GUI渲染線程與JS引擎線程是互斥的,所以如果JS執行的時間過長,這樣就會造成頁面的渲染不連貫,導出頁面渲染加載阻塞。
  3. 事件觸發線程
    • 當事件符合觸發條件被觸發時,該線程會把對應的事件回調函數添加到任務隊列的隊尾,等待 JS 引擎處理。
    • 歸屬於瀏覽器而不是JS引擎,用來控制事件循環。
    • 當JS引擎執行代碼塊如setTimeOut時(也可來自瀏覽器內核的其他線程,如鼠標點擊、AJAX異步請求等),會將對應任務添加到事件線程中
    • 當對應的時間符合觸發條件被觸發時,該線程會把事件添加到待處理隊列的隊尾,等待JS引擎的處理
    • 由於JS的單線程關係,這些待處理隊列中的事件都得排隊等待JS引擎處理(當JS引擎空閒時纔會去執行)
  4. 定時器觸發線程
    • 瀏覽器定時計數器並不是由Javas引擎計數的(因爲時單線程,會導致阻塞線程就會影響計時的準確)
    • 開啓定時器觸發線程時並觸發計時,計時完成後會被添加到任務隊列中,等待js引擎處理。
  5. 異步http請求線程
    • 在XMLHttpRequest連接後 在瀏覽器新開一個線程請求
    • 在檢測到狀態變更時,如果有設置回調函數,異步線程就**產生狀態變更事件*,將這個回調在放入事件隊列中,再由Javascript引擎執行。
      ![alt][]

Event Loop (事件循環機制)

  1. JS分爲同步任務和異步任務
  2. 同步任務都在主線程上執行,形成一個執行棧
  3. 除主線程之外,事件觸發線程管理着一個任務隊列,只要異步任務有了運行結果,就在任務隊列之中放置一個事件。
  4. 一旦執行棧中的所有同步任務執行完畢(此時JS引擎空閒),系統就會讀取任務隊列,將可運行的異步任務添加到可執行棧中,開始執行。

TODO:事件循環進階:macrotask(宏任務)與microtask(微任務)

參考文章:
https://www.cnblogs.com/cangqinglang/p/8963557.html
https://www.cnblogs.com/yqx0605xi/p/9267827.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章