高性能javascript學習筆記系列(3) -DOM編程

參考 高性能javascriptjavascript

文檔對象模型(DOM)是獨立於語言的,用於操做XML和HTML文檔的程序接口API,在瀏覽器中主要經過DOM提供的API與HTML進行交互,瀏覽器一般會把DOM和javascript獨立實現,這意味着當咱們經過javascript操做DOM的時候勢必的產生性能上的開銷,所以提高頁面性能的的思路是儘量的減小DOM操做或者優化DOM操做css

DOM的訪問與修改html

  (1)減小頻繁的讀取DOM元素java

(1)for(var i = 0;i < 10;i++) {
  document.getElementById("test") += "a";    
}
//上面的代碼每次循環都進行了讀取 
(2)var content = ""; for(var i = 0;i < 10;i++) { content += "a"; } document.getElementById("test").innerHTML = content; //只有在最後一次經過innerHTML進行了讀取 當咱們更新一段html是使用innerHTML代替原始的dom操做

 (2)節點克隆node

當須要建立大量類似的節點的時候,經過element.clonenode()複製相應的節點,來代替重複的建立相應的節點來提高一部分的性能數組

(3)處理HTML集合瀏覽器

當咱們經過document.getElementsByTagName()   document.getElementsByClassName() document.getElementsByName()  返回的是nodelist  它是一種類數組的集合,咱們能經過下標的方式查找到集合中的元素緩存

一樣的經過下面的屬性獲得的也是html集合 dom

document.images document.links document.forms document.forms[0].elements

操做html集合會出現性能的問題是html集合是維持實時的狀態,也就是當你在文檔中添加一個元素的時候,這個時候你在經過特定的方式獲取html集合的長度的時候它的長度是實時變化的,html集合與文檔處於鏈接的狀態,獲取html的信息的時候須要進行查詢操做。佈局

處理html集合元素有大體兩種方式:

3.1將html集合轉換成數組,由於遍歷數組相對於遍歷集合更快

  function toArray(coll) {
      for(var i = 0,a = [],length = coll.length;i < len;i++) {
        a[i] = coll[i];    
      }
      return a;
  } 

3.2減小集合的查詢操做,緩存局部變量

function test(coll) {
  var length = coll.length;
  var id = "";
  for(var i = 0;i <length;i+=1) {
      var el = coll[i];
      id = el.getAttribute("id");
      console.log(id);
  }
}

(4)選取dom元素 

4.1 使用能區分元素節點的選擇API

屬性名 被替代的屬性
children childNodes
childElementCount childNodes.length
firstElementChild firstChild
lastElementChild  lastChild
nextElementSibling nextSibling
previousElementSibling previousSibling

上面的第一列屬性只會返回相應的元素節點(兩個節點之間的空格也會被識別成文本節點)  當咱們經過第二列屬性進行操做的時候,就須要在進行一步過濾的操做,增長了開銷

4.2 使用選擇器API

當須要進行大量的組合操做的時候,經過document.querySelectorAll()來進行元素的選擇,經過這種方式獲取的是一個nodelist,但它不與文檔進行實時的更新,是一種靜態的列表

(5)重繪與重排

當下載完頁面的組件後,就會生成兩個頁面結構 DOM樹  表示頁面的結構  渲染樹 表示DOM節點如何被顯示   每個在DOM樹中須要被顯示的元素在渲染樹中至少存在一個對應的節點(在渲染樹中的節點稱爲幀或者盒),當DOM的變化影響了元素的幾何屬性(寬高)的時候,這樣瀏覽器就會從新計算元素的幾何尺寸,其餘元素的幾何尺寸也會受到相應的影響,瀏覽器會使渲染樹中受到影響的部分失效並從新構造渲染樹,這個過程叫作重排,完成重排後瀏覽器從新繪製受到影響的部分,這個過程就叫作重繪

重繪和重排都是代價昂貴的操做,因此優化的方案是最小化重繪和重排

重排發生的時機

  •   添加或刪除可見的DOM元素
  •   元素位置的改變
  •   元素尺寸的變化
  •   內容的改變(例如文本的改變或者圖片內容的改變影響了元素的幾何屬性)
  •   頁面渲染器的初始化
  •   瀏覽器窗口尺寸的改變

瀏覽器會優化重排的過程,經過隊列的方式修改並批量的執行重拍的過程,可是當咱們使用一些屬性或者方法的時候,會強制的刷新渲染隊列觸發重排,當咱們頻繁的進行這些操做的時候,就會形成性能的開銷

優化的思路:

(1)集中操做  將設置樣式和獲取樣式進行分離(不要在佈局信息改變的時候去進行查詢操做),而且儘量的合併操做

var el = document.getElementById("test");
el.style.cssText = "border-left:1px;border-right:2px;border-bottom:3px;";

(2)批量的修改DOM的時候,能夠經過下面的方式減小重繪與重排    

  1. 使元素脫離文檔流
  2. 對齊應用修改
  3. 將元素帶回文檔流

脫離文檔流的方案

  1. 隱藏元素 應用修改 顯示元素
  2. 使用文檔碎片(使用document.createDocumentFragment()建立的文檔碎片添加到文檔的時候,就將文檔碎片的子節點進行添加而不是文檔碎片自己)
  3. 將原始元素拷貝進行修改,而後替換元素元素

(3)緩存佈局信息 這個思路有點像處理集合元素的時候的方案,經過緩存局部的佈局信息,能減小強制刷新渲染隊列的次數,也就減小了重排

(4)動畫元素的處理 其實思路是同樣的 動畫有可能會形成大量其餘元素位置改變,當動畫開始的時候,讓它脫離文檔流,進行動畫的展現,動畫完結後讓它回到文檔流

相關文章
相關標籤/搜索