reflow
也就是 重排或者回流
由DOM或者佈局的變動而觸發。
如你改變了一個div
的位置,或者是改變了這個div的width, height, position 或者佈局類的樣式。
利用display:none
不渲染的特點
通過一次完整的web請求和渲染過程以及如何優化網頁,我們可以知道頁面渲染的時候,會忽略掉display: none
這一類的不佔佈局的元素。
所以,我們可以將元素先display:none
,然後用JS對該元素進行操作。等操作完成在會後,再將它display:block
,這樣只會觸發2次的reflow
。
利用innerHTML
當然上述的寫法也可以利用innerHTML
進行修改。
const ul = document.getElementById('content')
const lists = ['a', 'b', 'c', 'd']
const childElementString = lists.map(list=>`<li>${list}</li>`).join('')
ul.innerHTML = ul.innerHTML + childElementString
複製程式碼
這裡只進行了一次reflow。
使用DocumentFragment
上面的寫法顯然不夠好,無法複用。我們可以使用DocumentFragment
進行優化。
DocumentFragments
是DOM節點,但不是DOM tree的一部分。它存在於記憶體
中,可以理解為虛擬DOM。
const parentNode = document.getElementById('content')
const lists = ['a', 'b', 'c', 'd']
const fragment = document.createDocumentFragment
lists.forEach(text=>{
const li = document.createElement('li')
li.textContent = text
fragment.appendChild(li)
})
parentNode.appendChild(fragment)
複製程式碼
如果不使用DocumentFragment的話,會造成4次reflow,隨著需要修改的dom次數變多,還會造成更多次的reflow,但是通過fragment,只需要一次就夠了。
CSS 層面的優化
我們上面說了,不只是DOM tree的改變會觸發reflow,CSSOM的改變同樣會觸發。 這裡我們可以用替代的CSS屬性替代會造成reflow的屬性。
相關文章: