[HTML] 從CDN的引入位置 聊到CSS Render Blocking
如果有用過Bootstrap/FontAwesome都會發現引入CDN時,其實有分為加在<head>標籤裡頭的元素,或是<body>尾端的元素,為什麼不放在同個地方就好呢?
先針對<script>作回答
為了回答這個問題,我們必須要理解一件事,就是瀏覽器針對外部腳本的請求以及執行的時機,可以先看看這篇所提到的script標籤引入的機制。
於是我們可以開始勾引起了好奇心,究竟放哪裡有沒有差別?
針對<script>的位置以及就剛剛的連結作為回答,其實只要做到標記defer屬性後,不管放在什麼地方,執行順序都會固定,如同放在</body>之前。
- 不是每個User都在使用新穎的瀏覽器,還有舊型的專案也許是建立在HTML4上頭。
- Inline-script無法控制defer&async,那就只能在確定CDN請求回應並執行後,才能使用3rd的API。
- 意味著需要3rd的函數,必須在DOMContentLoaded事件觸發之後才能使用,沒有辦法單純的在cdn的element 下頭加入<script>後開始撰寫。
使用針對類似jquery等等的外部引入,放在<body>標籤的尾端已經有一個很好的解釋了。
如果將腳本放在head,那麼必然會因為載入jquery/popper/bootstrap腳本而blocking住整個頁面渲染。(Render Blocking JavaScript)
於是,我們產生了第二個讓人好奇的事情 。
CSS為什麼總是在<head>中加入?
將CSS放在head最合理的解釋是:我們希望整個頁面在開始渲染的初期,所有的排版以及字體還有各種配置都已經被配置好。
但是,上述的美意需要犧牲停止一段時間的渲染而去付出網路請求。
CSS Render Blocking
許多人希望使用者能先看到些許內容,不至於太快選擇離開頁面時,就會開始嘗試各種lazy load的做法。
第一個嘗試,link標籤就算是在body是否會work?
我們發現FireFox跟Chrome是支援的(IE似乎不兼容),所以把link標籤放在body的第一個子元素,效果上是一樣的。
我們要知道link標籤並不存在async跟defer的屬性。
第二個嘗試,減緩Rendering Block的方法
目前link標籤有rel=”preload”可以使用,透過預加載器的方式,來優化解析延遲,再加上以下幾種方法。
- 載入後 JS createElement&append 大法
- 更多的rendering blocking探討
以上討論的狀況都是based on HTML5
最後來考考各位,img加載圖片是否也會發生Render Blocking呢?