作者cyclone350 (老子我最神)
看板Web_Design
标题Re: [问题] 把CSS或JS的import放在html最後端?
时间Mon Dec 29 00:35:05 2014
: --
:
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 123.193.192.133
: ※ 文章网址: http://webptt.com/cn.aspx?n=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://webptt.com/cn.aspx?n=bbs/Web_Design/M.1419784509.A.C4C.html
1F:推 GoalBased: 我没有研究过这个,不过就推理(XD)的角度而言 12/29 08:40
2F:→ GoalBased: html和css应该要都载完才有办法render 12/29 08:41
3F:→ GoalBased: 不然你先render html 在画面上,之後加上css属性 12/29 08:41
4F:→ GoalBased: 那不就会看到两种画面吗,一开始的一闪而过接下来是有 12/29 08:41
5F:→ GoalBased: css的,以上纯属个人推测,所以我上一篇有说听过js 12/29 08:42
6F:→ GoalBased: 放底端没听过css,不过asp.net mvc的范例似乎也有把css 12/29 08:42
7F:→ GoalBased: 放尾端的状况出现 whatever.. 12/29 08:43
8F:推 Peruheru: 其实我看好色龙的网志,的确是会先闪过无CSS排版的画面 12/29 08:49
9F:推 GoalBased: 的确有一些网页会这样.. 12/29 09:11
10F:→ GoalBased: 看了一下GOOGLE首页,也是有些css放前面有些放後 12/29 09:14
11F:→ GoalBased: 详细的就需要再研究了 12/29 09:14
12F:→ GoalBased: 以APPLE来讲则是放在前面 12/29 09:16
13F:推 mmis1000: Google的建议就是把画面外的css塞尾端啊,这样就算闪动 12/29 12:01
14F:→ mmis1000: 也没差,反正你又看不到,而且能更早产生第一个画面,不 12/29 12:01
15F:→ mmis1000: 会转圈圈转很久 12/29 12:01
16F:→ mmis1000: 目前大部分浏览器都是 连线需要的时间 > 载入需要的时间 12/29 12:17
17F:→ mmis1000: > 重建render tree所需要的时间,多花一点时间重跑画面 12/29 12:18
18F:→ mmis1000: 很划算啊? 12/29 12:18
19F:→ mmis1000: 就像你用jquryui做dialog,等他载入完再产生画面根本没 12/29 12:20
20F:→ mmis1000: 意义,因为第一个画面又没dialog 12/29 12:21
21F:推 GoalBased: 所以重点在於 "画面外" 12/29 12:22
原作者回应:
您好。
概念是这样的:当我们打开浏览器浏览一个网页时,浏览器第一件事就是抓 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
22F:→ mmis1000: 怎麽可能没关系...jquery ui的css九成以上在第一个画面 12/29 20:46
23F:→ mmis1000: 都不会用到的...但提前载入却会bloack住整个画面 12/29 20:47
24F:→ mmis1000: 像是datapicker之类的,一开始都不会用到 12/29 20:50
25F:→ mmis1000: google的意思是 把虽然会用到,但不再第一个画面里的css 12/29 20:51
26F:→ mmis1000: 放後面,或用headjs之类的塞进onload里延後读取 12/29 20:52
27F:→ cyclone350: mmis 我懂你要表达的意思,但是教学的理论是必须整个 12/29 21:11
28F:→ cyclone350: CSS 及 DOM 读完才可以 render, 而你却的意思是读到 12/29 21:12
29F:→ cyclone350: 後就马上可以做render了 12/29 21:12
30F:→ mmis1000: 实作问题,至少ff是可以在全部资源读完前部分输出的 12/29 21:14
31F:→ cyclone350: 而我的实验是不论在前面或在後面都会 block 住... 12/29 21:14
32F:→ cyclone350: 恩,我测测看 FF 12/29 21:15
33F:→ mmis1000: fb也用了类似的trick来部分输出,在第一个画面只载入最 12/29 21:15
34F:→ mmis1000: 少量资源,後面其他的再用js读取 12/29 21:16
35F:→ mmis1000: 好像是叫 bigpipe 的方法 12/29 21:16
36F:→ cyclone350: 我对 js 动态载入是没有疑问的 12/29 21:19
37F:→ cyclone350: 无法... 我的实验是无法部分输出的,还是有任何方式 12/29 22:00
38F:→ cyclone350: 可以佐证浏览器可以部份输出或是CSS放最後面会影响 12/29 22:01
39F:→ cyclone350: 效能的文章? 或是哪一个有名的网站会把CSS放最後面? 12/29 22:02
40F:→ mmis1000: 开台南市公车动态的网页看看就知道了 12/29 22:08
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
42F:→ mmis1000: 你会发现render没有被jqueryui放最下面的css挡住 12/30 00:54
43F:→ mmis1000: 照你的讲法,就算放最下面也会挡住画面输出,但并不是 12/30 00:56
44F:→ mmis1000: 而是在它上面的screen.css读完就输出了 12/30 00:58
45F:→ alog: 不管怎麽样..以chrome做法是,不论dom有没有loading完 12/30 00:58
46F:→ alog: 上面的渲染样式 Chrome会按照CSS+Dom的状况才会做渲染 12/30 00:59
47F:→ alog: 然後再怎麽快都没用,大部份卡在你的file 跟 domain name 12/30 01:00
48F:→ alog: 跟你那台server的位置决定大部份的速度 12/30 01:00
49F:→ alog: 为了特定浏览器做了太多优化没啥用,忘记真正的问题才可怕 12/30 01:04
50F:→ alog: 然後,你可以利用css backgroundimage 或 js的new Image 12/30 01:07
51F:→ alog: 来做 image buffer,让其它页面会需要的影像事先载入 12/30 01:07
52F:→ alog: 使用者在换一下个页面时,他就不用再等待下载图片了 12/30 01:07
53F:→ alog: 适用於一些会有换图转场、大型图片档案 12/30 01:08
54F:→ alog: 顺便一提,CSS background image 做 buffer 蛮简单的 12/30 01:08
55F:→ alog: 你可以把一个看不到的元素或超级迷你的div加入一组class 12/30 01:08
56F:→ alog: 这组class有你设定好的背景图片 12/30 01:09
57F:→ alog: 最好那块是在网页上看不到 12/30 01:09
58F:→ alog: 然後把那组class摆在最後,而tag的部分也是摆在最後 12/30 01:10
59F:→ alog: 当系统载入差不多的时候,那块部分就会被载入 12/30 01:10
60F:→ alog: 因为排版引擎从dom+css的样式规则发现这个class有被使用 12/30 01:10
61F:→ alog: 於是他就开始载入/设定你那组元素的样式,有档案也会下载 12/30 01:11
62F:→ alog: 若只有单纯在css里面定义,排版引擎不会去碰那里面的样式 12/30 01:12
63F:→ alog: 最後我想说的是,不管放在上面还是下面,或者是外部载入 12/30 01:14
64F:→ alog: 或者是直接放在里面,都有他的用意跟适合的情况 12/30 01:14
65F:→ alog: 各有优点及缺点,没有特别王道 12/30 01:15
66F:→ mmis1000: 在我看来,他对 ie,ff,chrome 都有效就有使用价值了 12/30 01:15
67F:→ alog: 要调校请以你那个网站的主使用者用的浏览器下去调 12/30 01:16
68F:→ mmis1000: 而且就算没效你也没损失阿 12/30 01:16
69F:→ alog: IE、Firefox、Chrome 都有开发者工具,追一下Network 12/30 01:16
70F:→ alog: 的Timeline有没有用 12/30 01:16
71F:→ mmis1000: 都有效欧...而且刚刚的回答就是追timeline的结果 12/30 01:20
72F:→ mmis1000: 是throttle成 5kb/s 的速度测的 12/30 01:28
73F:推 ufenyaw: 推a大background image举例 很棒很实用 12/30 07:26
74F:→ mmis1000: 来个小测试吧,这是一个简单的网页,含有一个延迟很大的 12/31 01:49
75F:→ mmis1000: css档案,只是一个放头,一个放尾 12/31 01:49
79F:→ mmis1000: 假设说这个css没内容还是会挡住吗? 12/31 02:04
82F:→ superpai: 实测结果如果FX会让HTML先出来再上CSS 12/31 15:52
83F:→ superpai: 但是Chrome 会等CSS抓完再让整个画面一起出来 12/31 15:53
85F:→ mmis1000: 事实上chrome也会,但限transfer-encoding:chunked的网 12/31 16:57
86F:→ mmis1000: 页 12/31 16:57
看到效果了,感谢这麽热心的测试网址,我把结果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