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

減少瀏覽器重解析 JavaScript DOM操作優化方案

開發 前端
DOM操作會導致瀏覽器重解析(reflow),這是瀏覽器的一個決定頁面元素如何展現的計算過程,文章介紹了4種優化方案,覆蓋了修改和創建DOM節點兩種方式,幫助你減少觸發瀏覽器重解析的次數。

在我們開發互聯網富應用(RIA)時,我們經常寫一些JavaScript腳本來修改或者增加頁面元素,這些工作最終是DOM——或者說文檔對象模型——來完成的,而我們的實現方式會影響到應用的響應速度。

51CTO推薦閱讀:深入解讀JavaScript中BOM和DOM

DOM操作會導致瀏覽器重解析(reflow),這是瀏覽器的一個決定頁面元素如何展現的計算過程。直接修改DOM,修改元素的CSS樣式,修改瀏覽器的窗口大小,都會觸發重解析。讀取元素的布局屬性比如offsetHeithe或者offsetWidth也會觸發重解析。重解析需要花費計算時間,因此重解析觸發的越少,應用就會越快。

DOM操作通常要不就是修改已經存在的頁面上的元素,要不就是創建新的頁面元素。下面的4種優化方案覆蓋了修改和創建DOM節點兩種方式,幫助你減少觸發瀏覽器重解析的次數。

方案一:通過CSS類名切換來修改DOM

這個方案讓我們可以一次性修改一個元素和它的子元素的多個樣式屬性而只觸發一次重解析。

需求

