Re: [問題] 把CSS或JS的import放在html最後端?

看板Web_Design作者 (老子我最神)時間9年前 (2014/12/29 00:35), 9年前編輯推噓6(6080)
留言86則, 7人參與, 最新討論串2/3 (看更多)
: -- : ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.193.192.133 : ※ 文章網址: http://www.ptt.cc/bbs/Web_Design/M.1419765939.A.5D1.html : 推 GoalBased: 我只聽過JS放到尾端 沒聽過CSS 12/28 20:09 : → mmis1000: 照google的建議是,很重要的css放頭或內嵌,不重要的放 12/28 21:15 : → mmis1000: 尾部 12/28 21:15 : → cyclone350: 可以給參考網址嗎? 我從教學的理解,CSS是要放前面的 12/28 22:27 : → mmis1000: http://goo.gl/fj76zO 12/28 23:09 無法理解mmis1000提供網址的建議... 我看到的教學文章是說 瀏覽器會建立 DOM model tree 及 CSS model tree 而瀏覽器的畫面 Render tree 則需要上面兩個 tree 才能實現 所以先有 DOM model tree 是沒有畫面的 必須等到 CSS model tree 建立完後才可以做 render 在我的實測結果裡面,若將 CSS 放到最後面,並且讓 download 時間變為5秒 我的 html 是在 5 秒後才會呈現畫面... 也就是實測結果放前後的效果是一樣的 不管他是不是 small.css , 瀏覽器仍必須將他載下來建立成 CSS modell tree 後 才會進行 Render 而CSS 放在前面的好處在以下網頁有進行說明 http://ithelp.ithome.com.tw/question/10156492 而且 http://goo.gl/fj76zO 教學本身的網頁 html 讀取時間明顯多於 css 下載時間 可是頁面原始碼 css 仍然是放在網頁前端(head 裡面)... 最後我用 Chrome 的 time line 檢查讀取的順序及時間 發現不管 css 放前還是放後, chrome 都會優先讀取 html 本身,讀取完之後 才會開始下載 css css 放前面放後面真的有差嗎? -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.193.192.133 ※ 文章網址: http://www.ptt.cc/bbs/Web_Design/M.1419784509.A.C4C.html

12/29 08:40, , 1F
我沒有研究過這個,不過就推理(XD)的角度而言
12/29 08:40, 1F

12/29 08:41, , 2F
html和css應該要都載完才有辦法render
12/29 08:41, 2F

12/29 08:41, , 3F
不然你先render html 在畫面上,之後加上css屬性
12/29 08:41, 3F

12/29 08:41, , 4F
那不就會看到兩種畫面嗎,一開始的一閃而過接下來是有
12/29 08:41, 4F

12/29 08:42, , 5F
css的,以上純屬個人推測,所以我上一篇有說聽過js
12/29 08:42, 5F

12/29 08:42, , 6F
放底端沒聽過css,不過asp.net mvc的範例似乎也有把css
12/29 08:42, 6F

12/29 08:43, , 7F
放尾端的狀況出現 whatever..
12/29 08:43, 7F

12/29 08:49, , 8F
其實我看好色龍的網誌,的確是會先閃過無CSS排版的畫面
12/29 08:49, 8F

12/29 09:11, , 9F
的確有一些網頁會這樣..
12/29 09:11, 9F

12/29 09:14, , 10F
看了一下GOOGLE首頁,也是有些css放前面有些放後
12/29 09:14, 10F

12/29 09:14, , 11F
詳細的就需要再研究了
12/29 09:14, 11F

12/29 09:16, , 12F
以APPLE來講則是放在前面
12/29 09:16, 12F

12/29 12:01, , 13F
Google的建議就是把畫面外的css塞尾端啊,這樣就算閃動
12/29 12:01, 13F

12/29 12:01, , 14F
也沒差,反正你又看不到,而且能更早產生第一個畫面,不
12/29 12:01, 14F

12/29 12:01, , 15F
會轉圈圈轉很久
12/29 12:01, 15F

