在編寫頁面中,咱們要知道瀏覽器如何處理 HTML
、JavaScript
和 CSS
。
須要瞭解並注意五個主要區域, 這些咱們擁有控制權的部分,也是像素至屏幕管道中的關鍵點。css
ps: 固然,不是每一步更改都會遵循上圖這個流程。前端
好比:git
width
, height
, 位置
... 那麼瀏覽器就會檢查其餘元素,自動 重排一次
。color
, 陰影
... 不會影響頁面的佈局,那麼瀏覽器就會跳過佈局。這就是咱們日常說的:重排必定引發重繪,重繪不必定引發重排
。使用 csstriggers 能夠詳細看到 css 屬性改變時觸發的流程。github
舉個🌰:web
<div class="box box1">1</div> <div class="box box2"> 2 </div> <script> const box1 = document.querySelector('.box1'); setTimeout(() => { box1.style.display = 'none' }, 3000); </script>
咱們能夠看到,box1
和 box2
都綠(重繪)了一次,說明 box1
的變化影響了 box2
。那這個屬性變化的代價是比較大的。瀏覽器
假如是我讓 box1
的位置 向右移動 60px
,咱們作以下更改:性能優化
box1.style.display = 'none'
如今 box2
的位置不受影響,直觀地看到 box2
是沒被綠(重繪)的。微信
咱們在上一步作了優化,box2
已經不受影響,可是 box1
依然被重繪,那能不能在優化呢。
答案是能的。
left 這個屬性的改變會形成的影響是:前端性能
layout -> painted -> composited
這個流程能夠在 csstriggers 看到。
那如今咱們要找到一個 css 屬性,既能讓元素位移,又能形成的影響最小。
答案是有的:transform
:影響最小,直接到達最後一步 compositor。
作以下更改:ide
box1.style.transform = 'translateX(60px)'
好像事與願違。box1
, box2
都被重繪了。
這裏由於:他們都在一個層上,一個元素的變化也影響了其餘元素的變化。瀏覽器會聯合須要繪製的區域,而致使整個屏幕重繪
其實這裏有個條件:更改屬性所在的元素應處於其自身的合成層,若是沒在,咱們能夠提高爲合成層
這樣就不會影響其餘元素,而能減小繪製區域。
這裏我大概羅列了這麼多
在 box1
上面作以下更改:
will-change: transform;
再次觀察效果:
大功告成:
咱們能夠查看最終的分層效果:
和 ps
裏面的圖層差很少,每個圖層疊加在一塊兒組成咱們看到的網頁。
圖層越多越好嗎?
固然不是。提高合成層也得 消耗額外的內存和管理資源
正如MDN所說:若是你的頁面在性能方面沒什麼問題,則不要添加 will-change 屬性來榨取一丁點的速度。 will-change 的設計初衷是做爲最後的優化手段,用來嘗試解決現有的性能問題
前端性能優化之 Composite
關鍵轉譯路徑 Critical Rendering Path
will-change
堅持僅合成器的屬性和管理層計數
若是喜歡本篇文章,能夠關注的微信公衆號,若是不嫌煩,還能夠把它添加到桌面😀。