參考 高性能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的變化影響了元素的幾何屬性(寬高)的時候,這樣瀏覽器就會從新計算元素的幾何尺寸,其餘元素的幾何尺寸也會受到相應的影響,瀏覽器會使渲染樹中受到影響的部分失效並從新構造渲染樹,這個過程叫作重排,完成重排後瀏覽器從新繪製受到影響的部分,這個過程就叫作重繪
重繪和重排都是代價昂貴的操做,因此優化的方案是最小化重繪和重排
重排發生的時機
瀏覽器會優化重排的過程,經過隊列的方式修改並批量的執行重拍的過程,可是當咱們使用一些屬性或者方法的時候,會強制的刷新渲染隊列觸發重排,當咱們頻繁的進行這些操做的時候,就會形成性能的開銷
優化的思路:
(1)集中操做 將設置樣式和獲取樣式進行分離(不要在佈局信息改變的時候去進行查詢操做),而且儘量的合併操做
var el = document.getElementById("test"); el.style.cssText = "border-left:1px;border-right:2px;border-bottom:3px;";
(2)批量的修改DOM的時候,能夠經過下面的方式減小重繪與重排
脫離文檔流的方案
(3)緩存佈局信息 這個思路有點像處理集合元素的時候的方案,經過緩存局部的佈局信息,能減小強制刷新渲染隊列的次數,也就減小了重排
(4)動畫元素的處理 其實思路是同樣的 動畫有可能會形成大量其餘元素位置改變,當動畫開始的時候,讓它脫離文檔流,進行動畫的展現,動畫完結後讓它回到文檔流