記錄--虛擬 DOM 和實際 DOM 有何不同?

来源:https://www.cnblogs.com/smileZAZ/archive/2023/07/27/17585819.html
-Advertisement-
Play Games

這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 前言 本文我們會先聊聊 DOM 的一些缺陷,然後在此基礎上介紹虛擬 DOM 是如何解決這些缺陷的,最後再站在雙緩存和 MVC 的視角來聊聊虛擬 DOM。理解了這些會讓你對目前的前端框架有一個更加底層的認識,這也有助於你更好地理解這些前端框 ...


這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助

前言

本文我們會先聊聊 DOM 的一些缺陷,然後在此基礎上介紹虛擬 DOM 是如何解決這些缺陷的,最後再站在雙緩存和 MVC 的視角來聊聊虛擬 DOM。理解了這些會讓你對目前的前端框架有一個更加底層的認識,這也有助於你更好地理解這些前端框架。

DOM 的缺陷

比如,我們可以調用 document.body.appendChild(node)body 節點上添加一個元素,調用該 API 之後會引發一系列的連鎖反應。首先渲染引擎會將 node 節點添加到 body 節點之上,然後觸發樣式計算、佈局、繪製、柵格化、合成等任務,我們把這一過程稱為 重排。除了重排之外,還有可能引起重繪或者合成操作,形象地理解就是“牽一發而動全身”。另外,對於 DOM 的不當操作還有可能引發強制同步佈局和佈局抖動的問題,這些操作都會大大降低渲染效率。因此,對於 DOM 的操作時我們需要非常謹慎。

對於一些複雜的頁面或者目前使用非常多的單頁應用來說,其 DOM 結構是非常複雜的,而且還需要不斷地去修改 DOM 樹,每次操作 DOM 渲染引擎都需要進行重排、重繪或者合成等操作,因為 DOM 結構複雜,所生成的頁面結構也會很複雜,對於這些複雜的頁面,執行一次重排或者重繪操作都是非常耗時的,這就給我們帶來了真正的性能問題。所以我們需要有一種方式來減少 JavaScript 對 DOM 的操作,這時候虛擬 DOM 就上場了。

什麼是虛擬 DOM?

在談論什麼是虛擬 DOM 之前,我們先來看看虛擬 DOM 到底要解決哪些事情。

  1. 將頁面改變的內容應用到虛擬 DOM 上,而不是直接應用到 DOM 上。
  2. 變化被應用到虛擬 DOM 上時,虛擬 DOM 並不急著去渲染頁面,而僅僅是調整虛擬 DOM 的內部狀態,這樣操作虛擬 DOM 的代價就變得非常輕了。
  3. 在虛擬 DOM 收集到足夠的改變時,再把這些變化一次性應用到真實的 DOM 上。

基於以上三點,我們再來看看什麼是虛擬 DOM。為了直觀理解,你可以參考下圖:

該圖是結合 React 流程畫的一張虛擬 DOM 執行流程圖,下麵我們就結合這張圖來分析下虛擬 DOM 到底怎麼運行的。

  • 創建階段。首先依據 JSX 和基礎數據創建出來虛擬 DOM,它反映了真實的 DOM 樹的結構。然後由虛擬 DOM 樹創建出真實 DOM 樹,真實的 DOM 樹生成完後,再觸發渲染流水線往屏幕輸出頁面。
  • 更新階段。如果數據發生了改變,那麼就需要根據新的數據創建一個新的虛擬 DOM 樹;然後 React 比較兩個樹,找出變化的地方,並把變化的地方一次性更新到真實的 DOM 樹上;最後渲染引擎更新渲染流水線,並生成新的頁面。

既然聊到虛擬 DOM 的更新,那我們就不得不聊聊最新的 React Fiber 更新機制了。最開始的時候,比較兩個虛擬 DOM 的過程是在一個遞歸函數里執行的,其核心演算法是 reconciliation。通常情況下,這個比較過程執行得很快,不過當虛擬 DOM 比較複雜的時候,執行比較函數就有可能占據主線程比較久的時間,這樣就會導致其他任務的等待,造成頁面卡頓。

為瞭解決這個問題,React 團隊重寫了 reconciliation 演算法,新的演算法稱為 Fiber reconciler,所謂的 Fiber reconciler,就是在執行演算法的過程中出讓主線程,這樣就解決了之前執行函數占用時間過久的問題。至於具體的實現過程在這裡就不詳細分析了,如果感興趣的話,你可以自行查閱相關資料進行學習。

瞭解完虛擬 DOM 的大致執行流程,你應該也就知道為何需要虛擬 DOM 了。不過以上都從單純的技術視角來分析虛擬 DOM 的,那接下來我們再從雙緩存和 MVC 模型這兩個視角來聊聊虛擬 DOM。

雙緩存

使用雙緩存,可以讓你先將計算的中間結果存放在另一個緩衝區中,等全部的計算結束,該緩衝區已經存儲了完整的圖形之後,再將該緩衝區的圖形數據一次性複製到顯示緩衝區,這樣就使得整個圖像的輸出非常穩定。

