瀏覽器渲染頁面的主體流程

當咱們在瀏覽器輸入網址後;瀏覽器都會作哪些事情纔會讓咱們看見頁面呢?javascript

  • 首先在客戶端瀏覽器輸入網址:www.baidu.com
  • 客戶端瀏覽器向服務器發送請求 HTTP REQUEST(省略不少細節步驟)
  • 服務器端存儲着百度官網項目的原代碼
  • 服務器收到請求後:服務器端把指定文中的代碼返回給客戶端 HTTP RESPONSE

1、進程/線程

一個進程中,會包含零到多個線程java

一、進程 process

  • 電腦端安裝不少的應用軟件,每當運行一個應用程序,都至關於開闢了一個進程
  • 而對於瀏覽器來講,每新建一個頁卡訪問一個頁面,都是新開闢一個進程

二、線程 thread

  • 每個進程當中可能還會同時作多件事情,若是同時作多件事情,則會開闢多個線程

2、瀏覽器經常使用線程

瀏覽器是「多線程」的,可是JS渲染或者頁面渲染是「單線程」的編程

  • GUI 渲染線程
    • 渲染和繪製頁面
  • JS 引擎線程
    • 運行和渲染JS代碼
  • 事件管控和觸發線程
  • 定時器管控和觸發線程
  • 異步 HTTP 請求線程
  • ......

3、同步/異步

一、同步編程

  • 單線程
  • 一次只能處理一件事情,當前這件事情處理完,才能繼續處理下一件事情

二、異步編程

  • 同時能夠進行好幾件事情(通常是基於多線程併發完成的)
  • JS 中的異步編程,有本身一些特殊的處理方式
    • 隊列 Queue
    • 事件循環 EventLoop

例題:

let n = 10;
setTimeout(() => {
    n++;
    console.log(n);
}, 0);
console.log(n);
for (let i = 0; i < 99999999; i++) {}
console.log(n);
複製代碼

按步解析:瀏覽器

  • 一、JS 是單線程的,因此在 「棧」 中,代碼必定是按照順序,自上而下依次執行的服務器

  • 二、代碼執行過程當中若是遇到一個異步的操做代碼:網絡

    • 定時器(設置定時器的操做是同步的(當即設置),異步指的是間隔多久後執行指定的函數)
    • 事件綁定(監聽)
    • AJAX的異步請求
    • PROMISE/ASYNC/AWAIT
    • ......
  • 事件對列 EventQueue多線程

    • 三、當遇到定時器以後:瀏覽器默認開闢一個 事件隊列 EventQueue
    • 四、JS 代碼執行過程當中遇到的異步操做,都先放置到事件隊列中
      • 本題是把:(間隔瀏覽器最小反應事件內,執行對應的箭頭函數),放到事件隊列中
      • 瀏覽器會單獨開闢一個定時器線程:監聽事件隊列中存儲的各個定時器的到達時間
      • 只有 GUI 線程空閒下來,纔會過來找
  • 五、此時 GUI 渲染線程繼續向下執行代碼:輸出 10併發

  • 六、遇到循環:循環是同步的,代碼中遇到死循環,會中斷整個頁面的循環或者中斷代碼的執行異步

  • 七、繼續執行同步代碼:輸出10異步編程

  • 事件循環 EventLoop

    • 八、棧內存中的同步任務代碼都執行完了:
      • 去事件隊列中找到達時間的任務
      • 把找到的已經到達執行條件的任務,放入到棧中執行(每次只拿回來一個)
      • 仍是 GUI 線程執行他
    • 九、等 GUI 執行完,「閒下來」,在去事件隊列中找其餘到達時間的任務......一直到事件隊列被執行完爲止

    這個循環查找的過程就是 EventLoop 事件循環

三、三種 CSS 樣式的渲染區別

GUI 渲染頁面時,當遇到其餘請求時的兩種處理方法:

  • 讓 GUI 線程本身去拿:
    • 在CSS文件沒有從服務器加載回來以前,下面的代碼不會繼續渲染
  • 在開闢一個線程,專門去服務器加載CSS文件:
    • 不用管CSS是否加載回來,GUI線程繼續向下渲染

-1).在渲染過程當中遇到 <link> 引入式樣式 : 異步操做

  • 瀏覽器會新開闢一個 HTTP 的請求線程,專門去服務器加載 CSS 樣式內容
  • 此時 GUI 線程還能夠繼續向下渲染(不用管 CSS 是否回來)

-2).若是遇到的是 @import 導入式樣式 : 同步操做

  • 不會開闢新的線程去加載 CSS ,而是當前線程去加載
  • 這樣只要 CSS 沒有加載回來,下面的代碼都不會繼續渲染(阻礙頁面渲染)

<link>@import 相比較: link 會提升頁面渲染速度

-3).內嵌式

上面雖說link會提升頁面渲染速度 ,可是當 CSS 代碼較少的狀況下,咱們最好採用內嵌式(把CSS 和 HTML 寫在一塊兒),這樣只要把 HTML 加載回來,CSS 也回來了

任何形式的HTTP請求都必定會有時間和性能的消耗

  • 前提是CSS代碼少;
  • 代碼多的狀況下,若是仍是和HTML放在一塊兒,那麼第一次請求HTML的速度都會變慢,也就得不償失了;

4、瀏覽器渲染頁面的步驟

一、生成 DOM 樹

渲染了全部的 HTML 標籤

  • 轉換
    • 經過 HTTP 返還的首先是十六進制的編碼字節數據
    • 拿到字節數據後,瀏覽器會經過內部的機制,把數據轉換成咱們能看到的代碼
  • 令牌
    • 按照 W3C 規範(第五代版本的規範H5)的規則,轉換成咱們能看懂的標籤
  • 詞法分析
    • 經過轉換後的標籤,進行詞法解析,生成DOM節點
  • DOM構建
    • 最後經過查找每一個DOM節點之間的關係,生成DOM

圖片來源:圖片摘自網絡,若有侵權,聯繫刪除

二、生成 CSSOM 樹

請求回來 CSS 後,渲染完 CSS

同生成DOM樹同樣的過程生成CSSOM

圖片來源:圖片摘自網絡,若有侵權,聯繫刪除

三、DOM 樹 + CSSOM 樹 => RENDER-TREE(渲染樹)

圖片來源:圖片摘自網絡,若有侵權,聯繫刪除

四、 佈局(Layout)或 重排/迴流(reflow)

按照 RENDER-TREE 在設備的視口中進行結構和位置的相關計算=>佈局(Layout)或 重排/迴流(reflow)

五、繪製(painting)或 柵格化(rasterizing)

根據渲染樹以及迴流獲得的幾何信息,獲得節點的絕對像素=>繪製(painting)或 柵格化(rasterizing)

思惟導圖

相關文章
相關標籤/搜索