12/29 12:17, , 16F
目前大部分瀏覽器都是 連線需要的時間 > 載入需要的時間
12/29 12:17, 16F

12/29 12:18, , 17F
> 重建render tree所需要的時間,多花一點時間重跑畫面
12/29 12:18, 17F

12/29 12:18, , 18F
很划算啊?
12/29 12:18, 18F

12/29 12:20, , 19F
就像你用jquryui做dialog,等他載入完再產生畫面根本沒
12/29 12:20, 19F

12/29 12:21, , 20F
意義,因為第一個畫面又沒dialog
12/29 12:21, 20F

12/29 12:22, , 21F
所以重點在於 "畫面外"
12/29 12:22, 21F
原作者回應: 您好。 概念是這樣的:當我們打開瀏覽器瀏覽一個網頁時,瀏覽器第一件事就是抓 HTML Document 。抓完 HTML Document 後,瀏覽器就會開始進行解析的動作,當讀到 外連 CSS or JS 的 tag 時,瀏覽器就會去抓這些外連的檔案。 因此如果你把 CSS 放在最後,瀏覽器越晚讀到,自然會越慢開始下載而引響到 CSSOM 的 建構,最後就會導致整體 Render Tree 建構的速度 delay。 至於你給的連結當中,有人貼了一個 Google 的建議,根據我的理解,它想強調的重點是 :把至關重要的 CSS 直接嵌入 HTML ,你可以看到它下面的 small.css 中放的內容對於 那一個 HTML 完全沒有任何作用。不過我不知道實際開發網站的時候,是否會有人這樣做 ,畢竟如果這個頁面不會用到的話,就沒必要再讓使用者花費頻寬去抓不必要的檔案。 ======================================================================= 關鍵在於一個概念 瀏覽器會先建構 DOM 及 CSSOM,都完成後才會執行 render 而我嘗試過後,故意讓 CSS 放最後且 download 時間改為五秒 這五秒內完全沒有任何 DOM 物件出來,五秒過後... html 才開始顯示 所以不論是畫面外,還是畫面內,都必須先建立全部的 CSSOM 之後才會開始 render 另外跟 Js 應該沒啥關係,因為是 render 完之後,才會執行 document.ready 所以若 js 執行速度較慢的話,如使用 jquery UI 就可能先看到普通的 Button 當執行到 $("button").button() 之後,才會看到美美的 button 可是就 google 的建議看來,與這個概念是相衝突的,有幾種可能 1. 原作者錯了,瀏覽器根本不是等到 DOM 與 CSSOM 全部建立後才開始 render 2. 原作者是對的,我們誤會 google 的意思了,google 是強調 inline CSS 3. 其他... by the way... 剛剛去看 google 首頁... google 並沒有把 external css 放在 html 後面... 不過卻用了 inline CSS... 另外有些 CSS 放在 整個 html 的中間,不過只有 在 CSS 下方html才會 用到 CSS 的 class 還沒有看到 CSS 是放在下方的 例 ... .axxx {...} ... <p class="axx"> ... .gsss {...} ... <div class="gsss"> ※ 編輯: cyclone350 (123.193.192.133), 12/29/2014 20:24:32

12/29 20:46, , 22F
怎麼可能沒關係...jquery ui的css九成以上在第一個畫面
12/29 20:46, 22F

12/29 20:47, , 23F
都不會用到的...但提前載入卻會bloack住整個畫面
12/29 20:47, 23F

12/29 20:50, , 24F
像是datapicker之類的,一開始都不會用到
12/29 20:50, 24F

12/29 20:51, , 25F
google的意思是 把雖然會用到,但不再第一個畫面裡的css
12/29 20:51, 25F

12/29 20:52, , 26F
放後面,或用headjs之類的塞進onload裡延後讀取
12/29 20:52, 26F

12/29 21:11, , 27F
mmis 我懂你要表達的意思,但是教學的理論是必須整個
12/29 21:11, 27F