在這裡,你可以把虛擬 DOM 看成是 DOM 的一個 buffer,和圖形顯示一樣,它會在完成一次完整的操作之後,再把結果應用到 DOM 上,這樣就能減少一些不必要的更新,同時還能保證 DOM 的穩定輸出。

MVC 模式

接下來我們再來看看虛擬 DOM 在 MVC 模式中所扮演的角色。

在各大設計模式當中,MVC 是一個非常重要且應用廣泛的模式,因為它能將數據和視圖進行分離,在涉及到一些複雜的項目時,能夠大大減輕項目的耦合度,使得程式易於維護。關於 MVC 的基礎結構,你可以先參考下圖:

 

通過上圖可以發現,MVC 的整體結構比較簡單,由模型、視圖和控制器組成,其核心思想就是將數據和視圖分離,也就是說視圖和模型之間是不允許直接通信的,它們之間的通信是通過控制器來完成的。

比如在分析 React 項目時,我們可以把 React 的部分看成是一個 MVC 中的視圖,在項目中結合 Redux 就可以構建一個 MVC 的模型結構,如下圖所示:

在該圖中,我們可以把虛擬 DOM 看成是 MVC 的視圖部分,其控制器和模型都是由 Redux 提供的。其具體實現過程如下:

  • 圖中的控制器是用來監控 DOM 的變化,一旦 DOM 發生變化,控制器便會通知模型,讓其更新數據。
  • 模型數據更新好之後,控制器會通知視圖,告訴它模型的數據發生了變化。
  • 視圖接收到更新消息之後,會根據模型所提供的數據來生成新的虛擬 DOM。
  • 新的虛擬 DOM 生成好之後,就需要與之前的虛擬 DOM 進行比較,找出變化的節點。
  • 比較出變化的節點之後,React 將變化的虛擬節點應用到 DOM 上,這樣就會觸發 DOM 節點的更新。
  • DOM 節點的變化又會觸發後續一系列渲染流水線的變化,從而實現頁面的更新。

在實際工程項目中,你需要學會分析出各個模塊,並梳理出它們之間的通信關係,這樣對於任何框架你都能輕鬆上手了。

本文轉載於:

https://juejin.cn/post/7226971906652979255

如果對您有所幫助,歡迎您點個關註,我會定時更新技術文檔,大家一起討論學習,一起進步。

 


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

-Advertisement-
Play Games
更多相關文章
  • 一、索引概述 1.1 索引的介紹 索引index:是幫助 Mysql 高效獲取數據 的 有序的數據結構,在數據之外,資料庫系統維護著的滿足特定查找演算法的數據結構,這些數據結構以某種方式引用(指向)數據,這樣就可以在這些數據結構上實現高級查找演算法,這種數據結構就是索引 1.2 索引的優缺點 優點1:提 ...
  • # Spark之探究RDD > 如何瞭解一個組件,先看看官方介紹! ![](https://img2023.cnblogs.com/blog/3161112/202307/3161112-20230727212358040-237097554.png) 進入RDD.scala,引入眼帘的是這麼一段描 ...
  • 向量資料庫是一種專門用於存儲和處理向量數據的資料庫系統。向量數據是指具有多維度屬性的數據,例如圖片、音頻、視頻、自然語言文本等。傳統的關係型資料庫通常不擅長處理向量數據,因為它們需要將數據映射成結構化的表格形式,而向量數據的維度較高、結構複雜,導致存儲和查詢效率低下 ...
  • 忠人之事受人之托 起因是因為一位朋友的資料庫伺服器被重裝了,只剩下一個zbp_post.frm和zbp_post.ibd文件。咨詢我能不能恢復,確實我只用過mysqldump這種工具導出數據 然後進行恢復到資料庫。這種直接備份物理存儲文件還沒有嘗試過。 前提是需要歷史ibd文件的所屬資料庫版本 需要 ...
  • 一、SQL執行頻率 MySQL客戶端 連接成功後,通過show [session | global] status 命令可以提供伺服器狀態信息,通過如下指令,可以查看當前資料庫的insert,update,dalete,select的訪問頻次 show [global | session] stat ...
  • NineData新增了PostgreSQL數據源的支持,這是一個可視化、集成AI、多雲多環境、擁有企業級能力的PostgreSQL解決方案。無論您是個人開發者還是團隊,都可以通過NineData平臺一站式管理您的PostgreSQL數據源。 ...
  • 用戶使用資料庫客戶端工具如navicat、dbeaver等執行超大結果集的查詢語句導致異常中斷,中斷信息Last read message sequence %d is not equal to the max written message sequence %d。 ...
  • 博客推行版本更新,成果積累制度,已經寫過的博客還會再次更新,不斷地琢磨,高質量高數量都是要追求的,工匠精神是學習必不可少的精神。因此,大家有何建議歡迎在評論區踴躍發言,你們的支持是我最大的動力,你們敢投,我就敢肝 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...