你們好,林三心又來了。看了十幾遍
《康熙王朝》
和《雍正王朝》
,今天,就給你們講講「九龍奪嫡」
的那些事,順便講講瀏覽器渲染
(實際上是講瀏覽器渲染
,順便講講「九龍奪嫡」
,嘿嘿),以爲講得好記得給個贊
哦。css
畢竟,我也是一個有夢想的做者呢!html
請記住對應的關係哦,有利於後面更好地理解模塊之間的關係jquery
提及我們的康熙大帝啊,那可就牛逼了,擒鰲拜,平三番,遠征葛爾丹。可是也不耽誤他風流啊。「九子奪嫡」,說白了就是九個臭小子互相干架爭本身老子的皇位,那也怪不得這些臭小子啊,誰叫康熙大帝生那麼多呢?固然,九子中最突出的那幾個分別是大阿哥胤禔(HTML解析器),老三胤祉(繪圖模塊),老四胤禛(JS引擎),老八胤禩(CSS解析器),老十三(佈局Layout模塊)
webpack
HTML標籤
,順便解析內聯style標籤
裏的樣式,構建DOM樹
link
標籤裏的外聯漂亮樣式,構建CSS樹
樣式
和DOM節點
(增刪改查或者綁定事件)DOM樹
和CSS樹
合併,並製成一張佈局圖紙
(不負責渲染,只提供圖紙)圖紙
,並繪製
出來給大夥看看如下內容以前,你們要先明白一個道理:
解析
和渲染
是兩個過程,解析
了不必定會渲染
(也就是你還看不到頁面效果),渲染
了說明解析
完了,這就比如:你有了錢(解析
)不必定會去買別墅(渲染
),可是若是你買了別墅(渲染
)那說明你是真的有錢(解析
)web
<style>
// 6萬行css樣式
.box { background: red } // 最後一行
</style>
<div class="box"></div>
<div></div>
<div></div>
<div></div>
複製代碼
- 問: HTML解析器負責解析
HTML標籤
,順便解析內聯style標籤
裏的樣式,那麼問題來了:style標籤裏有6萬多行樣式,會由於解析得太慢,而致使後面的div標籤都沒法解析而且渲染嗎?
- 答:
不會
,HTML解析器是異步解析
的,而且不
阻塞渲染
。大阿哥(HTML解析器)從上往下走,碰到了style標籤,發現裏面實在是太多樣式了,判斷須要解析好久,便派了四個小兵,先去解析下面的四個div標籤並先渲染出來,提升效率。
- 形成的問題: 因爲style裏太多樣式,因此小兵們解析渲染div標籤完,大阿哥卻還未解析完style裏的樣式,因此class="box"的div標籤先渲染出來(無樣式),等大阿哥解析完style標籤,纔會把.box的樣式賦給這個渲染出來的div標籤,這就致使了這個div標籤在頁面上出現了
無樣式 -> 有樣式
的效果,也就是所謂的閃屏現象
- 如何解決問題: 少用style內聯標籤,大阿哥要帶兵解析HTML已經夠累了,你還讓他去解析style標籤,不形成'閃屏現象'纔怪
// index.css裏
// 6萬行css樣式
.box { background: red } // 最後一行
// html代碼
<link href="index.css"></link> // 引入 <div class="box"></div>
<div></div>
<div></div>
<div></div>
複製代碼
- 問: CSS解析器負責解析
link
標籤裏的外聯樣式,那麼問題來了:link標籤外聯樣式有6萬多行,會由於解析得太慢,而致使後面的div標籤都沒法解析而且渲染嗎?
- 答:
不會
阻塞後面div標籤的解析
,可是會
阻塞後邊div標籤的渲染
,也就是說,CSS解析器
在解析link標籤裏這6萬行樣式的同時,HTML解析器
已經帶了幾個小兵去把下面的div標籤全解析了,但只是解析了,並未渲染出來,等到CSS解析器
把6萬行樣式解析完,再一次性合併CSS樹
和DOM樹
並渲染到頁面上去
- 爲何: 由於這麼作能夠避免
閃屏現象
並提升渲染性能
。上面說了閃屏現象
就是頁面上出現了無樣式 -> 有樣式
的效果,體驗不好,因此如何避免呢?最好的辦法就是等到最終的DOM樹
與最終的CSS樹
結合完,再一次性渲染上去,這樣頁面就不會出現無樣式 -> 有樣式
這樣的問題了。屢次的渲染如今變成了一次性渲染,那天然是提升了渲染的性能。
- 形成的問題: 若是CSS解析器解析的太慢,那麼頁面就一直沒法完成最終渲染,也就會出現一小段時間
白屏現象
- 如何解決問題: 核心就是加快外聯樣式的加載速度:
- 使用CDN節點進行外部資源加速
- 對外部樣式文件進行壓縮(使用打包工具,例如webpack,gulp等)
- 優化你的樣式文件的代碼
// index.js文件
// 6萬多行代碼,對dom進行了一系列操做
// html頁面
<script src="index.js"></script> // 引入 <div id="box"></div>
<div></div>
<div></div>
<div></div>
複製代碼
- 問: JS引擎暗地裏操縱各類
樣式
和DOM節點
(增刪改查或者綁定事件),會由於執行script標籤的引用代碼太慢,而致使後面的div標籤都沒法解析而且渲染嗎?
- 答:
會
阻塞後面div標籤的解析和渲染,等到JS引擎
把全部JS代碼加載
並執行
完成,纔會放HTML解析器
往下解析DOM,而且一次性渲染出來
- 爲何: 舉個反例,在四阿哥(JS引擎)緩慢地執行這6萬行代碼同時,康熙命令大阿哥(HTML解析器)不要管四阿哥,大膽地往下解析HTML,大阿哥立刻帶着本身的小兵們立刻解析完全部div標籤,而後滿懷成就感地想跑去康熙面前請功領賞,而此時四阿哥還未執行完他的JS代碼,大阿哥跑啊跑啊,跑到康熙面前的一瞬間,四阿哥恰好執行完JS代碼,並把大阿哥剛剛解析完的全部標籤都刪了(畢竟四阿哥擁有操控DOM的能力啊),康熙一看,雷霆大怒:「WDNMD!!!老大,你不是說都解析好了嗎?在哪呢??敢騙老子?」對着大阿哥一頓臭罵。大阿哥心想:「老四,WDNMD,敢把老子解析的成功給刪了!」後來康熙得知後,便制定了一套規則:之後四阿哥先執行代碼,而後再派大阿哥去解析HTML,這樣大阿哥就不會作無用功啦!
- 問題: 若是JS代碼執行報錯或者執行過慢,那麼後面的HTML就會永遠沒法解析了,那麼頁面有可能就一直是一片空白。
- 如何解決問題: 核心就是改變JS代碼的執行順序,或者優化JS執行速度:
<script async></script>
加上async
屬性,JS代碼會異步加載並執行(多script標籤狀況下,並不會按着script在頁面中的順序來執行,而是誰先加載完誰執行)<script defer></script>
加上defer
屬性,JS代碼會異步加載(若是有多個設置了defer的script標籤存在,則會按照順序執行全部的script,會在DOMCotentLoaded
前執行)- 把script標籤放在頁面尾部
- 優化JS代碼,加快執行速度
跟上面
HTML解析器和JS引擎
同理,只不過是DOM樹
和CSS樹
的區別gulp
<script src="jquery.js"></script>
<script src="bootstrap.js"></script>
複製代碼
會先執行完上邊script再執行下邊script,由於有可能下邊的script依賴於上邊的script代碼(上方例子,bootstrap依賴於jquery)bootstrap
<script src="index1.js"></script>
<script src="index2.js"></script>
<div></div>
複製代碼
會先執行完上邊script再執行下邊script,由於上方script可能修改dom,下方也修改dom,那確定是排隊一個一個來,否則就亂套了瀏覽器
<script src="index1.js" defer></script>
<script src="index2.js" defer></script>
複製代碼
會異步加載,也就是下方可能比上方加載更快,可是最終代碼執行仍是會按順序由上往下,而且在DOMContentLoaded以前執行markdown
<script src="index1.js" async></script>
<script src="index2.js" async></script>
複製代碼
會異步加載並異步執行,也就是誰先加載完誰就先執行,不按順序app
問:爲何CSS解析器只能阻塞HTML渲染但不能阻塞HTML解析,但JS引擎卻能同時阻塞HTML的解析和渲染呢?
答:由於CSS並不能操做DOM啊,因此也不必阻塞HTML解析。可是JS引擎就不同了,能隨意操做DOM,因此須要阻塞HTML解析,避免HTML解析器作無用功。
再來看看渲染大體過程:
DOMContentLoaded
發生在這onload
發生在這
JavaScript
是瀏覽器中運行的大腦,最能獲得瀏覽器(康熙)青睞的確定是JavaScript(四阿哥),因此最後確定是四阿哥胤禛
勝出啦,恭喜雍正帝
!
雍正也是我很喜歡的一位,
推行新政
,火耗歸公
,攤丁入畝
,士紳一體當差一體納糧
,派年羹堯平定羅布贊旦增阿拉布坦叛亂
等等,都很出色!
感興趣的能夠去看看
《雍正王朝》
,和《大明王朝》
並列爲中國古裝劇的巔峯之做!