12/29 21:12, , 28F
CSS 及 DOM 讀完才可以 render, 而你卻的意思是讀到
12/29 21:12, 28F

12/29 21:12, , 29F
後就馬上可以做render了
12/29 21:12, 29F

12/29 21:14, , 30F
實作問題,至少ff是可以在全部資源讀完前部分輸出的
12/29 21:14, 30F

12/29 21:14, , 31F
而我的實驗是不論在前面或在後面都會 block 住...
12/29 21:14, 31F

12/29 21:15, , 32F
恩,我測測看 FF
12/29 21:15, 32F

12/29 21:15, , 33F
fb也用了類似的trick來部分輸出,在第一個畫面只載入最
12/29 21:15, 33F

12/29 21:16, , 34F
少量資源,後面其他的再用js讀取
12/29 21:16, 34F

12/29 21:16, , 35F
好像是叫 bigpipe 的方法
12/29 21:16, 35F

12/29 21:19, , 36F
我對 js 動態載入是沒有疑問的
12/29 21:19, 36F

12/29 22:00, , 37F
無法... 我的實驗是無法部分輸出的,還是有任何方式
12/29 22:00, 37F

12/29 22:01, , 38F
可以佐證瀏覽器可以部份輸出或是CSS放最後面會影響
12/29 22:01, 38F

12/29 22:02, , 39F
效能的文章? 或是哪一個有名的網站會把CSS放最後面?
12/29 22:02, 39F

12/29 22:08, , 40F
開台南市公車動態的網頁看看就知道了
12/29 22:08, 40F
http://www.wfublog.com/2014/10/javascript-css-location-performance.html 我 google web效能調教,對於 css 真的都是放前面, js 放後面 另外 http://2384.tainan.gov.tw/TNWeb/Index.jsp?locale=zh_TW&agis=Yes 很明顯是 render tree 在畫阿... 他並不是一個 DOM 畫完成一個醜醜圖形後 再套入 CSS 變美美的圖形 否則不會最一開始是樣板先出來,之後才是內容 ※ 編輯: cyclone350 (123.193.192.133), 12/29/2014 22:17:46

12/30 00:54, , 41F
http://goo.gl/Ny5tLc 開chrome,trolttoe選最慢的
12/30 00:54, 41F

12/30 00:54, , 42F
你會發現render沒有被jqueryui放最下面的css擋住
12/30 00:54, 42F

12/30 00:56, , 43F
照你的講法,就算放最下面也會擋住畫面輸出,但並不是
12/30 00:56, 43F

12/30 00:58, , 44F
而是在它上面的screen.css讀完就輸出了
12/30 00:58, 44F

12/30 00:58, , 45F
不管怎麼樣..以chrome做法是,不論dom有沒有loading完
12/30 00:58, 45F

12/30 00:59, , 46F
上面的渲染樣式 Chrome會按照CSS+Dom的狀況才會做渲染
12/30 00:59, 46F

12/30 01:00, , 47F
然後再怎麼快都沒用,大部份卡在你的file 跟 domain name
12/30 01:00, 47F

12/30 01:00, , 48F
跟你那台server的位置決定大部份的速度
12/30 01:00, 48F

12/30 01:04, , 49F
為了特定瀏覽器做了太多優化沒啥用,忘記真正的問題才可怕
12/30 01:04, 49F

12/30 01:07, , 50F
然後,你可以利用css backgroundimage 或 js的new Image
12/30 01:07, 50F

12/30 01:07, , 51F
來做 image buffer,讓其它頁面會需要的影像事先載入
12/30 01:07, 51F

12/30 01:07, , 52F
使用者在換一下個頁面時,他就不用再等待下載圖片了
12/30 01:07, 52F

12/30 01:08, , 53F
適用於一些會有換圖轉場、大型圖片檔案
12/30 01:08, 53F

12/30 01:08, , 54F
順便一提,CSS background image 做 buffer 蠻簡單的
12/30 01:08, 54F

12/30 01:08, , 55F
你可以把一個看不到的元素或超級迷你的div加入一組class
12/30 01:08, 55F

