1. 程式人生 > >讀高效能Javascript筆記

讀高效能Javascript筆記

  1. 把一段內嵌指令碼放在引用外鏈樣式表的 標籤之後,會導致頁面阻塞去等待樣式表的下載.
    這樣做是為了內嵌指令碼在執行時能夠獲得最精準的樣式資訊.

  2. 下載同一個 CDN 下的多個 JS 檔案,可以這麼寫:

<script src="http://apps.bdimg.com?/libs/jquery/2.1.4/jquery.min.js&libs/angular.js/1.5.0-beta.0/angular-animate.min.js"></script>

等同於

<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"
>
</script> <script src="http:http://apps.bdimg.com/libs/angular.js/1.5.0-beta.0/angular-animate.min.js"></script>

這樣就可以使用一個 script 標籤下載多個 javascript 檔案.減少了 HTTP 請求

  1. defer, async 新增到標籤中,下載時並行下載不進行阻塞.區別是 async 下載完成後立即執行與順序無關. defer 按標籤順序執行,且執行在 window.onload 之前

  2. Javascript 載入優化方案:

    1. 閉合之前,將所有
try {
    // code may throw error
} catch (e) {
    handleError(e)
}

這樣由於只執行了一條語句且沒有區域性變數的訪問,作用域的臨時改變不影響效能.

  1. 使用閉包的時候應該注意: 在頻繁的訪問跨作用域的識別符號時,每次訪問都會帶來效能損失,解決方案是將常用的外部變數儲存在區域性變數中,然後訪問區域性變數.

  2. 因為在各個瀏覽器中的 JS 引擎 與 DOM 渲染引擎都是兩個相互獨立的部分,僅通過對外暴露的介面呼叫,因為呼叫需要額外的開銷,所以要儘量減少 DOM 操作.

  3. 如果在對效能有苛刻要求的地方更新一大段 html ,推薦使用 innerHTML ,因為它在大部分的瀏覽器中都支行的更快,但在日常操作中它與原生方法沒有任何區別.

  4. HTML 集合是包含 DOM 節點引用的類陣列物件:

    1. document.getElementsByName()
    2. document.getElementsByClassName()
    3. document.getElementsByTagName()
    4. document.forms
    5. document.images
    6. document.links
    7. document.forms[0].elements
      HTML 集合一直與文件保持著連線,具有實時性,所以很影響效率.建議拷貝到普通陣列中,然後進行操作.
  5. 在現代瀏覽器中可以使用瀏覽器商提供的 API 來替代 DOM 屬性以獲取更高的效率.

瀏覽器商提供屬性 DOM 屬性
children childNodes
childrenElementCount childNodes.length
firstElementChild firstChild
lastElementChild lastChild
nextElementSibling nextSibling
previousElementSibling previousSibling

12. 獲取以下屬性或呼叫方法,會強制重新整理重排佇列並立即執行

  • offsetTop offsetLeft offsetWidth offsetHeight
  • scrollTop scrollLeft scrollWidth scrollHeight
  • clientTop clientLeft clientWidth clientHeight
  • getComputedStyle()

因為重繪和重排代價非常高,所以要減少修改次數.比較高效的操作是合併所有改變然後一次處理,如使用 cssText 屬性

el.style.cssText = 'width:200px;height:200px;'
  1. 要批量修改的時候,為了避免多次的重繪與重排,我們可以這麼操作

    1. 使元素脫離文件流
    2. 編輯修改
    3. 將元素放回文件流

    這樣做,有三種方案:
    1. 隱藏元素,應用修改,重新顯示

    display:'none' => // happychange// => display:'block'

    2. 使用文件片段, fragment 在當前文件外構建,再拷貝迴文檔
    3. 將元始元素拷貝到一個脫離文件的節點中,修改副本,完成之後再替換原始元素.

  2. 動畫操作時涉及到了大量樣式操作,會涉及很多重繪與重排,極大的浪費了計算資源,可以用以下步驟避免

    1. 使用絕對定位,使元素脫離文件流
    2. 動畫重繪,變更.因為這已經脫離了文件流了,只是小面積的重繪,不影響大部.
    3. 動畫結束之後恢復定位.
  3. 使用事件委託來減少事件處理器的數量.

  4. 迴圈速度的優化:

    1. 減少屬性查詢:

      for(let i=0,j=arr.length;i<j;i++){
          // code
      }
    2. 倒序操作:

      for(let i = arr.length;i--;){
          // code
      }
  5. 書上提到了達夫裝置,我試驗了一下,沒啥卵用.可以是我不會使用吧,總之別在那上面浪費時間了.