电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

一篇文章帶你搞懂Vue虛擬Dom與diff算法

瀏覽:146日期:2022-12-03 14:04:41

前言

使用過Vue和React的小伙伴肯定對虛擬Dom和diff算法很熟悉,它扮演著很重要的角色。由于小編接觸Vue比較多,React只是淺學,所以本篇主要針對Vue來展開介紹,帶你一步一步搞懂它。

虛擬DOM

什么是虛擬DOM?

虛擬DOM(Virtual Dom),也就是我們常說的虛擬節點,是用JS對象來模擬真實DOM中的節點,該對象包含了真實DOM的結構及其屬性,用于對比虛擬DOM和真實DOM的差異,從而進行局部渲染來達到優化性能的目的。真實的元素節點:

<div id='wrap'> <p class='title'>Hello world!</p></div>

VNode:

{ tag:’div’, attrs:{ id:’wrap’ }, children:[ { tag:’p’, text:’Hello world!’, attrs:{ class:’title’, } } ]}

為什么使用虛擬DOM?

簡單了解虛擬DOM后,是不是有小伙伴會問:Vue和React框架中為什么會用到它呢?好問題!那來解決下小伙伴的疑問。起初我們在使用JS/JQuery時,不可避免的會大量操作DOM,而DOM的變化又會引發回流或重繪,從而降低頁面渲染性能。那么怎樣來減少對DOM的操作呢?此時虛擬DOM應用而生,所以虛擬DOM出現的主要目的就是為了減少頻繁操作DOM而引起回流重繪所引發的性能問題的!

虛擬DOM的作用是什么?

兼容性好。因為Vnode本質是JS對象,所以不管Node還是瀏覽器環境,都可以操作; 減少了對Dom的操作。頁面中的數據和狀態變化,都通過Vnode對比,只需要在比對完之后更新DOM,不需要頻繁操作,提高了頁面性能;

虛擬DOM和真實DOM的區別?

說到這里,那么虛擬DOM和真實DOM的區別是什么呢?總結大概如下:

虛擬DOM不會進行回流和重繪; 真實DOM在頻繁操作時引發的回流重繪導致性能很低; 虛擬DOM頻繁修改,然后一次性對比差異并修改真實DOM,最后進行依次回流重繪,減少了真實DOM中多次回流重繪引起的性能損耗; 虛擬DOM有效降低大面積的重繪與排版,因為是和真實DOM對比,更新差異部分,所以只渲染局部;

總損耗 = 真實DOM增刪改 + (多節點)回流/重繪; //計算使用真實DOM的損耗總損耗 = 虛擬DOM增刪改 + (diff對比)真實DOM差異化增刪改 + (較少節點)回流/重繪; //計算使用虛擬DOM的損耗

可以發現,都是圍繞頻繁操作真實DOM引起回流重繪,導致頁面性能損耗來說的。不過框架也不一定非要使用虛擬DOM,關鍵在于看是否頻繁操作會引起大面積的DOM操作。

那么虛擬DOM究竟通過什么方式來減少了頁面中頻繁操作DOM呢?這就不得不去了解DOM Diff算法了。

DIFF算法

當數據變化時,vue如何來更新視圖的?其實很簡單,一開始會根據真實DOM生成虛擬DOM,當虛擬DOM某個節點的數據改變后會生成一個新的Vnode,然后VNode和oldVnode對比,把不同的地方修改在真實DOM上,最后再使得oldVnode的值為Vnode。

diff過程就是調用patch函數,比較新老節點,一邊比較一邊給真實DOM打補丁(patch);

對照vue源碼來解析一下,貼出核心代碼,旨在簡單明了講述清楚,不然小編自己看著都頭大了O(∩_∩)O

patch

那么patch是怎樣打補丁的?

