【用友iUAP專家講堂】React設計虛擬DOM優劣
React是Facebook于2013年5月推出的一個用來構建用戶界面的開源JavaScript框架。React一經推出,便受到國外開發者的追捧,國內的流行始于2014年年中,雖然起步晚,但是發展迅速,目前其相關開發教程和使用文檔已遍布國內各大技術社區和論壇,其中不乏一些對比性質的話題,例如:React.js和Angular.js的優劣對比。
React的迅速成名的背后,與其對DOM(文檔對象模型,Document Object Model)操作的高性能特性是密不可分的。DOM的渲染效率,一直是前端交互開發的重要性能瓶頸,目前主流JavaScript框架中的操作大量依賴于DOM提供的操作,從而導致了前端交互的效率低下,尤其是在大型復雜的頁面渲染中,這種情況表現的比較突出。而React另起爐灶,引入虛擬DOM模式的概念,巧妙繞開了頻繁操作DOM的場景,并利用這種模式來處理DOM,從而讓其更新操作達到***的高效。
理解虛擬DOM的高性能,需要先了解一下DOM的渲染過程。
DOM渲染過程
所謂DOM渲染,即瀏覽器將HTML字符串轉換成網頁視圖并渲染視圖的過程。首先,瀏覽器的HTML解析器,會對HTML字符串進行解析,并將它轉換成DOM樹,同時,CSS解析器也會解析HTML使用到的CSS樣式,生成一系列CSS規則;然后瀏覽器的渲染引擎將DOM樹和CSS規則進行整合,并生成一個可用于視圖渲染的DOM渲染樹;接著確定DOM布局,即每一個節點在瀏覽器中的確切位置;***一步是進行繪制,將每一個節點的每一個像素繪制在屏幕上,于是我們便看到了期望的網頁視圖。深入了解這一過程中的復雜,我們可以再對HTML解析器的處理過程做一個特寫:HTML解析器中,有兩個程序在交替執行: 分詞程序和解析程序;分詞程序負責將HTML字符串切分成合法的DOM標簽字符串,然后交給解析程序處理,解析程序則將其添加到正在構建的DOM樹中;當分詞程序解析完所有的字符串后,DOM樹也便構建完成了。
到這里,我們可以理解DOM的渲染為什么這么慢了: 這個過程,的確是太復雜了。在網頁交互中頻繁地對DOM進行添加、移除操作,會極大地降低視圖渲染的效率,進而降低交互的效率。而在React之前的UI更新操作(包括各大JavaScript框架的UI處理方式),都是先移除原始DOM,再進行新DOM的構建和插入,因而前端交互效率很低,交互體驗很差。
React采用了虛擬DOM模式,于是這種情況改變了。
虛擬DOM,簡單來說,是一個模擬DOM樹的JavaScript對象。React對UI的更新,并沒有使用傳統的方式: 移除指定區域的所有DOM節點,然后把新節點添加進去,而是采用了差異更新的辦法。React會在內存中保留一份指定的原始DOM對應的JavaScript對象,更新之前對比其和新DOM樹的JavaScript對象之間的差異,并精確計算出差異所在,然后對存在差異的DOM的屬性或文本進行更新。例如,使用Ajax更新列表的內容,由***頁轉向第二頁的過程中,如果兩頁數據形成的DOM樹有完全相同的結構,則不會有任何DOM的刪除或添加操作,React僅僅會更新存在差異的原始DOM的屬性或文本值。差異更新的辦法,將DOM的添加、刪除的操作頻次降到了***,也因而減輕了DOM渲染效率低的限制,從而讓React對UI的操作獲得了極大的速度提升。
到了這里,我們可以認識到虛擬DOM的優勢所在:差異對比、差異更新。但是對于這種思想,React的實現方式并不一定是***的,比如這種更新方式,需要對虛擬DOM對象進行存儲,那必然對內存有額外的消耗。而且,如果瀏覽器采用了這種方式來更新DOM,這種思想便從源頭得到了實現,各大JavaScript框架就無需再關心DOM操作的性能問題,那React的高性能優勢是不是就不存在,甚至會變成一種累贅了?