在了解vDOM流程前需要先了解真實DOM的流程
一菇用、真實DOM和其解析流程酌伊?
瀏覽器渲染引擎工作流程都差不多报亩,大致分為5步舌厨,創(chuàng)建DOM樹——創(chuàng)建StyleRules——創(chuàng)建Render樹——布局Layout——繪制Painting
第一步
用HTML分析器岂却,分析HTML元素忿薇,構(gòu)建一顆DOM樹(標記化和樹構(gòu)建)裙椭。
第二步
用CSS分析器躏哩,分析CSS文件和元素上的inline樣式,生成頁面的樣式表揉燃。
第三步
將DOM樹和樣式表扫尺,關(guān)聯(lián)起來,構(gòu)建一顆Render樹(這一過程又稱為Attachment)炊汤。每個DOM節(jié)點都有attach方法正驻,接受樣式信息,返回一個render對象(又名renderer)抢腐。這些render對象最終會被構(gòu)建成一顆Render樹姑曙。
第四步
有了Render樹,瀏覽器開始布局迈倍,為每個Render樹上的節(jié)點確定一個在顯示屏上出現(xiàn)的精確坐標伤靠。
第五步
Render樹和節(jié)點顯示坐標都有了,就調(diào)用每個節(jié)點paint方法啼染,把它們繪制出來宴合。
DOM樹的構(gòu)建是文檔加載完成開始的?構(gòu)建DOM數(shù)是一個漸進過程迹鹅,為達到更好用戶體驗卦洽,渲染引擎會盡快將內(nèi)容顯示在屏幕上。它不必等到整個HTML文檔解析完畢之后才開始構(gòu)建render數(shù)和布局斜棚。
Render樹是DOM樹和CSSOM樹構(gòu)建完畢才開始構(gòu)建的嗎阀蒂?這三個過程在實際進行的時候又不是完全獨立,而是會有交叉弟蚀。會造成一邊加載脂新,一遍解析,一遍渲染的工作現(xiàn)象粗梭。
CSS的解析是從右往左逆向解析的(從DOM樹的下-上解析比上-下解析效率高)争便,嵌套標簽越多,解析越慢断医。
二滞乙、JS操作真實DOM的代價!
用我們傳統(tǒng)的開發(fā)模式鉴嗤,原生JS或JQ操作DOM時斩启,瀏覽器會從構(gòu)建DOM樹開始從頭到尾執(zhí)行一遍流程。在一次操作中醉锅,我需要更新10個DOM節(jié)點兔簇,瀏覽器收到第一個DOM請求后并不知道還有9次更新操作,因此會馬上執(zhí)行流程,最終執(zhí)行10次垄琐。例如边酒,第一次計算完,緊接著下一個DOM更新請求狸窘,這個節(jié)點的坐標值就變了墩朦,前一次計算為無用功。計算DOM節(jié)點坐標值等都是白白浪費的性能翻擒。即使計算機硬件一直在迭代更新氓涣,操作DOM的代價仍舊是昂貴的,頻繁操作還是會出現(xiàn)頁面卡頓陋气,影響用戶體驗劳吠。
三、虛擬DOM
虛擬DOM就是為了解決瀏覽器性能問題而被設(shè)計出來的巩趁。如前赴背,若一次操作中有10次更新DOM的動作,虛擬DOM不會立即操作DOM晶渠,而是將這10次更新的diff內(nèi)容保存到本地一個JS對象中凰荚,最終將這個JS對象一次性attch到DOM樹上,再進行后續(xù)操作褒脯,避免大量無謂的計算量便瑟。所以,用JS對象模擬DOM節(jié)點的好處是番川,頁面的更新可以先全部反映在JS對象(虛擬DOM)上到涂,操作內(nèi)存中的JS對象的速度顯然要更快,等更新完成后颁督,再將最終的JS對象映射成真實的DOM践啄,交由瀏覽器去繪制。
Vitual DOM
是一種虛擬dom技術(shù)沉御,本質(zhì)上是基于javascript
實現(xiàn)的屿讽,相對于dom
對象,javascript
對象更簡單吠裆,處理速度更快伐谈,dom
樹的結(jié)構(gòu),屬性信息都可以很容易的用javascript
對象來表示试疙。
Virtual DOM
并沒有完全實現(xiàn)DOM
诵棵,Virtual DOM
最主要的還是保留了Element
之間的層次關(guān)系和一些基本屬性. 你給我一個數(shù)據(jù),我根據(jù)這個數(shù)據(jù)生成一個全新的Virtual DOM
祝旷,然后跟我上一次生成的Virtual DOM
去 diff
履澳,得到一個Patch
嘶窄,然后把這個Patch
(補丁)打到瀏覽器的DOM
上去。
虛擬DOM的存在的意義距贷? Vitual DOM
的真正意義是為了實現(xiàn)跨平臺柄冲,服務(wù)端渲染,以及提供一個性能還算不錯 Dom 更新策略储耐。Vitual DOM
讓整個 mvvm 框架靈活了起來。
diff
只是為了虛擬DOM比較替換效率更高滨溉,通過diff
得到diff算法結(jié)果數(shù)據(jù)表(需要進行哪些操作記錄表)什湘。原本要操作的DOM在vue這邊還是要操作的,只不過用到了js的DOM fragment來操作dom(統(tǒng)一計算出所有變化后統(tǒng)一更新一次DOM)進行瀏覽器DOM一次性更新晦攒。其實DOM fragment我們不用平時發(fā)開也能用闽撤,但是這樣程序員寫業(yè)務(wù)代碼就用把DOM操作放到fragment里,這就是框架的價值脯颜,程序員才能專注于寫業(yè)務(wù)代碼。