激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服務器之家 - 編程語言 - JavaScript - React - 詳解react應用中的DOM DIFF算法

詳解react應用中的DOM DIFF算法

2022-02-25 16:22time_w React

這篇文章主要介紹了react應用中的DOM DIFF算法,幫助大家更好的理解和學習使用react,感興趣的朋友可以了解下

前言

對我們搞前端的來說,目前最流行的兩大前端框架毫無疑問當屬React和Vue,對于這兩大框架,想必大家也是再熟悉不過了。然而,這兩大框架無一例外的全部放棄使用傳統的DOM技術,卻采用了以JS為基礎的Virtual DOM技術,也可稱作虛擬DOM。所以,到底什么是Virtual DOM?兩大熱門框架全部使用Virtual DOM的原因又是什么?接下來讓我這個搞前端的人來好好地為您講解一下DOM DIFF算法的牛逼之處。

什么是Virtual DOM?

如字面意思所說,Virtual DOM即 虛擬DOM,它的特點就是利用Javascript來模擬DOM結構,并且將DOM的變化對比放在JS層中進行比較。具體操作如下:


  1. // 普通的HTML DOM結構
  2. <ul class="list">
  3. <li class="item">wjy</li>
  4. <li class="item">易烊千璽</li>
  5. </ul>
  6.  
  7. // 映射出的虛擬DOM
  8. {
  9. tag:'ul',
  10. props:{
  11. class:'list'
  12. },
  13. children: [
  14. {
  15. tag:'li',
  16. props:{
  17. class:'item'
  18. },
  19. children: ['易烊千璽']
  20. }
  21. ]
  22. }

有朋友或許會有點迷惑,普通的HTML DOM結構不好嗎?通俗易懂,代碼也更加簡潔,為什么還需要采用嵌套遞歸的虛擬DOM形式呢?其實這和普通DOM在重新渲染的過程中非常消耗性能有關,DOM操作看似簡便,但其實效率相當低,這是因為如果是在需要頻繁修改的真實DOM中,看起來更加復雜的運用JS結構的Virtual DOM效率會更高.

使用Virtual DOM的原因

DOM 渲染頁面的操作流程

  • 當瀏覽器通過域名從服務器拿到對應的HTML文件后,瀏覽器首先會進行構建DOM樹和CSSOM樹,關于樹的概念,學過數據結構與算法的同學或許對樹的節點概念印象深刻。
  • 在HTML DOM中,所有的事物都是節點,而DOM是被視為節點樹的HTML,并且,各個節點之間有著相應的層級關系。DOM節點樹和HTML中的標簽一一對應,構成了DOM樹
  • HTML文件

詳解react應用中的DOM DIFF算法

  • HTML DOM樹

詳解react應用中的DOM DIFF算法

同樣的。在CSS文檔中,所有的元素也皆是節點,與HTML中的標簽一一對應,構成了CSSOM樹 如下圖所示

詳解react應用中的DOM DIFF算法

警告! 如果在構建DOM樹的過程中,有遇到JS相關的內容時,DOM樹的構建會立即停止,這是由于,JS可以對DOM節點進行操作,瀏覽器為了防止JS會對以完成的DOM造成影響,會阻止DOM樹的構建,以節約資源。

在DOM樹和CSSOM樹不斷構建的過程中,渲染樹也在逐漸形成,瀏覽器會根據所構建的渲染樹進行網頁布局和繪制流程,不斷地進行網頁的搭建。具體操作流程圖如下:

詳解react應用中的DOM DIFF算法

一般而言,對于頁面渲染的常規操作,我們通常是操作DOM,修改并重置innerHTML完成頁面的渲染,每進行一次DOM的更新操作,都會重新進行一次渲染流程,這個過程包含著頁面的重繪和重排。

Virtual DOM的優勢

詳解react應用中的DOM DIFF算法

但是如果對于大型頁面項目,或者具有多標簽,多屬性的網頁而言,常規的DOM操作實在是太耗時了,每次的簡單修改都需要牽動大量的DOM節點的重繪與重排,極大地降低了頁面渲染效率.于是,當前端開發人員面對DOM瓶頸一籌莫展的時候,Virtual DOM顯示出了作為輕量級的JavaScript對象的極大優越性,順利得到了了前端開發者的青睞。

