前端小誌(轉型中)

一個用來記錄人老會忘記的地方

Browser render & performance

2018年03月25日
原本要介紹javascript event loop的,寫一寫變成介紹browserXDD

有人問在處理器loading js會block render是為什麼,我知道js是single thread,但並不能確定是single thread的問題,於是乎一切要從browser講起。

modern browser通常是multi process的,自己認為最大的優點是

  • 避免一頁crash而導致整個browser crash
  • 避免插件crash而導致整個browser crash

而對於前端最重要的就是渲染進程(process),而一個process又可以分成multi thread,而渲染進程裡面擁有的重要thread

  • GUI
  • JS
  • Event
  • Timer
  • Http request

GUI與JS thread是戶斥的,因為當repaint的時候會觸發GUI thread,但JS執行後很有可能會造成多次repaint,於是乎JS在執行的時候會先block GUI thread,待JS結束後才換GUI thread。

所以如果在browser裡需要做密集運算可以使用web worker,browser會開一個子thread用來處理運算,但是不能操作dom,這是一個很酷的功能,目前的專案有地方可以優化的,只是browser的支援度還不夠所以放棄(IE 11 up...),希望未來有機會玩囉。

假設我們發送了一個http request,browser的行為大致如下

  1. Get content from http request
  2. Parse html and create dom tree (trigger DOMContentLoaded)
  3. Parse css and create render tree(with dom tree)
  4. (Layout/Reflow) the render tree
  5. Paint the render tree
  6. Composite & show on screen (trigger load)

RenderTree

原本我知道javascript要放在body之後或是寫上defer,這邊我才發現css也會block render(dom tree ok,但render tree不行),但是為了first time render,所以css一定要放在head,但如果很大要進行特殊處理,這邊有另一個領域叫critical render path(因為main css屬於critical但js不是,所以js可以慢load)。

(這就非常有趣了,首先我不知道webpack包裝成的SPA是怎麼處理css的,另外就是css in jsx,loader,styled-Component各會造成怎樣的效果。之後研究的目標之一)

composite是另一個很有趣的概念,首先要先了解render pipeline

render_pipeline

在前端的渲染機制是這樣

  • Javascript - trigger event
  • Style - css selector
  • Layout - calculate Layout
  • Paint - fill pixel
  • Composite - layer merge

只介紹後面三個,跟頁面排版有關的東西會重新計算(width, height, left...),此種行為觸發layout,跟繪制有關的觸發paint(color, border...),跟layer有關的觸發composite,這是一個pipeline,但不是每一個都要經過,經過越少step的效能越好。而通常在一個沒有特別設置的頁面只會有一個layer(或是browser預設的layer?待求證),但我們可以用tranform, translate 3d, will-change等去特別制造一個layer出來,最後composite的時候就會組合起來。所以就以純移動來講,使用tranform(Style -> Composite)比left(Style -> Layout -> Paint -> Composite)好,但實際使用一個頁面太多layer反而會降低效率,所以這又很吃應用場景。

當你修改了某些css的style,會產生不同的cost。這邊有份簡報,甚至你可以到css trigger查詢。

(這邊也非常有趣,沒有實際優化過,不過用過一兩次will-change)

PS. 其實大部份的概念來自這篇文章,建議好好的看過文章,因為我的版本省略了很多介紹XD

不過以上介紹的東西在現代的前端開發(SPA component...)還需要再釐清,很多都是3-4年前的推廣,像是css建議多用class而不要js控制,但jsx推崇css in js,另外在render部份使用vdom技術,加上使用webpack打包會不會已經不用關注某些問題值得再討論。


展開Disqus
分類
最近文章
友站連結
© 2019 Ernie Yang