12/30 01:09, , 56F
這組class有你設定好的背景圖片
12/30 01:09, 56F

12/30 01:09, , 57F
最好那塊是在網頁上看不到
12/30 01:09, 57F

12/30 01:10, , 58F
然後把那組class擺在最後,而tag的部分也是擺在最後
12/30 01:10, 58F

12/30 01:10, , 59F
當系統載入差不多的時候,那塊部分就會被載入
12/30 01:10, 59F

12/30 01:10, , 60F
因為排版引擎從dom+css的樣式規則發現這個class有被使用
12/30 01:10, 60F

12/30 01:11, , 61F
於是他就開始載入/設定你那組元素的樣式,有檔案也會下載
12/30 01:11, 61F

12/30 01:12, , 62F
若只有單純在css裡面定義,排版引擎不會去碰那裡面的樣式
12/30 01:12, 62F

12/30 01:14, , 63F
最後我想說的是,不管放在上面還是下面,或者是外部載入
12/30 01:14, 63F

12/30 01:14, , 64F
或者是直接放在裡面,都有他的用意跟適合的情況
12/30 01:14, 64F

12/30 01:15, , 65F
各有優點及缺點,沒有特別王道
12/30 01:15, 65F

12/30 01:15, , 66F
在我看來,他對 ie,ff,chrome 都有效就有使用價值了
12/30 01:15, 66F

12/30 01:16, , 67F
要調校請以你那個網站的主使用者用的瀏覽器下去調
12/30 01:16, 67F

12/30 01:16, , 68F
而且就算沒效你也沒損失阿
12/30 01:16, 68F

12/30 01:16, , 69F
IE、Firefox、Chrome 都有開發者工具,追一下Network
12/30 01:16, 69F

12/30 01:16, , 70F
的Timeline有沒有用
12/30 01:16, 70F

12/30 01:20, , 71F
都有效歐...而且剛剛的回答就是追timeline的結果
12/30 01:20, 71F

12/30 01:28, , 72F
是throttle成 5kb/s 的速度測的
12/30 01:28, 72F

12/30 07:26, , 73F
推a大background image舉例 很棒很實用
12/30 07:26, 73F

12/31 01:49, , 74F
來個小測試吧,這是一個簡單的網頁,含有一個延遲很大的
12/31 01:49, 74F

12/31 01:49, , 75F
css檔案,只是一個放頭,一個放尾
12/31 01:49, 75F

12/31 01:49, , 76F

12/31 01:50, , 77F

12/31 01:50, , 78F

12/31 02:04, , 79F
假設說這個css沒內容還是會擋住嗎?
12/31 02:04, 79F

12/31 02:04, , 80F

12/31 02:04, , 81F

12/31 15:52, , 82F
實測結果如果FX會讓HTML先出來再上CSS
12/31 15:52, 82F

12/31 15:53, , 83F
但是Chrome 會等CSS抓完再讓整個畫面一起出來
12/31 15:53, 83F


12/31 16:57, , 85F
事實上chrome也會,但限transfer-encoding:chunked的網
12/31 16:57, 85F

12/31 16:57, , 86F
12/31 16:57, 86F
看到效果了,感謝這麼熱心的測試網址,我把結果PO出來 1. 電腦版 Chrome : 無效果,必須等CSS載完後才會顯示頁面 2. 手機版 Chrome : 有效果,會先顯示 BODY 內容後,再畫出紅色背景 3. Firefox:有效果,會先顯示 BODY 內容後,再畫出紅色背景 4. IE11:有效果,會先顯示 BODY 內容後,再畫出紅色背景 看來目前只有 Chrome 符合教學網址的建議,會全部讀完才 render 非 google chrome 的瀏覽器則符合 google 的建議... ※ 編輯: cyclone350 (123.193.192.133), 12/31/2014 23:48:43
文章代碼(AID): #1Ke34znC (Web_Design)
文章代碼(AID): #1Ke34znC (Web_Design)