有人問在處理器loading js會block render是為什麼,我知道js是single thread,但並不能確定是single thread的問題,於是乎一切要從browser講起。
modern browser通常是multi process的,自己認為最大的優點是
而對於前端最重要的就是渲染進程(process),而一個process又可以分成multi thread,而渲染進程裡面擁有的重要thread
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的行為大致如下
原本我知道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
在前端的渲染機制是這樣
只介紹後面三個,跟頁面排版有關的東西會重新計算(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打包會不會已經不用關注某些問題值得再討論。