//patch函數 oldVnode:老節點 vnode:新節點function patch (oldVnode, vnode) { ... if (sameVnode(oldVnode, vnode)) { patchVnode(oldVnode, vnode) //如果新老節點是同一節點,那么進一步通過patchVnode來比較子節點 } else { /* -----否則新節點直接替換老節點----- */ const oEl = oldVnode.el // 當前oldVnode對應的真實元素節點 let parentEle = api.parentNode(oEl) // 父元素 createEle(vnode) // 根據Vnode生成新元素 if (parentEle !== null) { api.insertBefore(parentEle, vnode.el, api.nextSibling(oEl)) // 將新元素添加進父元素 api.removeChild(parentEle, oldVnode.el) // 移除以前的舊元素節點 oldVnode = null } } ... return vnode}//判斷兩節點是否為同一節點function sameVnode (a, b) { return ( a.key === b.key && // key值 a.tag === b.tag && // 標簽名 a.isComment === b.isComment && // 是否為注釋節點 // 是否都定義了data,data包含一些具體信息,例如onclick , style isDef(a.data) === isDef(b.data) && sameInputType(a, b) // 當標簽是<input>的時候,type必須相同 )}

從上面可以看出,patch函數是通過判斷新老節點是否為同一節點:

如果是同一節點,執行patchVnode進行子節點比較; 如果不是同一節點,新節點直接替換老節點;

那如果不是同一節點,但是它們子節點一樣怎么辦嘞?OMG,要牢記:diff是同層比較,不存在跨級比較的!簡單提一嘴,React中也是如此,它們只是針對同一層的節點進行比較。

patchVnode

既然到了patchVnode方法,說明新老節點為同一節點,那么這個方法做了什么處理?

