成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

藝龍網王海濱:前端渲染優化-domdiff

原創
開發 架構 前端
對于不斷發展的web應用,性能的優化,用戶的體驗從來都沒有間斷過,如何逆水行舟,不進則退。隨著通訊技術的高速發展,web應用在近幾年快速增加及普及,已經成為人們必不可少的工具,充斥著生活的方方面面,商務,娛樂,旅游,工作。

對于不斷發展的web應用,性能的優化,用戶的體驗從來都沒有間斷過,如何逆水行舟,不進則退。隨著通訊技術的高速發展,web應用在近幾年快速增加及普及,已經成為人們必不可少的工具,充斥著生活的方方面面,商務,娛樂,旅游,工作。

隨著用戶規模的日益增大,web應用的內容和功能也變得越來越豐富,各大應用對于用戶的體驗,流量,內存,性能優化也越來越高,人們不僅僅要看到自己需要的內容,還對響應速度,動畫的流暢性,瀏覽網頁的等待時間都提出了非常大的要求。

在網頁首屏優化上,我們盡量采用異步加載頁面數據的方式來提升用戶的流暢性,也增加了一些離線模板的技術規劃,而在代碼的底層組件,我們引入了一下新的方向,去減少用戶點擊事件之后對頁面DOM節點的操作,從而提升用戶體驗。

我們希望slarkjs是一個簡單的,通用的,易了解和使用的框架,而我們的組員也保持著平常心的心態去豐富我們的框架,我們希望slarkjs是很多初級的h5開發希望去了解的,去熟悉的,以下我會用很多非常白話文的概念思路去解析我們的框架組件,給一些對h5有興趣,對slarkjs有興趣的前端開發童靴去了解組件化的開發思路與框架的理念。

回到dom優化上,最開始我們打算是引用domdiff的理念,來進行數據對比,而這些數據對比完全是在js中去實現,然后精簡之后來進行dom的操作。舉個簡單的例子,一個dom節點可能是這樣的: 

  1. <ul> 
  2. <li>1</li> 
  3. <li>2</li> 
  4. <li>3</li> 
  5. <li>4</li> 
  6. </ul> 

 

而我們想把它變成這樣 

  1. <ul> 
  2. <li>1</li> 
  3. <li>2</li> 
  4. <li>3</li> 
  5. <li>5</li> 
  6. <li>6</li> 
  7. </ul> 

正常情況我們只有兩種方式,***種,替換整個ul節點,第二種,將你想要變成的數據循環inner進去,這樣我們就有了4次的刪除和5次的添加,但是我們覺得這些dom操作太多了。

其實真實的情況,我們最需要把第四個li中的數據替換,并且在后面添加一個<li>6/li>就能達到我們需要的結果,我們需要一個組件來幫助我們對dom節點的操作進行分析。一般的domdiff應用都存在于大多數的聊天室,評論區,一些頻繁的dom替換的場所,我們希望他是一個小型的,方便應用的,適合框架的一個小應用。

在開發期間,我們還花費了將近兩周的時間對現在非常流行的react及react-native進行了詳細的技術調研,我不得不說,react的開發效率是我目前所見最快速的框架,他的模塊化開發思路,虛擬dom的理念都是我非常喜歡的一種方式,并且我們嘗試了將它合并進slarkjs框架,開始我們只希望讓它來負責view層的重繪工作,但是在實踐中我們其實更希望它能負責更多的內容,可惜的是,react來web層面的使用,還有一定局限性,并且需要大量的開發時間來修改一些組件,很遺憾我們暫時停滯了這個項目的開發進度,但react-native在app上的開發,卻是一個潛能***的壯舉,在之后的文章中,我們會持續的給大家帶來slarkjs框架是如何吸收react-native并融入到app的開發。現在我們先回到domdiff的思路邏輯中。首先,我們在構建domdiff中,想法是很簡單的,