我們現在需要寫一個函數來修改一個超鏈接的幾個樣式規則。要實現很簡單,把這幾個規則對應的屬性逐一改了就好了。但是帶來的問題是,每修改一個樣式屬性,都會導致一次頁面的重解析。

  1. function selectAnchor(element) {  
  2.   element.style.fontWeight = 'bold';  
  3.   element.style.textDecoration = 'none';  
  4.   element.style.color = '#000';  

解決方案

要解決這個問題,我們可以先創建一個樣式名,并且把要修改的樣式規則都放到這個類名上,然后我們給超鏈接添加上這個新類名,就可以實現添加幾個樣式規則而只觸發一次重解析了。這個模式還有個好處是也實現了表現和邏輯相分離。

  1. .selectedAnchor {  
  2.   font-weight: bold;  
  3.   text-decoration: none;  
  4.   color: #000;  
  5. }  
  6. function selectAnchor(element) {  
  7.   element.className = 'selectedAnchor';  

方案二:在非渲染區修改DOM

上一個方案解決的是修改一個超鏈接的問題,當一次需要對很多個超鏈接進行相同修改的時候,這個方案就可以大顯身手了。

需求

需求是這樣的,我們要寫一個函數來修改一個指定元素的子元素中所有的超鏈接的樣式名(className)屬性。要實現很簡單,我們可以通過遍歷每個超鏈接并且修改它們的樣式名來完成任務。但是帶來的問題就是,每修改一個超鏈接都會導致一次重解析。

  1. function updateAllAnchors(element, anchorClass) {  
  2.   var anchors = element.getElementsByTagName('a');  
  3.   for (var i = 0length = anchors.length; i < length; i ++) {  
  4.      anchors.className = anchorClass;  
  5.   }  

解決方案

要解決這個問題,我們可以把被修改的指定元素從DOM里面移除,再修改所有的超鏈接,然后在把這個元素插入回到它原來的位置上。為了完成這個復雜的操作,我們可以先寫一個可重用的函數,它不但移除了這個DOM節點,還返回了一個把元素插回到原來的位置的函數。

  1. /**  
  2. * Remove an element and provide a function that inserts it into its original position  
  3. * @param element {Element} The element to be temporarily removed  
  4. * @return {Function} A function that inserts the element into its original position  
  5. **/  
  6.  
  7. function removeToInsertLater(element) {  
  8.   var parentNode = element.parentNode;  
  9.   var nextSibling = element.nextSibling;  
  10.   parentNode.removeChild(element);  
  11.   return function() {  
  12.     if (nextSibling) {  
  13.        parentNode.insertBefore(element, nextSibling);  
  14.     } else {  
  15.    parentNode.appendChild(element);  
  16.     }  
  17.   };  

有了上面這個函數,現在我們就可以在一個不需要解析渲染的元素上面修改那些超鏈接了。這樣只在移除和插入元素的時候各觸發一次重解析。

  1. function updateAllAnchors(element, anchorClass) {  
  2.   var insertFunction = removeToInsertLater(element);  
  3.   var anchors = element.getElementsByTagName('a');  
  4.   for (var i = 0length = anchors.length; i < length; i ++) {  
  5.      anchors.className = anchorClass;  
  6.   }  
  7.     insertFunction();  

方案三:一次性的DOM元素生成

這個方案讓我們創建一個元素的過程只觸發一次重解析。在創建完元素以后,先進行所有需要的修改,最后才把它插入到DOM里面去就可以了

需求

需求是這樣的,實現一個函數,往一個指定的父元素上插入一個超鏈接元素。這個函數要同時可以設置這個超鏈接的顯示文字和樣式類。我們可以這樣做:創建元素,插入到DOM里面,然后設置相應的屬性。這就要觸發3次重解析。

  1. function addAnchor(parentElement, anchorText, anchorClass) {  
  2.   var element = document.createElement('a');  
  3.   parentElement.appendChild(element);  
  4.   element.innerHTML = anchorText;  
  5.   element.className = anchorClass;  

解決方案

很簡單,我們只要把插入元素這個操作放到最后做,就可以只進行一次重解析了。

  1. var element = document.createElement('a');  
  2. element.innerHTML = anchorText;  
  3. element.className = anchorClass;  
  4. parentElement.appendChild(element);  

復制代碼不過,要是我們想要插入很多個超鏈接到一個元素里面的話,那么這個做法還是有問題:每插入一個超鏈接還是要觸發一次重解析。下一個方案可以解決這個問題。

方案四:通過文檔片段對象(DocumentFragment)創建一組元素

這個方案允許我們創建并插入很多個元素而只觸發一次重解析。要實現這點需要用到所謂的文檔片段對象(DocumentFragment)。我們先在 DOM之外創建一個文檔片段對象(這樣它也就不需要解析和渲染),然后我們在文檔片段對象中創建很多個元素,最后我們把這個文檔片段對象中所有的元素一次性放到DOM里面去,只觸發一次重解析。

需求

我們要寫一個函數,往一個指定的元素上面增加10個超鏈接。如果我們簡單的直接插入10個超鏈接到元素上面,就會觸發10次重解析。

  1. function addAnchors(element) {  
  2. var anchor;  
  3. for (var i = 0; i < 10; i ++) {  
  4.     anchor = document.createElement('a');  
  5.     anchor.innerHTML = 'test';  
  6.     element.appendChild(anchor);  
  7.     }  

解決方案

要解決這個問題,我們要先創建一個文檔片段對象,然后把每個新創建的超鏈接都插入到它里面去。當我們把文檔片段對象用appendChild命令插入到指定的節點時,這個文檔片段對象的所有子節點就一起被插入到指定的元素里面,而且只需要觸發一次重解析。

  1. function addAnchors(element) {  
  2.   var anchor, fragment = document.createDocumentFragment();  
  3.   for (var i = 0; i < 10; i ++) {  
  4.     anchor = document.createElement('a');  
  5.     anchor.innerHTML = 'test';  
  6.     fragment.appendChild(anchor);  
  7.   }  
  8.   element.appendChild(fragment);  

【編輯推薦】

  1. IE中JavaScript DOM ready應用技巧
  2. 深入解讀JavaScript中BOM和DOM
  3. 雕蟲無小技 JavaScript初學者的10個迷你技巧
  4. 早該知道的7個JavaScript技巧
  5. JavaScript最讓人費解的十件事
責任編輯:王曉東 來源: pin5i
相關推薦

2016-10-09 08:38:01

JavaScript瀏覽器事件

2010-09-15 09:12:03

JavaScript瀏覽器兼容

2022-12-08 15:42:36

瀏覽器重繪回流

2018-01-19 14:39:53

瀏覽器頁面優化

2010-09-28 15:12:27

Javascript

2010-09-13 17:12:55

JavaScript

2016-10-26 23:00:15

javascripttesttdd

2017-01-05 09:07:25

JavaScript瀏覽器驅動

2017-07-19 14:26:01

前端JavaScriptDOM

2012-08-02 10:21:49

DOM瀏覽器

2010-09-08 16:50:11

JavaScriptDOM操作

2010-10-08 15:00:08

FirefoxJavaScript兼

2010-09-28 14:52:57

JavaScriptDOM

2010-09-08 15:47:08

JavsScriptJavaScript

2009-03-23 14:14:33

JSONAJAXJavaScript

2010-09-28 15:07:48

JavaScript

2017-02-07 09:44:12

Chrome源碼DOM樹

2013-11-05 16:32:18

搜狗瀏覽器安全漏洞

2015-04-22 09:26:58

前端頁面卡頓DOM操作

2017-10-09 13:39:26

瀏覽器渲染服務器
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 97人人干 | 亚洲国产精品99久久久久久久久 | 久久亚洲美女 | 久久国产婷婷国产香蕉 | 国产综合在线视频 | 久久国产欧美日韩精品 | 天天干视频 | 免费av电影网站 | 天天色天天射天天干 | 天天色天天色 | 中文字幕成人在线 | 日韩国产黄色片 | 欧美成年网站 | 九九福利 | 亚洲精品久久久久久一区二区 | 亚洲精品免费在线观看 | 久久蜜桃精品 | 一二三四av | 麻豆视频在线免费观看 | 精品在线一区 | 天天插天天操 | 99热首页| 欧美videosex性极品hd | 自拍偷拍欧美 | hdfreexxxx中国妞 | 婷婷久久综合 | 少妇久久久久 | 久久激情视频 | 亚洲精品国产电影 | 国产精品久久久久久久久图文区 | 国产高清视频一区 | 亚洲一区二区在线播放 | 精品亚洲一区二区 | 国产日韩精品在线 | 在线免费黄色小视频 | 亚洲欧美综合精品久久成人 | 黄色欧美在线 | 国产乱码久久久 | 三级视频在线观看电影 | 精品国产乱码久久久久久牛牛 | 国产免费一区二区三区最新6 |