日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

EventLoop = TaskQueue + RenderQueue,你看明白了嗎?

來源: 責編: 時間:2023-12-08 09:13:38 242觀看
導讀前言在最近的工作和學習中,有一個詞總是在眼前揮之不去--EventLoop。而在之前,其實我們講過相關的內容,Event Loop 可視化解析圖片上文我們從偏JS調用機制的角度分析了,調用棧(Call Stack)/宏任務隊列 (Task Queue)和微任

前言

在最近的工作和學習中,有一個詞總是在眼前揮之不去--EventLoop。而在之前,其實我們講過相關的內容,Event Loop 可視化解析uWX28資訊網——每日最新資訊28at.com

Event Loop圖片uWX28資訊網——每日最新資訊28at.com

上文我們從偏JS調用機制的角度分析了,調用棧(Call Stack)/宏任務隊列 (Task Queue)和微任務隊列 (Microtask Queue)他們之間的關系和他們是如何協同合作的。并且,舉了很多例子,用可視化的方式講解它們如何工作的。uWX28資訊網——每日最新資訊28at.com

而今天,我們從瀏覽器內部的實現細節來談談EventLoop是如何從接受任務到渲染出對應頁面的。uWX28資訊網——每日最新資訊28at.com

也就是下圖中所涉及到的各個重要節點。在閱讀完本文后,希望大家能對下面有一個清晰的認知。uWX28資訊網——每日最新資訊28at.com

圖片圖片uWX28資訊網——每日最新資訊28at.com

好了,天不早了,干點正事哇。uWX28資訊網——每日最新資訊28at.com

我們能所學到的知識點

  1. 前置知識點
  2. 事件循環(Event Loop)
  3. 任務隊列/微任務隊列/調用棧
  4. 在渲染隊列中執行的是什么?
  5. EventLoop模型

1. 前置知識點

「前置知識點」,只是做一個概念的介紹,不會做深度解釋。因為,這些概念在下面文章中會有出現,為了讓行文更加的順暢,所以將本該在文內的概念解釋放到前面來。「如果大家對這些概念熟悉,可以直接忽略」同時,由于閱讀我文章的群體有很多,所以有些知識點可能「我視之若珍寶,爾視只如草芥,棄之如敝履」。以下知識點,請「酌情使用」。uWX28資訊網——每日最新資訊28at.com

頁面刷新術語

我們在頁面是如何生成的(宏觀角度)一文中提到過這些指標,這里就拿來主義了。uWX28資訊網——每日最新資訊28at.com

  • 「屏幕刷新頻率」

一秒內屏幕刷新的次數(一秒內顯示了多少幀的圖像),單位 Hz(赫茲),如常見的 60 Hz。「刷新頻率取決于硬件的固定參數」(不會變的)。uWX28資訊網——每日最新資訊28at.com

  • 「逐行掃描」
  • 顯示器并不是一次性將畫面顯示到屏幕上,而是「從左到右邊,從上到下逐行掃描」,順序顯示整屏的一個個像素點,不過這一過程快到人眼無法察覺到變化。uWX28資訊網——每日最新資訊28at.com

  • 以 60 Hz 刷新率的屏幕為例,這一過程即 1000 / 60 ≈ 16ms。uWX28資訊網——每日最新資訊28at.com

  • 當掃描完一個屏幕后,設備需要「重新回到第一行」以進入下一次的循環,此時有一段時間空隙,稱為VerticalBlanking Interval(VBI)。uWX28資訊網——每日最新資訊28at.com

  • 「幀率 (Frame Rate)」uWX28資訊網——每日最新資訊28at.com

  • 表示 「GPU 在一秒內繪制操作的幀數」,如 60 fps,即每秒鐘GPU最多繪制 60 幀畫面。uWX28資訊網——每日最新資訊28at.com

  • 幀率是「動態變化」的,例如當畫面靜止時,GPU 是沒有繪制操作的,屏幕刷新的還是buffer中的數據,即GPU最后操作的幀數據。uWX28資訊網——每日最新資訊28at.com

  • 「畫面撕裂(tearing)」uWX28資訊網——每日最新資訊28at.com

  • 一個屏幕內的數據來自2個不同的幀,畫面會出現撕裂感。uWX28資訊網——每日最新資訊28at.com

測試幀率

我們可以借助requestAnimationFrame通過每個測量前后幀發生的時間間隔,來從側面查看本地瀏覽器幀率。uWX28資訊網——每日最新資訊28at.com