1.    我們需要它來接收2個參數,1.現在頁面上的節點,2.我們需要讓它變成什么樣子。

  1. var domdiff = function(oldid,newid) { 
  2.         var a1 = document.getElementById(oldid); 
  3.         var a2 = document.getElementById(newid); 
  4.         var dd = new diffDOM(); 
  5.         dd.apply(a2, dd.diff(a2, a1)); 
  6.     }; 
  7. var tdomdiff = function(oldid,newid) { 
  8.         var a2 = document.getElementById(oldid); 
  9.         var a3 = document.createElement('div');  
  10.         a3.innerHTML = newid; 
  11.         var dd = new diffDOM(); 
  12.         dd.apply(a2, dd.diff(a2, a3)); 
  13.     };

2.    我們需要它來對2個參數進行數據對比,并放回一個list,里面包含最少量級的dom操作

  1. if (!tree1 || !tree2) { 
  2.            return false
  3.        } 
  4.        if (tree1.nodeType !== tree2.nodeType) { 
  5.            return false
  6.        } 
  7.        if (tree1.nodeType === 3) { 
  8.            if (tree2.nodeType !== 3) { 
  9.                return false
  10.            } 
  11. return preventRecursion ? true : tree1.data === tree2.data; 
  12.        } 
  13.        if (tree1.nodeName !== tree2.nodeName) { 
  14.            return false
  15.        } 
  16.        if (tree1.tagName === tree2.tagName) { 
  17.            .... 
  18.        } 
  19.        if (tree1.childNodes.length !== tree2.childNodes.length) { 
  20.            return false
  21.        } 

3.    去實現list 

  1. Object.keys(options).forEach(function(t) { 
  2.     diff[t] = options[t]; 
  3.     }); 

從開發的角度來講,1,3都非常好實現,而第二步,會讓大多數的前端開發覺得頭疼,這時候我們需要介紹兩個很容易被遺忘,并且不會經常用到的屬性nodeTpye和childNodes,其實JS有很多屬性我們是很少會用到或者說,在我們的業務開發中和技術實現中很少去涉及的,相對來說,這也影響了我們對更深入的技術開發的方向,所以很多時候,我們提倡去看一些開發大拿的代碼,其實是去看他們都用到了哪些屬性,他們的開發邏輯思維,而并不是去copy他們的代碼。

NodeType,它會讓我們獲得body元素的節點類型。說得簡單一些,就是讓我們知道當前節點是元素,屬性,文本內容等等

ChildNodes會讓我們獲得body元素的子節點集合,以NodeList對象。簡單解釋就是返回一個list,里面是當前節點下所有的子節點,包括class,文本,select,option等等。

之后就很好去分析我們的構想了,通過NodeType去獲取節點并判斷節點屬性,當然還要去判斷當前頁面的節點是否唯一,然后通過ChildNodes去對比節點下屬性之間的差異,并且需要增加一些屬性作為標記,比如判斷當前是否應該修改,修改的順序等等。OK,說干就干,于是我們有了以下這個邏輯圖

 

 

(點擊圖片查看大圖)

    我們在diff中傳建了一個空的list數組,然后將2個nodeType傳到finddiff中,finddiff會做兩件事情,在finddiff-out中判斷在body中是否唯一,然后分離其中的數據并在list中增加***個修改項,也就是最外層的修改項。然后再Finddiff-inner中通過ChildNodes分析內部結構,并且循環去判斷2組數據中是否重疊,這里有個小問題,就是你需要用用距離值去填充匹配獲相同的內容量,舉個例子:

 

  1. <ul> 
  2. <li>1</li> 
  3. <li>2</li> 
  4. <li>3</li> 
  5. <li>4</li> 
  6. </ul> 

 

而我們想把它變成這樣

 

  1. <ul> 
  2. <li>1</li> 
  3. <li>5</li> 
  4. <li>6</li> 
  5. <li>3</li> 
  6. <li>4</li> 
  7. </ul> 

 

如果你僅僅是去循環判斷重復,那你會在第二步的時候,將5變成2,第三步將6變成3,這樣是一個很浪費資源的,所以我們需要用距離值去填充,當我們用新數據去循環的時候,我們需要在***次循環中判斷參數是否重復,對重復的參數判斷修改值為false,再第二次循環中對非重復的參數用距離值去填充數據,***得出最簡單的list來覆蓋。