在頁面進行重新渲染的時候,Virtual DOM進行dom diff計算對比兩次并發現其中的差異,只需要修改DOM樹中不同的部分即可.也可以理解為Virtual DOM做了一個中間件,先利用JS修改Virtual DOM,在對比出差異后,將所有的更改加入頁面的真實DOM.所以說,Virtual DOM的最大優勢就在于完全不用像原生DOM,在對比之后還要進行DOM的重建與創造,因為這對于大型項目的運行來說非常消耗性能,開銷極大.由此可見,不論在什么體量的網頁中,放棄傳統DOM采用Virtual DOM無疑是非常高效且絕佳的選擇.

如何將DOM用virtual DOM 來表示

首先,在vscode中新建一個dom diff 項目,項目初始化,裝好相應組件

由于是DOM樹,所以在將HTML轉換成DOM樹時,要運用遞歸的形式,首先創建結點,其次設置屬性,然后設置子節點


  1. <ul class="list">
  2. <li class="item">wjy</li>
  3. <li class="item">易烊千璽</li>
  4. </ul>
  5.  
  6. // DOM 樹的表達轉換形式
  7. let virtualDOM = createElement('ul', {
  8. class:'list',
  9. }, [
  10. createElement('li',{
  11. class:'item'
  12. },['wjy']),
  13. createElement('li',{
  14. class:'item'
  15. },['易烊千璽']),
  16. ])

然后,在新建一個element.js文件進行向外輸出,完成頁面渲染


  1. // 通過構造函數Element構造虛擬DOM節點
  2. class Element {
  3. constructor(type,props,children){
  4. this.type = type;
  5. this.props = props;
  6. this.children =children;
  7. }
  8. }
  9. //
  10. const createElement = (type,props,children) => {
  11. return new Element(type,props,children);
  12. }
  13.  
  14. // 進行頁面渲染 將Virtual Dom轉化為真實DOM
  15. const render = (domObj) => {
  16. let el = document.createElement(domObj.type);
  17. for(let key in domObj.props){
  18. setAttr(el,key,domObj.props[key]);
  19. }
  20. domObj.children.forEach(child => {
  21. child = (child instanceof Element)
  22. ? render(child)
  23. : document.createTextNode(child);
  24. el.appendChild(child);
  25.  
  26. })
  27. return el;
  28. }
  29.  
  30. function setAttr(node,key,value){
  31. switch(key){
  32. case 'value':
  33. if(node.tagName.toLowerCase() === 'input' ||
  34. node.tagName.toLowerCase() ==='textarea'
  35. ){
  36. node.value = value;
  37. }else{
  38. node.setAttribute(key,value)
  39. }
  40. break;
  41. case 'style':
  42. // node.setAttribute('style',value)
  43. node.style.cssText = value;
  44. break;
  45. default:
  46. node.setAttribute(key,value)
  47. break;
  48. }
  49. }
  50.  
  51. // 將真實DOM 掛載到制定根節點
  52. const renderDOM = (el,target) => {
  53. target.appendChild(el);
  54. }
  55.  
  56. // 向外輸出
  57. export {
  58. createElement,
  59. render,
  60. renderDOM
  61. }

在控制臺上得到真實DOM

詳解react應用中的DOM DIFF算法

頁面渲染成功!

詳解react應用中的DOM DIFF算法

DOM DIFF算法

在用戶進行操作更改交互頁面操作后,虛擬DOM樹上的節點會發生變化,然而此時真實節點卻沒有改變,為了使得更改與真實頁面同步,我們會使用DOM DIFF算法找出這兩顆樹的差異,然后產生差異補丁對象,再將差異補丁對象應用到真實的DOM節點上去,于是完成了頁面的渲染和更新。

傳統的Diff算法時間復雜度達到了O(n^3),若要滿足每次都可以整體刷新頁面的目的,這種指數型的增長的性能開銷是無法滿足性能要求的,于是,Facebook的工程師對此進行了優化,通過制定diff策略將Diff算法的復雜度降低到了O(n)

Diff 策略

  • DOM節點跨層級的操作特別少,所以可以忽略不計
  • 擁有相同類的兩個組件將會產生相似的樹形結構,擁有不同類的兩個組件將會產生不同的樹形結構
  • 同一層級的一組子節點,他們可以通過uuid進行區分

Diff 粒度

由于DIFF的粒度不同,DIFF算法按照下面的順序依次執行

  • Tree DIFF
  • Component DIFF
  • Element DIFF

打補丁

我們根據diff策略以及react diff中的比對算法將兩個虛擬DOM通過深度優先遍歷進行比較,如果有差異,就把所遍歷到節點的索引值所對應的操作存儲起來,也稱為補丁對象(patches)

