本文不會介紹整個前端渲染過程的步驟,只是記錄最近閱讀的文章的些許思考和感悟。(文章地址一(系列),文章地址二)html
但願你們在閱讀這篇文章以前能將上述文章仔細瀏覽一篇,由於本文所述基本是基於其內容。前端
Navigation Timing API:可經過打印(performance)查看;git
瀏覽器加載事件:domContentLoaded,onloadgithub
上圖整理了Navigation Timing API中的一些事件和瀏覽器加載事件的發生順序。web
這些事件的含義是什麼呢?咱們直接引用文章地址一(系列)的介紹:chrome
domContentLoaded:表示 DOM 準備就緒而且沒有樣式表阻止 JavaScript 執行的時間點,這意味着如今咱們能夠構建渲染樹了。瀏覽器
看了上述事件的介紹,大體瞭解了每一個事件所表明的含義,但也帶着少量疑惑:框架
首先看第一個問題,咱們直接用chrome控制檯的performance來看效果。dom
上圖中,上方的Network的藍條是HTML的下載時間,下方箭頭所指是HTML的解析時間。async
從中咱們能夠得出HTML解析的確是分批進行,而且解析並不須要等HTML徹底下載完。那爲何要分批進行呢?這個問題我找了許多資料也沒有得出結論,因而本身從中思考。假設不是分批進行,那實現會有兩種狀況:1.等HTML所有下載完,再一塊兒解析;2.每下載必定量的HTML就將其放入解析器等待排隊解析。前者首先確定被排除,若HTML很大,會影響首屏加載速度,後者按理速度更快,或許其實現的難度以及可能會帶來的一些問題而沒有采用?這個問題思考了良久,感受從理論上是可行的,但從技術角度,因爲本身這方面的知識實在薄弱,因此也沒法得知其實現的過程是否存在技術瓶頸。
第二個問題:CSSOM樹構建是否在domContentLoaded事件以前?
話很少說咱們本身實踐。
首先我先建立一個HTML文件並寫入少量標籤,再建立一個CSS並於HTML引入,在CSS文件中寫入大量內容(本身實踐時寫了5W多行)。而後用performance查看。
上圖每一個箭頭表明的含義:
從這個步驟以及其所處時間,咱們能夠清晰的得出,該結論不許確。那麼該做者爲何會得出該結論呢,是他犯錯了嗎?我隨後發現他在這篇文章下面還寫了一句「domContentLoaded通常表示DOM和CSSOM均準備就緒的時間點」。那麼這句話意味着大部分的時候CSSOM樹的構建是在domContentLoaded事件以前。但是這個大部分又指的是什麼狀況,這又涉及到另外一個知識點「DOM樹,CSSOM樹,JS的三角關係」,構造DOM樹時碰見JS會先解析執行JS,而在解析執行JS時遇到CSSOM,又會先構造CSSOM樹,這個過程稍後會具體說明。那麼如今咱們能夠明白這個問題的關鍵所在了,由於在大部分頁面中是擁有JS的,而因爲其解析順序,那麼在domContentLoaded事件以前一定已經成功構造CSSOM樹。
第三個問題:domInteractive與domContentLoaded的區別是什麼呢?這兩個事件中間是否還會進行其餘操做?
咱們都知道script標籤有defer和async兩個屬性。有了這兩個屬性,瀏覽器就會加一個進程下載JS。那麼下載完的執行時間點是在何時?其中async會在JS下載完後立馬執行,也正是這個緣由,會致使JS的執行順序不必定按標籤的從上至下,而是按照下載完的時間。那麼defer屬性的執行時間呢,我想你們應該都能猜到了,它的執行時間點的確就是在上述的兩個事件之間,那麼咱們也就得知這兩個事件的區別所在。
咱們都知道前端渲染有三大樹:DOM樹,CSSOM樹,RENDER樹。那麼這三大樹的構造時間和上述的事件執行時間的順序又是怎樣的呢。
其中DOM樹和RENDER樹所在位置實際上是顯而易見的,而且在以前內容也已經指出。DOM樹在domInteractive事件以前,RENDER樹在domContentLoaded事件以後。可是CSSOM樹就難以捉摸,其與DOM樹的關係,徹底受到是否擁有JS影響。
在肯定CSSOM樹所處位置前,咱們先肯定一個上面提到的概念:構造DOM樹時碰見JS會先解析執行JS,而在解析執行JS時遇到CSSOM,又會先構造CSSOM樹。官方給出的緣由是,JS會使用document.write而改變DOM樹,因此構造DOM樹時碰到JS會先執行JS;而JS在執行時,須要查找CSS,因此執行JS時,碰到構造CSSOM樹,會先構造CSSOM樹。可是這裏有一點奇怪的時,JS也能夠經過創造Link標籤的方式改變CSSOM樹,因此我的感受官方的這種解釋有點牽強。不過官方的解釋雖然不能讓人徹底信服,但這執行順序是不會有錯的。
接下來咱們分別經過有無JS兩大類確認CSSOM樹所處位置:
可是有2個有意思的狀況:
(1) 若是咱們動態建立link標籤並添加到html中,那麼又會發生什麼呢?若JS還沒解析執行完,那麼會中止JS而去解析CSS,若JS已執行完那麼CSSOM樹其實也不是一定在domInteractive以前。(固然這可能已經不算初次渲染構建)
(2) link標籤放到JS後面又會發生什麼呢?這種狀況我發現無論我怎麼嘗試,CSSOM樹一定在DOM樹構建以前構建,但其又在JS執行完成後。若是有興趣的同窗能夠查查是爲何。
其實前端渲染是一個很龐大的知識點,而且其涉及的周邊知識也及其龐大,本文只是對其中一個小知識點作了思考和實踐。最後要說的一點是,以上內容,純屬我的看法,若有不當,請多指教。