const checkRequestAnimationDiff = () => {    let prev;    function call() {        requestAnimationFrame((timestamp) => {            if (prev) {                console.log(timestamp - prev);                 // 應該大約是60FPS的16.6毫秒            }            prev = timestamp;            call();        });    }    call();}checkRequestAnimationDiff();

隨意打開一個網站,并將上述代碼貼到devtool-Console運行。uWX28資訊網——每日最新資訊28at.com

下面是,我們在React-官網[1]中實驗的結果。uWX28資訊網——每日最新資訊28at.com

圖片圖片uWX28資訊網——每日最新資訊28at.com

從輸出結果來看,雖然結果不是唯一,但是它們的值都穩定在16.67~16.68。和我們60fps是吻合的。uWX28資訊網——每日最新資訊28at.com

WebAPI

WebAPI工作的原理依賴于瀏覽器作為宿主環境來提供和執行這些API。在Web開發中,我們通常指的WebAPI是「瀏覽器內置的API」,它們允許開發者利用JavaScript與瀏覽器的功能進行交互。uWX28資訊網——每日最新資訊28at.com

APIsuWX28資訊網——每日最新資訊28at.com

描述uWX28資訊網——每日最新資訊28at.com

網絡請求uWX28資訊網——每日最新資訊28at.com

(Network Requests)uWX28資訊網——每日最新資訊28at.com

使用XMLHttpRequestfetch API,可以發起異步的HTTP請求到服務器,并在不刷新頁面的情況下獲取或發送數據。uWX28資訊網——每日最新資訊28at.com


uWX28資訊網——每日最新資訊28at.com

DOM操作uWX28資訊網——每日最新資訊28at.com

(DOM Manipulation)uWX28資訊網——每日最新資訊28at.com

瀏覽器提供了一套DOM API,允許JavaScript訪問和操作頁面上的元素。比如,可以添加、刪除或更改元素,或者修改元素的樣式和內容。uWX28資訊網——每日最新資訊28at.com

事件處理uWX28資訊網——每日最新資訊28at.com

(Event Handling)uWX28資訊網——每日最新資訊28at.com

WebAPI允許注冊事件處理程序來響應用戶行為(如點擊、滑動)或瀏覽器事件(如頁面加載、窗口尺寸變化)。uWX28資訊網——每日最新資訊28at.com

存儲機制uWX28資訊網——每日最新資訊28at.com

(Storage Mechanisms)uWX28資訊網——每日最新資訊28at.com

瀏覽器提供了如localStoragesessionStorageIndexedDB等API,可以在用戶的設備上存儲數據。uWX28資訊網——每日最新資訊28at.com

設備APIuWX28資訊網——每日最新資訊28at.com

(Device APIs)uWX28資訊網——每日最新資訊28at.com

可以訪問設備的硬件,如攝像頭、麥克風、地理位置等,這通常通過navigator對象暴露的API實現。uWX28資訊網——每日最新資訊28at.com

圖形和動畫uWX28資訊網——每日最新資訊28at.com

(Graphics & Animation)uWX28資訊網——每日最新資訊28at.com

CanvasWebGL API允許在網頁上繪制二維和三維圖形。requestAnimationFrame為動畫提供了一個優化的循環機制。uWX28資訊網——每日最新資訊28at.com

性能監控uWX28資訊網——每日最新資訊28at.com

(Performance Monitoring)uWX28資訊網——每日最新資訊28at.com

Performance API提供了獲取瀏覽器性能相關數據的接口,幫助開發者監控和優化網頁性能。uWX28資訊網——每日最新資訊28at.com

其他APIuWX28資訊網——每日最新資訊28at.com

(Other APIs)uWX28資訊網——每日最新資訊28at.com

還有諸如Web Audio APIWebRTCWebSocket等,使得在網頁上實現復雜的音頻處理、實時通信成為可能。uWX28資訊網——每日最新資訊28at.com

WebAPI的工作流程

  1. 「調用API」:開發者在JavaScript代碼中調用某個WebAPI。
  2. 「瀏覽器解釋執行」: 瀏覽器解釋JavaScript代碼,并「執行相應的API調用」。
  3. 「API內部處理」:WebAPI內部可能會執行多種操作,如觸發網絡請求、訪問數據庫、啟動硬件設備等。
  4. 「回調和事件循環」:對于異步操作,WebAPI通常會使用回調函數或Promise來處理操作完成后的結果。瀏覽器的事件循環機制確保了這些回調在適當的時候被調用。
  5. 「渲染和更新」:對于涉及視覺變化的API,如DOM操作或Canvas繪圖,瀏覽器會更新頁面內容,這通常發生在瀏覽器的下一個重繪周期。

在整個過程中,「瀏覽器的角色是中介」,它提供了執行API的環境和必要的安全措施。這些API讓Web應用可以像本地應用一樣豐富和強大,同時仍然運行在瀏覽器這個相對安全的沙箱環境中。uWX28資訊網——每日最新資訊28at.com

下面的圖,展示了WebAPI的地位(中間部分)。uWX28資訊網——每日最新資訊28at.com

圖片圖片uWX28資訊網——每日最新資訊28at.com

GPU硬件加速

「GPU(Graphics Processing Unit)硬件加速」是一種利用GPU來執行圖形和計算任務的技術。在Web開發中,GPU硬件加速可以通過利用用戶計算機中的GPU資源來加速瀏覽器的渲染和繪制操作。這通常可以提高網頁的性能和流暢度,尤其是對于需要大量圖形操作的頁面。uWX28資訊網——每日最新資訊28at.com

在Web開發中,一些CSS屬性和操作可以觸發GPU硬件加速,以便更有效地利用GPU資源。uWX28資訊網——每日最新資訊28at.com

  1. 3D 變換(transform)

使用transform屬性進行3D變換,如translate3d、rotate3d、scale3d等,可以觸發GPU硬件加速。例如:uWX28資訊網——每日最新資訊28at.com

.element {  transform: translate3d(0, 0, 0);}
  1. CSS 動畫(animation)和過渡(transition):
  • 使用CSS動畫和過渡屬性,例如transform屬性的過渡,可以觸發GPU硬件加速。例如:uWX28資訊網——每日最新資訊28at.com

    .element {  transition: transform 0.3s ease-in-out;}

    uWX28資訊網——每日最新資訊28at.com

  1. uWX28資訊網——每日最新資訊28at.com

    Canvas 繪圖:uWX28資訊網——每日最新資訊28at.com

    uWX28資訊網——每日最新資訊28at.com

  • 在<canvas>元素上進行繪圖操作通常會利用GPU硬件加速。這包括使用2D或WebGL上下文進行圖形渲染。uWX28資訊網——每日最新資訊28at.com

  1. uWX28資訊網——每日最新資訊28at.com

    使用 will-change 屬性:uWX28資訊網——每日最新資訊28at.com

    uWX28資訊網——每日最新資訊28at.com

  • will-change屬性告訴瀏覽器某個屬性將會被改變,從而可以提前進行優化。例如:uWX28資訊網——每日最新資訊28at.com

    .element {  will-change: transform;}

    uWX28資訊網——每日最新資訊28at.com

  1. uWX28資訊網——每日最新資訊28at.com

    使用 image-rendering 屬性:uWX28資訊網——每日最新資訊28at.com

    uWX28資訊網——每日最新資訊28at.com

  • image-rendering屬性用于指定圖像的渲染質量,而且在某些情況下也能觸發GPU硬件加速。例如:uWX28資訊網——每日最新資訊28at.com

    .element {  image-rendering: pixelated;}

    uWX28資訊網——每日最新資訊28at.com

  1. uWX28資訊網——每日最新資訊28at.com

    使用 backface-visibility 屬性:uWX28資訊網——每日最新資訊28at.com

    uWX28資訊網——每日最新資訊28at.com

  • backface-visibility屬性用于指定當元素不面向屏幕時是否可見。在某些情況下,該屬性的使用可以觸發GPU硬件加速。例如:uWX28資訊網——每日最新資訊28at.com

    .element {  backface-visibility: hidden;}

    uWX28資訊網——每日最新資訊28at.com

  1. uWX28資訊網——每日最新資訊28at.com

    使用 filter 屬性(某些情況下):uWX28資訊網——每日最新資訊28at.com

    uWX28資訊網——每日最新資訊28at.com

  • 在某些情況下,使用filter屬性(如模糊、對比度等)可能觸發GPU硬件加速。uWX28資訊網——每日最新資訊28at.com

還記得我們在你會在瀏覽器中打斷點嗎?我會!中介紹過如何看chromium 在線倉庫[2]uWX28資訊網——每日最新資訊28at.com

那我們就從源碼的角度來看看,為什么上面的屬性會走GPU硬件加速uWX28資訊網——每日最新資訊28at.com

或者我們可以看compositing_reason_finder.cc這個文件,它例舉了很多枚舉類型。uWX28資訊網——每日最新資訊28at.com

圖片圖片uWX28資訊網——每日最新資訊28at.com

2. 事件循環(Event Loop)

事件循環就是一個「死循環」,不死不休。uWX28資訊網——每日最新資訊28at.com

舊的操作系統不支持多線程,它們的事件循環可以被大致描述為一個簡單的循環:uWX28資訊網——每日最新資訊28at.com

while (true) {    if (hasTasks()) {        executeTask();    }}

現代操作系統的調度器(schedulers)非常復雜。它們有優先級設置、執行隊列等許多其他技術。uWX28資訊網——每日最新資訊28at.com

這里做一個題外話,看到schedulers/優先級設置是不是想到React-Fiber架構了。其實,React在內部就是模仿操作系統,做了自己的實現邏輯。(這里就不展開說明了)uWX28資訊網——每日最新資訊28at.com

為了讓事情簡單化,我們可以將事件循環(Event Loop)描述為一個循環,該循環檢查是否有任何待處理的任務:uWX28資訊網——每日最新資訊28at.com

圖片圖片uWX28資訊網——每日最新資訊28at.com


任務觸發器

瀏覽器屬于「事件驅動」的技術框架,如果想讓Event Loop探查并執行對應的任務,首先要做的就是將某些任務進行觸發。也就是喚起指定任務的觸發器。uWX28資訊網——每日最新資訊28at.com

下面就是我們平時能夠接觸到的任務觸發器uWX28資訊網——每日最新資訊28at.com

  1. 「<script>標簽」:通過HTML的<script>標簽引入的代碼會被瀏覽器解析并執行,相關的同步任務會被放入事件循環中。
  2. 「延后的任務」:

setTimeout:設置一個計時器,在指定的延時后執行一段代碼。uWX28資訊網——每日最新資訊28at.com

setInterval:設置一個計時器,按照指定的時間間隔重復執行一段代碼。uWX28資訊網——每日最新資訊28at.com

requestIdleCallback:安排一個函數在瀏覽器空閑時期被調用。uWX28資訊網——每日最新資訊28at.com

  1. 「瀏覽器API的事件處理程序」:

用戶觸發的事件,例如click, mousedown, input, blur等。uWX28資訊網——每日最新資訊28at.com

代碼生成的事件,比如XMLHttpRequest的響應處理、fetch API的promise resolve等。uWX28資訊網——每日最新資訊28at.com

  1. uWX28資訊網——每日最新資訊28at.com

    「Promise狀態變化」:當一個Promise對象的狀態改變時(例如從pending變為fulfilled或rejected),相關的任務會被加入事件循環。uWX28資訊網——每日最新資訊28at.com

    uWX28資訊網——每日最新資訊28at.com

  2. uWX28資訊網——每日最新資訊28at.com

    「觀察者」:uWX28資訊網——每日最新資訊28at.com

    uWX28資訊網——每日最新資訊28at.com

DOMMutationObserver:用于觀察DOM變動,當DOM發生變化時可以通知應用。uWX28資訊網——每日最新資訊28at.com

IntersectionObserver:用于觀察元素是否進入了父元素或視口的特定區域。uWX28資訊網——每日最新資訊28at.com

  1. uWX28資訊網——每日最新資訊28at.com

    requestAnimationFrame:用于在「下一次重新渲染前」執行動畫或視覺更新的函數,使動畫流暢。uWX28資訊網——每日最新資訊28at.com

    uWX28資訊網——每日最新資訊28at.com

上面的任務幾乎都是通過WebAPI進行觸發的。uWX28資訊網——每日最新資訊28at.com

例如,我們在代碼中有這樣一行:setTimeout(function a() {}, 100)。當我們執行setTimeout時,WebAPI將任務延遲了100毫秒。100毫秒后,WebAPI將函數a()放入任務隊列(Task Queue)(也可以稱為Callback Queue)中。事件循環在下一個循環中獲取該任務并執行它。uWX28資訊網——每日最新資訊28at.com

JS執行和頁面渲染是難兄難弟

EventLoop = TaskQueue + RenderQueueuWX28資訊網——每日最新資訊28at.com

在之前的文章中,我們提到過文檔對象模型(DOM)是一個應用編程接口(API),通過創建表示文檔的樹,以一種「獨立于平臺和語言」的方式訪問和修改一個頁面的內容和結構。uWX28資訊網——每日最新資訊28at.com

在HTML文檔中,Web開發者可以使用JS來CRUD DOM 結構,其主要的目的是「動態」改變HTML文檔的結構。uWX28資訊網——每日最新資訊28at.com

  • 讀取DOM元素的數據:大小、屬性、位置等
  • 改變屬性:data-屬性、寬度、高度、位置、CSS屬性等
  • 創建/刪除HTML節點

而在JS把玩DOM之后,就將其扔給了瀏覽器的渲染引擎,而渲染引擎任勞任怨的處理DOM和DOM攜帶的附帶信息,并將其渲染成用戶心儀的頁面。uWX28資訊網——每日最新資訊28at.com

也就是說「JS和瀏覽器(渲染引擎)都能染指過DOM」。uWX28資訊網——每日最新資訊28at.com

基于上面的特定的背景,我們可以得出一個結論,執行JS和渲染頁面都在同一個線程里。uWX28資訊網——每日最新資訊28at.com

這意味著事件循環包含渲染流程。而渲染流程不是單一的操作。其實,它是渲染隊列:uWX28資訊網——每日最新資訊28at.com

圖片圖片uWX28資訊網——每日最新資訊28at.com

現在EventLoop處理鏈路上有兩個任務源。uWX28資訊網——每日最新資訊28at.com

  1. JS任務 - SomeJsTasks
  2. 渲染任務 - RenderQueue

屏幕更新

對于瀏覽器來說,事件循環與幀(frames)密切相關,因為EventLoop同時執行JS代碼并渲染頁面。uWX28資訊網——每日最新資訊28at.com

可以將幀視為屏幕狀態的快照,即用戶在某一時刻看到的畫面。uWX28資訊網——每日最新資訊28at.com

圖片圖片uWX28資訊網——每日最新資訊28at.com

我們在Chromium 最新渲染引擎--RenderingNG也介紹過frames。uWX28資訊網——每日最新資訊28at.com

圖片圖片uWX28資訊網——每日最新資訊28at.com

瀏覽器的目標是盡快顯示頁面更新,考慮到硬件和軟件的限制:uWX28資訊網——每日最新資訊28at.com

  • 硬件限制:屏幕刷新率
  • 軟件限制:操作系統設置、瀏覽器及其設置、節能設置等

絕大多數瀏覽器/操作系統支持60幀每秒(Frames Per Second,FPS)。瀏覽器試圖以這個特定的速率更新屏幕。uWX28資訊網——每日最新資訊28at.com

當我們使用60 FPS時,這意味著瀏覽器在必須「渲染新幀之前有16.6毫秒的時間段來執行任務」(1000/60),而渲染新幀也會消耗時間。uWX28資訊網——每日最新資訊28at.com

3. 任務隊列/微任務隊列/調用棧

瀏覽器使用兩個隊列來執行我們的JS代碼:uWX28資訊網——每日最新資訊28at.com

  • 任務隊列(TaskQueue)或宏任務隊列專用于所有事件、延遲任務等。
  • 微任務隊列(Microtask Queue)用于處理 promise 回調(已解決和已拒絕),以及 MutationObserver。這個隊列中的單個元素被稱為 微任務。

任務隊列(Task Queue)

當瀏覽器收到一個新任務時,它將任務放入任務隊列。每個事件循環定期從任務隊列中獲取任務并執行它。任務完成后,「如果瀏覽器有時間(渲染隊列沒有任務),事件循環從任務隊列獲取另一個任務,直到渲染隊列接收到任務為止」。uWX28資訊網——每日最新資訊28at.com

案例分析1

圖片圖片uWX28資訊網——每日最新資訊28at.com

我們有3個任務:A、B、C。事件循環獲取并執行第一個任務,花費了4毫秒。然后事件循環檢查其他隊列(微任務隊列和渲染隊列),它們是空的。事件循環執行任務B,花費了12毫秒。總共兩個任務使用了16毫秒。然后瀏覽器將任務添加到渲染隊列以繪制新幀。事件循環檢查渲染隊列并開始執行渲染隊列中的任務,它們大約花費1毫秒。完成這些操作后,事件循環返回到任務隊列并執行最后一個任務C。uWX28資訊網——每日最新資訊28at.com

事件循環無法預測任務將花費多少時間。此外,事件循環「無法暫停任務來渲染幀」,因為瀏覽器引擎不知道該任務是否會對繪制內容有修改動作,還是任務只是為了渲染幀做了一些無關痛癢的準備工作。uWX28資訊網——每日最新資訊28at.com

在執行JS代碼期間,「JS所做的所有更改并不會直接呈現給用戶,而是等到宏任務和所有待處理的微任務完成后才會表現出來」。但是,此時在JS中可以獲取到最新DOM的變更信息。uWX28資訊網——每日最新資訊28at.com

案例分析2

圖片圖片uWX28資訊網——每日最新資訊28at.com

隊列中只有2個任務(A、B)。第一個任務A花費了240毫秒(無法中斷)。由于60FPS意味著每16.6毫秒應該渲染一幀,所以瀏覽器有14幀的空窗期。當任務A結束時,事件循環執行渲染隊列中的任務以繪制新幀。uWX28資訊網——每日最新資訊28at.com

「盡管我們失去了14幀,這并不意味著我們將連續渲染15幀。它只會渲染最后一幀」。uWX28資訊網——每日最新資訊28at.com

這就是當JS中有長任務執行時,會阻塞頁面的渲染,如果這14幀中間操作了過多的DOM,頁面中就會有一種從第一幀到第十五幀的跳動。這就是為什么我們總是要將長任務拆分成很多小任務的原因。uWX28資訊網——每日最新資訊28at.com

調用棧(Call Stack)

在Event Loop 可視化解析講解中我們對調用棧有過介紹。uWX28資訊網——每日最新資訊28at.com

圖片圖片uWX28資訊網——每日最新資訊28at.com

案例分析

function D() {  debugger;  console.log('前端柒八九');}function C() {  D();}function B() {  C();  }function other() {   // 不在我們考察堆棧上下文中}function A() {  const arr = [];  while (arr.length < 2) {    arr.push(other());  }  B();}console.log(A());

將上面的代碼貼到devTool-Console或者devTool-Source-Snippet中執行。這段代碼將在debugger處暫停。uWX28資訊網——每日最新資訊28at.com

這里多提一嘴,關于如何在瀏覽器中優雅的調試斷點,可以參考你會在瀏覽器中打斷點嗎?我會!uWX28資訊網——每日最新資訊28at.com

  • console.log(A());,它是調用棧的開始。
  • 然后我們進入 A 函數,并多次調用 other。在我們到達debugger之前,這個函數不會出現在調用棧中,因為它在我們到達調試器之前就結束了。

這是我們在debugger停止時調用棧的樣子:uWX28資訊網——每日最新資訊28at.com

圖片圖片uWX28資訊網——每日最新資訊28at.com

圖中(anonymous)表示全局作用域,我們沒貼出來,它就是指向25行調用棧的入口的。uWX28資訊網——每日最新資訊28at.com

當調用棧為空時,「當前任務」完成。uWX28資訊網——每日最新資訊28at.com

微任務

微任務只有兩個可能的來源:uWX28資訊網——每日最新資訊28at.com

  1. Promise 回調(onResolved/onRejected)
  2. MutationObserver 回調。

微任務有一個主要特征,使它們與其他任務完全不同:uWX28資訊網——每日最新資訊28at.com

一旦調用棧為空,微任務將立即執行。uWX28資訊網——每日最新資訊28at.com

微任務可以創建其他微任務,「這些微任務將在調用棧結束時執行」。每個「新的微任務都會推遲執行新的宏任務或新幀的渲染」。uWX28資訊網——每日最新資訊28at.com

案例分析

在這個例子中,微任務隊列中有4個微任務:uWX28資訊網——每日最新資訊28at.com

圖片圖片uWX28資訊網——每日最新資訊28at.com

要執行的第一個微任務是A。A花費了200毫秒,而且我們在渲染隊列中有任務。然而,它們將被推遲,因為我們仍然有3個微任務。這意味著在執行A后,事件循環將執行微任務B、C,最后是D。當「微任務隊列變空時,事件循環渲染新幀」。在這個例子中,這4個微任務花費了0.5秒。在這段時間內,瀏覽器「UI被阻塞,不可交互」。uWX28資訊網——每日最新資訊28at.com

后續的微任務可以阻塞網站UI,使頁面變得不可交互。uWX28資訊網——每日最新資訊28at.com

這個微任務特性既可能是優勢也可能是劣勢。例如,當 MutationObserver 根據DOM更改調用其回調時,用戶在回調完成之前看不到頁面上的更改。因此,我們可以有效地管理用戶看到的內容。uWX28資訊網——每日最新資訊28at.com

更新后的事件循環圖示:uWX28資訊網——每日最新資訊28at.com

圖片圖片uWX28資訊網——每日最新資訊28at.com

各自的特性

  • 調用棧是用于跟蹤「正在被執行」函數的機制,而宏任務隊列是用于跟蹤「將要被執行」函數的機制。
  • 宏任務隊列和微任務隊列都是「FIFO」(先進先出)的隊列結構,這些任務是「同步阻塞」的

4. 在渲染隊列中執行的是什么?

其實,在瀏覽器中渲染頁面是有很多步驟的。uWX28資訊網——每日最新資訊28at.com

同時還涉及多個進程之間的通信。這在之前的頁面是如何生成的(宏觀角度)有過介紹,這里就不在羅嗦了。uWX28資訊網——每日最新資訊28at.com

而今天呢,我們從瀏覽器渲染幀的角度來看到底發生了啥?!其實幀渲染不是一個單一的操作,它有幾個階段,每個階段都可以分為子階段。uWX28資訊網——每日最新資訊28at.com

新幀渲染的基本結構uWX28資訊網——每日最新資訊28at.com

RequestAnimationFrame(RAF)

圖片圖片uWX28資訊網——每日最新資訊28at.com

requestAnimationFrame 是一個由瀏覽器提供的 JavaScript API,用于在下一次「瀏覽器重繪之前」執行指定的函數。這個函數通常用于執行動畫或其他需要高性能更新的任務,因為它會在瀏覽器的繪制周期內運行,以確保動畫的平滑流暢。uWX28資訊網——每日最新資訊28at.com

特點

  1. 「與瀏覽器的重繪同步:」 requestAnimationFrame 的執行時機與瀏覽器的重繪周期相同,通常是每秒60次(60幀每秒),這確保了動畫的流暢性。
  2. 「自動暫停:」 當用戶切換到其他標簽頁或最小化瀏覽器時,requestAnimationFrame 會自動暫停,從而節省系統資源。
  3. 「避免卡頓:」 由于與瀏覽器的繪制同步,requestAnimationFrame 可以避免由于連續執行任務導致的卡頓和性能問題。
  4. RAF的回調有一個DOMHighResTimeStamp參數,它是自時間起源[3]以來經過的毫秒數,即文檔生命周期的開始。我們不需要在回調中使用performance.now();
  5. RAF返回一個描述符(id),因此你可以使用cancelAnimationFrame取消RAF回調(就像使用setTimeout一樣);
  6. 更改元素大小或讀取元素屬性的JS代碼會強制使用requestAnimationFrame;

樣式重新計算(Recalc Style)

圖片圖片uWX28資訊網——每日最新資訊28at.com

瀏覽器重新計算應用的樣式。此步驟還會計算哪些媒體查詢將處于活動狀態。uWX28資訊網——每日最新資訊28at.com

以下操作能觸發重新計算包括uWX28資訊網——每日最新資訊28at.com

  • 直接更改,比如 a.styles.left = '10px'
  • 通過CSS文件描述的更改,比如 element.classList.add('my-styles-class')。

此過程可能觸發整個DOM樹的整體計算也可以是局部小范圍的計算過程,取決于「被改動的元素的位置」。uWX28資訊網——每日最新資訊28at.com

  • 例如,改動body元素的屬性,就會發生整個DOM樹的重新計算。

圖片圖片uWX28資訊網——每日最新資訊28at.com

將元素樣式和DOM元素結合起來,就會生成Render TreeuWX28資訊網——每日最新資訊28at.com

我們可以通過devTool-Performance來檢測網站在這步所花費的時間。uWX28資訊網——每日最新資訊28at.com

圖片圖片uWX28資訊網——每日最新資訊28at.com

React官網-樣式重新計算所花費時間uWX28資訊網——每日最新資訊28at.com

布局(Layout)

計算每個「可視元素」的位置信息(距離視口的距離和元素本身大小)。并生成對應的Layout Tree。 頁面上的DOM元素越多,操作就越復雜。uWX28資訊網——每日最新資訊28at.com

圖片圖片uWX28資訊網——每日最新資訊28at.com

React官網-布局所花費時間React官網-布局所花費時間uWX28資訊網——每日最新資訊28at.com

觸發條件

對于現今「富應用」來講,做頁面中做元素的移動和變更那是家常便飯。以下操作就會觸發對應的布局流程uWX28資訊網——每日最新資訊28at.com

  • 讀取與元素的大小和位置相關的屬性(offsetWidth、offsetLeft、getBoundingClientRect等)。
  • 寫入與元素的大小和位置相關的屬性,除了某些屬性(例如 transform 和 will-change)。

這里,我們用一點篇幅來講一下為何transform/will-change能跳過布局階段,直接進入合成階段。uWX28資訊網——每日最新資訊28at.com

在之前的Chromium 最新渲染引擎--RenderingNG我們講過,在渲染流程的最開始其實是還有一個步驟叫做animate。uWX28資訊網——每日最新資訊28at.com

圖片圖片uWX28資訊網——每日最新資訊28at.com

在渲染流程的圖中,用不同顏色來標識該階段可能會被不同的線程或者進程所執行。uWX28資訊網——每日最新資訊28at.com

顏色uWX28資訊網——每日最新資訊28at.com

所在進程/線程uWX28資訊網——每日最新資訊28at.com

綠色uWX28資訊網——每日最新資訊28at.com

渲染進程中的主線程uWX28資訊網——每日最新資訊28at.com

黃色uWX28資訊網——每日最新資訊28at.com

渲染進程中的合成線程uWX28資訊網——每日最新資訊28at.com

橘色uWX28資訊網——每日最新資訊28at.com

viz進程(也叫GPU進程)uWX28資訊網——每日最新資訊28at.com

在某些階段,可能會被多個地方所執行,所以該階段可能存在多個顏色。uWX28資訊網——每日最新資訊28at.com

而animate存在兩個顏色(綠色和黃色)也就是這一步,會在多個地方被執行。uWX28資訊網——每日最新資訊28at.com

而讓animate能夠在黃色階段,也就是在合成線程中執行,就是我們使用了一些CSS3屬性uWX28資訊網——每日最新資訊28at.com

  1. transform
  2. opacity
  3. filter
  4. will-change

使用了這些屬性后,會跳過前面很多的步驟,例如重新計算樣式/布局/重繪等階段。并且,在合成線程進行數據轉換后,開啟GPU的「硬件加速」。uWX28資訊網——每日最新資訊28at.com

就這速度,你說能不快嗎。uWX28資訊網——每日最新資訊28at.com

其實,上面的內容在大部分教程中,都是一種鐵打不動的定律。使用了transform/will-change開啟了GPU硬件加速,所以性能提升了。uWX28資訊網——每日最新資訊28at.com

強制布局

強制布局(Forced Synchronous Layout 或 Forced Reflow)是Web性能優化領域的一個術語,它指的是瀏覽器在能夠繼續「處理后續操作之前,必須完成當前的布局計算」。uWX28資訊網——每日最新資訊28at.com

當強制執行布局時,瀏覽器會暫停JS主線程,盡管調用棧不是空的。uWX28資訊網——每日最新資訊28at.com

有很多我們耳熟能詳的操作,都會觸發強制布局。uWX28資訊網——每日最新資訊28at.com

圖片圖片uWX28資訊網——每日最新資訊28at.com

想了解更多

本文鏈接:http://www.www897cc.com/showinfo-26-39500-0.htmlEventLoop = TaskQueue + RenderQueue,你看明白了嗎?

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 為什么不能通過GetProcAddress調用CreateWindow?

下一篇: .NET Core 3.1 升級到 .NET 8,看看都有哪些變化

標簽:
  • 熱門焦點
  • vivo TWS Air開箱體驗:真輕 臻好聽

    在vivo S15系列新機的發布會上,vivo的最新款真無線藍牙耳機vivo TWS Air也一同發布,本次就這款耳機新品給大家帶來一個簡單的分享。外包裝盒上,vivo TWS Air保持了vivo自家產
  • 6月安卓手機好評榜:魅族20 Pro蟬聯冠軍

    性能榜和性價比榜之后,我們來看最后的安卓手機好評榜,數據來源安兔兔評測,收集時間2023年6月1日至6月30日,僅限國內市場。第一名:魅族20 Pro好評率:95%5月份的時候魅族20 Pro就是
  • 線程通訊的三種方法!通俗易懂

    線程通信是指多個線程之間通過某種機制進行協調和交互,例如,線程等待和通知機制就是線程通訊的主要手段之一。 在 Java 中,線程等待和通知的實現手段有以下幾種方式:Object 類下
  • 摸魚心法第一章——和配置文件說拜拜

    為了能摸魚我們團隊做了容器化,但是帶來的問題是服務配置文件很麻煩,然后大家在群里進行了“親切友好”的溝通圖片圖片圖片圖片對比就對比,簡單對比下獨立配置中心和k8s作為配
  • 自動化在DevOps中的力量:簡化軟件開發和交付

    自動化在DevOps中扮演著重要角色,它提升了DevOps的效能。通過自動化工具和方法,DevOps團隊可以實現以下目標:消除手動和重復性任務。簡化流程。在整個軟件開發生命周期中實現更
  • 花7萬退貨退款無門:誰在縱容淘寶珠寶商家造假?

    來源:極點商業作者:楊銘在淘寶購買珠寶玉石后,因為保證金不夠賠付,店鋪關閉,退貨退款難、維權無門的比比皆是。&ldquo;提供相關產品鑒定證書,支持全國復檢,可以30天無理由退換貨。&
  • 2299元起!iQOO Pad開啟預售:性能最強天璣平板

    5月23日,iQOO如期舉行了新品發布會,除了首發安卓最強旗艦處理器的iQOO Neo8系列新機外,還在發布會上推出了旗下首款平板電腦——iQOO Pad,其搭載了天璣
  • Windows 11發布,微軟一改往常對老機型開放的態度

    距離 Windows 11 發布已經過去一周,在過去一周里,很多數碼愛好者圍繞其對 Android 應用的支持、對老機型的升級問題展開了激烈討論。與以往不同的是,在這次大
  • 榮耀Magic4 至臻版 首創智慧隱私通話 強勁影音系統

    2022年第一季度臨近尾聲,在該季度內,許多品牌陸續發布自己的最新產品,讓大家從全新的角度來了解當今的手機技術。手機是電子設備中,更新迭代十分迅速的一款產品,基
Top 主站蜘蛛池模板: 南昌市| 屏南县| 穆棱市| 新宾| 枣强县| 保定市| 蚌埠市| 油尖旺区| 东源县| 当涂县| 儋州市| 平遥县| 营山县| 和平区| 固始县| 镇原县| 红桥区| 开鲁县| 宿松县| 平阳县| 临沂市| 铜鼓县| 南召县| 老河口市| 合山市| 确山县| 准格尔旗| 西和县| 汶上县| 临猗县| 离岛区| 焉耆| 扶余县| 广平县| 周至县| 巧家县| 垫江县| 公主岭市| 二手房| 郧西县| 泸西县|