這樣的方式,減少了頁面對dom的操作次數,提升頁面的加載速率和二次加載速率,但是也是有一些坑的,比如:如果頁面dom修改量巨大,在循環中會浪費非常多的時間去循環判斷重復項,可能會比單獨替換整體dom節點花費更多的時間,所以在domdiff中,需要增加一些判斷,去適應大多數的方式。比如:減少循環,如果只是單純的文本替換,我們并不需要去循環判斷它的其他屬性,又或者增加閥值,如果運行時間或者數據量超過標準時間進行部分的dom替換,這些都是組件級對代碼的嚴謹性。

結尾,domdiff其實是為了瀏覽器的優化而做,但是也要適應當前的環境而用,它更像是react虛擬dom理念的前身,有好處也有壞處,使用時候還需謹慎,我們會在今后的1,2個月中,對react-native進行詳細的分析,并且嘗試去融入到我們的框架中,也許會打出分支版,slarkjs-native來支持app的開發,到時候會給大家繼續分享進一步的技術體驗,希望對h5比較有興趣的童靴可以加入到我們的team中,體驗既擁有Native的用戶體驗、又保留React的開發效率。

參考文獻

http://www.w3school.com.cn/jsref/prop_node_nodetype.asp

http://www.w3school.com.cn/jsref/prop_node_childnodes.asp

https://github.com/Seven-wang/react 

作者簡介
 
王海濱 ,8年互聯網前端開發,任職過中演票務通等互聯網電商平臺,14年就任藝龍網前端框架組開發工程師,負責藝龍網前端框架開發。
 
 
責任編輯:王雪燕 來源: 51CTO
相關推薦

2015-09-18 09:10:53

藝龍網Slarkjs框架

2015-12-01 10:05:29

Slarkjs框架離線模板

2015-09-21 11:48:45

藝龍網前端優化IT技術周刊

2016-12-08 10:57:08

渲染引擎前端優化

2023-04-10 11:18:38

前端性能優化

2018-06-27 08:21:31

前端Web渲染

2015-05-27 15:26:46

攜程

2015-05-28 10:35:38

攜程

2015-05-28 13:34:30

攜程

2012-06-01 10:28:54

Web

2012-06-06 15:57:29

Web

2020-05-27 09:41:10

前端性能邊緣計算

2015-05-27 13:57:53

攜程

2022-02-16 08:11:52

組件渲染前端

2015-05-28 10:48:11

攜程

2017-04-12 11:46:46

前端瀏覽器渲染機制

2013-07-10 10:24:10

2015-05-27 14:06:55

攜程

2009-02-19 13:55:58

2015-08-18 15:33:38

戴爾云計算anycloud
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美日韩电影一区 | 久久国产精品色av免费观看 | 国产精品99久久久久久www | 日本一二三区在线观看 | 一级欧美日韩 | 久久久久久久一区 | 中文字幕亚洲精品 | 国产欧美日韩视频 | 日韩在线播放中文字幕 | 亚洲精品视频免费看 | 91丨九色丨国产在线 | 一区二区三区在线播放视频 | 欧美久久久久久久 | 国产精品69久久久久水密桃 | 一区二区三区在线电影 | 国产成人精品一区二区三区视频 | 亚洲视频在线一区 | 精品国产99| 中文字幕国产视频 | 精品亚洲视频在线 | 福利片在线观看 | 久久高清亚洲 | 91亚洲精品国偷拍自产在线观看 | 福利视频一区二区 | 欧美jizzhd精品欧美巨大免费 | 中文字幕一区二区三区乱码在线 | 欧美日韩不卡 | 亚洲成人精品免费 | 欧美一级免费看 | 久久久久久国产精品免费免费男同 | 国产精品亚洲二区 | 亚洲黄色片免费观看 | www.亚洲精品| 国产精品久久久久久久久久久久久 | 中文字幕一级毛片 | 国产成人精品一区二区三区在线 | 一区二区成人 | 在线久草| 日韩欧美一区二区三区 | 黄色在线免费看 | 日韩一区二区不卡 |