function patchVnode (oldVnode, vnode) { const el = vnode.el = oldVnode.el //找到對應的真實DOM let i, oldCh = oldVnode.children, ch = vnode.children if (oldVnode === vnode) return //如果新老節點相同,直接返回 if (oldVnode.text !== null && vnode.text !== null && oldVnode.text !== vnode.text) { //如果新老節點都有文本節點且不相等,那么新節點的文本節點替換老節點的文本節點 api.setTextContent(el, vnode.text) }else { updateEle(el, vnode, oldVnode) if (oldCh && ch && oldCh !== ch) { //如果新老節點都有子節點,執行updateChildren比較子節點[很重要也很復雜,下面展開介紹] updateChildren(el, oldCh, ch) }else if (ch){ //如果新節點有子節點而老節點沒有子節點,那么將新節點的子節點添加到老節點上 createEle(vnode) }else if (oldCh){ //如果新節點沒有子節點而老節點有子節點,那么刪除老節點的子節點 api.removeChildren(el) } }}

如果兩個節點不一樣,直接用新節點替換老節點;

如果兩個節點一樣,

​新老節點一樣,直接返回; ​老節點有子節點,新節點沒有:刪除老節點的子節點; 老節點沒有子節點,新節點有子節點:新節點的子節點直接append到老節點; ​都只有文本節點:直接用新節點的文本節點替換老的文本節點; ​都有子節點:updateChildren

最復雜的情況也就是新老節點都有子節點,那么updateChildren是如何來處理這一問題的,該方法也是diff算法的核心,下面我們來了解一下!

updateChildren

由于代碼太多了,這里先做個概述。updateChildren方法的核心:

提取出新老節點的子節點:新節點子節點ch和老節點子節點oldCh; ch和oldCh分別設置StartIdx(指向頭)和EndIdx(指向尾)變量,它們兩兩比較(按照sameNode方法),有四種方式來比較。如果4種方式都沒有匹配成功,如果設置了key就通過key進行比較,在比較過程種startIdx++,endIdx--,一旦StartIdx > EndIdx表明ch或者oldCh至少有一個已經遍歷完成,此時就會結束比較。

下面結合圖來理解:

一篇文章帶你搞懂Vue虛擬Dom與diff算法

第一步:

oldStartIdx = A , oldEndIdx = C;newStartIdx = A , newEndIdx = D;

此時oldStartIdx和newStarIdx匹配,所以將dom中的A節點放到第一個位置,此時A已經在第一個位置,所以不做處理,此時真實DOM順序:A B C;

第二步:

oldStartIdx = B , oldEndIdx = C;newStartIdx = C , oldEndIdx = D;

一篇文章帶你搞懂Vue虛擬Dom與diff算法

此時oldEndIdx和newStartIdx匹配,將原本的C節點移動到A后面,此時真實DOM順序:A C B;

第三步:

oldStartIdx = C , oldEndIdx = C;newStartIdx = B , newEndIdx = D;oldStartIdx++,oldEndIdx--;oldStartIdx > oldEndIdx

此時遍歷結束,oldCh已經遍歷完,那么將剩余的ch節點根據自己的index插入到真實DOM中即可,此時真實DOM順序:A C B D;

所以匹配過程中判斷結束有兩個條件:

oldStartIdx > oldEndIdx表示oldCh先遍歷完成,如果ch有剩余節點就根據對應index添加到真實DOM中; newStartIdx > newEndIdx表示ch先遍歷完成,那么就要在真實DOM中將多余節點刪除掉;

看下圖這個實例,就是新節點先遍歷完成刪除多余節點:

一篇文章帶你搞懂Vue虛擬Dom與diff算法

最后,在這些子節點sameVnode后如果滿足條件繼續執行patchVnode,層層遞歸,直到oldVnode和Vnode中所有子節點都比對完成,也就把所有的補丁都打好了,此時更新到視圖。

總結

最后,用一張圖來記憶整個Diff過程,希望你能有所收獲!

一篇文章帶你搞懂Vue虛擬Dom與diff算法

彩蛋

因為React只是簡單學了基礎,這里作為對比來概述一下:

1.React渲染機制:React采用虛擬DOM,在每次屬性和狀態發生變化時,render函數會返回不同的元素樹,然后對比返回的元素樹和上次渲染樹的差異并對差異部分進行更新,最后渲染為真實DOM。

2.diff永遠都是同層比較,如果節點類型不同,直接用新的替換舊的。如果節點類型相同,就比較他們的子節點,依次類推。通常元素上綁定的key值就是用來比較節點的,所以一定要保證其唯一性,一般不采用數組下標來作為key值,因為當數組元素發生變化時index會有所改動。

3.渲染機制的整個過程包含了更新操作,將虛擬DOM轉換為真實DOM,所以整個渲染過程就是Reconciliation。而這個過程的核心又主要是diff算法,利用的是生命周期shouldComponentUpdate函數。

到此這篇帶你搞懂Vue虛擬Dom與diff算法的文章就介紹到這了,更多相關Vue虛擬Dom與diff算法內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Vue
相關文章:
主站蜘蛛池模板: 赛默飞Thermo veritiproPCR仪|ProFlex3 x 32PCR系统|Countess3细胞计数仪|371|3111二氧化碳培养箱|Mirco17R|Mirco21R离心机|仟诺生物 | 幂简集成 - 品种超全的API接口平台, 一站搜索、试用、集成国内外API接口 | 苏州柯瑞德货架-仓库自动化改造解决方案 | 外贮压-柜式-悬挂式-七氟丙烷-灭火器-灭火系统-药剂-价格-厂家-IG541-混合气体-贮压-非贮压-超细干粉-自动-灭火装置-气体灭火设备-探火管灭火厂家-东莞汇建消防科技有限公司 | 卓能JOINTLEAN端子连接器厂家-专业提供PCB接线端子|轨道式端子|重载连接器|欧式连接器等电气连接产品和服务 | 知企服务-企业综合服务(ZiKeys.com)-品优低价、种类齐全、过程管理透明、速度快捷高效、放心服务,知企专家! | 车充外壳,车载充电器外壳,车载点烟器外壳,点烟器连接头,旅行充充电器外壳,手机充电器外壳,深圳市华科达塑胶五金有限公司 | 高低温试验房-深圳高低温湿热箱-小型高低温冲击试验箱-爱佩试验设备 | 刺绳_刀片刺网_刺丝滚笼_不锈钢刺绳生产厂家_安平县浩荣金属丝网制品有限公司-安平县浩荣金属丝网制品有限公司 | 佛山市钱丰金属不锈钢蜂窝板定制厂家|不锈钢装饰线条|不锈钢屏风| 电梯装饰板|不锈钢蜂窝板不锈钢工艺板材厂家佛山市钱丰金属制品有限公司 | 欧盟ce检测认证_reach检测报告_第三方检测中心-深圳市威腾检验技术有限公司 | 塑料托盘厂家直销-吹塑托盘生产厂家-力库塑业【官网】 | 变位机,焊接变位机,焊接变位器,小型变位机,小型焊接变位机-济南上弘机电设备有限公司 | 消泡剂-水处理消泡剂-涂料消泡剂-切削液消泡剂价格-东莞德丰消泡剂厂家 | 步进电机_agv电机_伺服马达-伺服轮毂电机-和利时电机 | 拉力机-拉力试验机-万能试验机-电子拉力机-拉伸试验机-剥离强度试验机-苏州皖仪实验仪器有限公司 | 国产液相色谱仪-超高效液相色谱仪厂家-上海伍丰科学仪器有限公司 | 窖井盖锯圆机_锯圆机金刚石锯片-无锡茂达金刚石有限公司 | 上海平衡机-单面卧式动平衡机-万向节动平衡机-圈带动平衡机厂家-上海申岢动平衡机制造有限公司 | 全自动端子机|刺破式端子压接机|全自动双头沾锡机|全自动插胶壳端子机-东莞市傅氏兄弟机械设备有限公司 | 创富网-B2B网站|供求信息网|b2b平台|专业电子商务网站 | PCB设计,PCB抄板,电路板打样,PCBA加工-深圳市宏力捷电子有限公司 | 杰福伦_磁致伸缩位移传感器_线性位移传感器-意大利GEFRAN杰福伦-河南赉威液压科技有限公司 | 餐饮小吃技术培训-火锅串串香培训「何小胖培训」_成都点石成金[官网] | 维泰克Veertek-锂电池微短路检测_锂电池腐蚀检测_锂电池漏液检测 | 中山市派格家具有限公司【官网】 | 环保袋,无纺布袋,无纺布打孔袋,保温袋,环保袋定制,环保袋厂家,环雅包装-十七年环保袋定制厂家 | 嘉兴泰东园林景观工程有限公司_花箱护栏 | 双效节能浓缩器-热回流提取浓缩机组-温州市利宏机械 | 多米诺-多米诺世界纪录团队-多米诺世界-多米诺团队培训-多米诺公关活动-多米诺创意广告-多米诺大型表演-多米诺专业赛事 | 模具钢_高速钢_不锈钢-万利钢金属材料 | 深圳市宏康仪器科技有限公司-模拟高空低压试验箱-高温防爆试验箱-温控短路试验箱【官网】 | 深圳美安可自动化设备有限公司,喷码机,定制喷码机,二维码喷码机,深圳喷码机,纸箱喷码机,东莞喷码机 UV喷码机,日期喷码机,鸡蛋喷码机,管芯喷码机,管内壁喷码机,喷码机厂家 | 酒水灌装机-白酒灌装机-酒精果酒酱油醋灌装设备_青州惠联灌装机械 | 冷却塔减速机器_冷却塔皮带箱维修厂家_凉水塔风机电机更换-广东康明冷却塔厂家 | 影像测量仪_三坐标测量机_一键式二次元_全自动影像测量仪-广东妙机精密科技股份有限公司 | 招商帮-一站式网络营销服务|互联网整合营销|网络推广代运营|信息流推广|招商帮企业招商好帮手|搜索营销推广|短视视频营销推广 | 深圳VI设计-画册设计-LOGO设计-包装设计-品牌策划公司-[智睿画册设计公司] | 钢骨架轻型板_膨石轻型板_钢骨架轻型板价格_恒道新材料 | 【星耀裂变】_企微SCRM_任务宝_视频号分销裂变_企业微信裂变增长_私域流量_裂变营销 | 无线讲解器-导游讲解器-自助讲解器-分区讲解系统 品牌生产厂家[鹰米讲解-合肥市徽马信息科技有限公司] |