然后對真實的DOM再次經過深度優先遍歷,補丁對象中的索引就會和DOM相對應,我們就完成了DOM的更新操作。

結語 在互聯網環境下,隨時刷新交互頁面是我們上網的常規操作,然而這一簡單的操作卻是多次算法優化的結果。DOM DIFF的底層原理挺復雜,如果有感興趣的朋友,可以自行搜索相關文獻,因為本文只是淺析,所以太多方面就不贅述了,如果本文有知識錯漏的地方,也歡迎指正!虛心接收一切合理批評!

如果這篇文章有幫助到你對dom diff算法的理解,也希望您能為我點一個贊,答主是剛入門的前端小白,每一個贊都是我前進的動力,我會持續更新掘金的博客的

以上就是詳解react應用中的DOM DIFF算法的詳細內容,更多關于react應用的DOM DIFF算法的資料請關注服務器之家其它相關文章!

原文鏈接:https://juejin.cn/post/6948696440935809031

延伸 · 閱讀

精彩推薦
  • React不用一行代碼,搞懂React調度器原理

    不用一行代碼,搞懂React調度器原理

    本文會講解React調度器Scheduler的實現原理。知道你不喜歡看大段的代碼,所以本文沒有一行代碼。文末有Scheduler的源碼地址,感興趣的話可以去看看。...

    魔術師卡頌10562021-12-26
  • ReactVite搭建React項目的方法步驟

    Vite搭建React項目的方法步驟

    這篇文章主要介紹了Vite搭建React項目的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面...

    Cookieboty5132022-02-24
  • ReactReactRouter的實現方法

    ReactRouter的實現方法

    這篇文章主要介紹了ReactRouter的實現,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下...

    WindrunnerMax6172022-01-06
  • Reactreact-native 實現購物車滑動刪除效果的示例代碼

    react-native 實現購物車滑動刪除效果的示例代碼

    這篇文章主要介紹了react-native 實現購物車滑動刪除效果的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,...

    程序猿tx3882021-12-31
  • ReactReact使用emotion寫css代碼

    React使用emotion寫css代碼

    這篇文章主要介紹了React如何使用emotion寫css代碼,幫助大家更好的理解和學習使用React,感興趣的朋友可以了解下...

    joychenke8162022-02-25
  • ReactReact中setState的使用與同步異步的使用

    React中setState的使用與同步異步的使用

    這篇文章主要介紹了React中setState的使用與同步異步的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋...

    一顆冰淇淋5232022-02-17
  • React使用react從零封裝一個可實時預覽的Json編輯器

    使用react從零封裝一個可實時預覽的Json編輯器

    文章將介紹如何使用react,開發一個自定義json編輯器組件.我們這里使用了jsoneditor這個第三方庫。...

    趣談前端7502022-01-12
  • Reactreact項目從新建到部署的實現示例

    react項目從新建到部署的實現示例

    這篇文章主要介紹了react項目從新建到部署的實現示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們...

    juejin9402022-01-21
主站蜘蛛池模板: 免费一级毛片在线播放视频老 | 欧美一级毛片大片免费播放 | 久久99精品久久久久久国产越南 | 欧美视屏一区二区 | 娇妻被各种姿势c到高潮小说 | 久国久产久精永久网页 | 国产成人自拍视频在线 | 99国产精品自拍 | 黄色网址免费在线播放 | 日韩视频精品一区 | xp123精品视频 | 日本黄色一级毛片 | 一本色道久久久888 香蕉视频99 | 免费毛片视频播放 | 久久精品99久久久久久2456 | 羞羞视频免费入口网站 | 久草成人在线观看 | 特色一级黄色片 | a级高清免费毛片av在线 | 久久久精品网 | av影院在线 | 欧美一级一片 | 在线a免费观看 | 国内精品一级毛片免费看 | 欧美日韩精品一区二区三区蜜桃 | 日韩精品羞羞答答 | 国产成人精品免费视频大全办公室 | 中国久久久 | 噜噜在线视频 | 国产精彩视频在线 | 欧美日韩中文字幕在线视频 | 日本娇小18xxxⅹhd | 日韩欧美激情视频 | 成人福利视频在线 | 亚洲视频黄 | 欧美亚洲一级 | 激情大乳女做爰办公室韩国 | 亚洲午夜久久久久 | 一区二区三区无码高清视频 | 男女羞羞视频在线免费观看 | 日本精品视频一区二区三区四区 |