[HTML] 從CDN的引入位置 聊到CSS Render Blocking

realdennis
3 min readDec 14, 2018

--

如果有用過Bootstrap/FontAwesome都會發現引入CDN時,其實有分為加在<head>標籤裡頭的元素,或是<body>尾端的元素,為什麼不放在同個地方就好呢?

先針對<script>作回答

為了回答這個問題,我們必須要理解一件事,就是瀏覽器針對外部腳本的請求以及執行的時機,可以先看看這篇所提到的script標籤引入的機制。

於是我們可以開始勾引起了好奇心,究竟放哪裡有沒有差別?

Source: Bootstrap官方文檔

針對<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>中加入?

Fontawesome也會叫你把Link標籤丟到<head>裡頭

將CSS放在head最合理的解釋是:我們希望整個頁面在開始渲染的初期,所有的排版以及字體還有各種配置都已經被配置好。

但是,上述的美意需要犧牲停止一段時間的渲染而去付出網路請求。

只怕引入過多多餘的東西 卡死了渲染時間

CSS Render Blocking

許多人希望使用者能先看到些許內容,不至於太快選擇離開頁面時,就會開始嘗試各種lazy load的做法。

第一個嘗試,link標籤就算是在body是否會work?

我們發現FireFox跟Chrome是支援的(IE似乎不兼容),所以把link標籤放在body的第一個子元素,效果上是一樣的。

我們要知道link標籤並不存在async跟defer的屬性。

第二個嘗試,減緩Rendering Block的方法

目前link標籤有rel=”preload”可以使用,透過預加載器的方式,來優化解析延遲,再加上以下幾種方法。

以上討論的狀況都是based on HTML5

最後來考考各位,img加載圖片是否也會發生Render Blocking呢?

--

--

No responses yet