前言

html css javascript可以算是前端必须掌握的东西了,但是我们的浏览器是怎样解析这些东西的呢 我们如何处理html css javascript这些东西来让我们的网页更加合理,在我这里做了一些实验,总结起来给大家看看。

最简单的页面

我们打开chrome的控制台查看timeline

1

由上图 可得结论

1 图中蓝色透明条标识浏览器从发起请求到接收到服务器返回第一个字节的时间,时间还是挺长的,而蓝色实体条则为真正的html页面下载的时间 还是很短的。

 

2 图中红框内的这部分时间则表示浏览器从下载完成html之后开始构建dom,当发现一个image标签时所花费的时间,由此可见dom是顺序执行的,当发现image时便立即发起请求,而紫色透明条则是image发起请求时在网络传输时所消耗的时间。

 

3 图中timeline蓝色竖线所处的时间为domComplete时间,红色竖线为dom的onload时间,由此可见两种事件的差异。而浏览器构建dom树所花费的时间可以算出即domComplete时间 减去 html下载完成后的时间大概80ms。


含有css的页面

我们打开chrome的控制台查看timeline

2

1 在添加了外部引入css之后,并没有发现什么异常,但是有一点指的注意,也就是红色竖线和蓝色竖线挨得更进了,这表明domComplete时间必须等待css解析完成,也就是构建dom树必须等待css解析完成,这也就解释了下图

3


含有javascript和css的页面

我们打开chrome的控制台查看timeline

4

1 图上显示在引入外部的js文件之后domComplete时间又被延后了,结合上面的renderTree,由于javascript代码可能会更改css属性或者是dom结构,所以在形成renderTree之前必须等待javascript解析完成才能接着构建renderTree。

2 将javascript放在head内和body底部的区别也在于此,放在head里面,由于浏览器发现head里面有javascript标签就会暂时停止其他渲染行为,等待javascript下载并执行完成才能接着往下渲染,而这个时候由于在head里面这个时候页面是白的,如果将javascript放在页面底部,renderTree已经完成大部分,所以此时页面有内容呈现,即使遇到javascript阻塞渲染,也不会有白屏出现。


内嵌javascript的页面

5

 

1 图上可以看到,由于内嵌了javascript,页面上减少了一个请求,导致html文档变大,消耗时间增多,但是domComplete时间提升的并不多。


使用async的javascript

 

6

1 可以看到domComplete时间被大大提前 javascript也没有阻塞css和body里面img元素的并行下载。

2 使用async标识的script,浏览器将异步执行这中script不会阻塞正常的dom渲染,这时html5所支持的属性,另外defer也可以达到这种效果。


head里面js和css加载的关系

外联js在css前面

1 没有阻止css的并行加载但是影响了body里面img的并行加载


外联js在css中间

1 影响了css的并行加载和body里面img的并行加载


外联js在css最后

1 影响了css的并行加载和body里面img的并行加载


内嵌js在css前面

1 没有影响css的并行加载也没有影响body里面img的并行加载


内嵌js在css中间

1 影响了css的并行加载没有英雄body里面img的并行加载


内嵌js在css最后

1 影响了css和body里面img的并行加载。


综上所述:

当浏览器从服务器接收到了HTML文档,并把HTML在内存中转换成DOM树,在转换的过程中如果发现某个节点(node)上引用了CSS或者 IMAGE,就会再发1个request去请求CSS或image,然后继续执行下面的转换,而不需要等待request的返回,当request返回 后,只需要把返回的内容放入到DOM树中对应的位置就OK。但当引用了JS的时候,浏览器发送1个js request就会一直等待该request的返回。因为浏览器需要1个稳定的DOM树结构,而JS中很有可能有代码直接改变了DOM树结构,浏览器为了防止出现JS修改DOM树,需要重新构建DOM树的情况,所以 就会阻塞其他的下载和呈现.

 

这里的结论:

1 在head里面尽量不要引入javascript.

2 如果要在head引入js 尽量将js内嵌.

3 把内嵌js放在所有css的前面.

 

后记

1 本次的测试页面 http://1.lvming6816077.sinaapp.com/testaa/demo.html

2 测试所用浏览器 chrome

3 参考资料:http://www.zhihu.com/question/20357435/answer/14878543

http://www.haorooms.com/post/web_xnyh_jscss

4 如果有哪里说的不清楚或者错误的地方,欢迎留言反馈。

原创文章转载请注明:

转载自AlloyTeam:http://www.alloyteam.com/2015/05/wang-ye-xing-neng-zhi-html-css-javascript/

  1. xiangnaier 2016 年 11 月 17 日

    真棒!早发现这么好的东西就好了!

  2. bire 2016 年 10 月 26 日

    图挂了

  3. f91 2016 年 4 月 3 日

    非常感谢

  4. f91 2016 年 4 月 3 日

    mark

  5. J 2015 年 11 月 6 日

    赞 受教了

  6. 非礼 2015 年 10 月 15 日

    有错别字,“英雄”改成“影响”。还有有仁兄说大部分网站还是将js放在head里,这个我觉得是每个网站各自考虑的东西和平衡不一样。就好比大家都知道两点之间直线最短。但是实际上又有多少人按照直线走了呢。

    • TAT.tennylv

      吕鸣 2015 年 7 月 30 日

      domContentLoaded和domComplete是两个不同的事件哦http://www.nihaoshijie.com.cn/index.php/archives/472

    • TAT.tennylv

      吕鸣 2015 年 7 月 30 日

      动态引入的js不是一开始在页面就写的是通过js去改变dom来引入script标签 这个时候整个页面也已经完成了自然不会影响首屏的domContentLoaded

      • 新浪前端 2015 年 7 月 30 日

        依然是似懂非懂。通过脚本动态引入的js文件,是等这个动态js文件加载完了,再执行domContentLoaded,还是domContentLoaded根本就不受动态js文件加载的影响?我问的是这个意思。

        • TAT.tennylv

          吕鸣 2015 年 7 月 30 日

          这个是不影响的 你可以做个实验试一下嘛 先不动态引入js 然后看一下domContentLoaded时间 然后在动态引入js 在看一下时间 这样一对比就知道结果了 自己动手更加清晰 可以参考http://1.lvming6816077.sinaapp.com/testaa/domComplete.html

    • TAT.tennylv

      吕鸣 2015 年 7 月 30 日

      既然浏览器只能等js加载完了,才能执行domContentLoaded 这里说的是js放在body底部 这是为了尽快让页面有可视内容出来 这个时候这些内容不一定都能点击一些事件绑定等逻辑放在body底部这些逻辑不影响页面展示的

  7. 云库网 2015 年 7 月 27 日

    看来大家都学到东西了

  8. 游客 2015 年 7 月 25 日

    你们都在说尽量吧外联JS放在底部,但是基本所有的网站都是放在head里面…….

  9. John 2015 年 6 月 9 日

    非常好的文章只是第二点我不同意(2 如果要引入js 尽量将js内嵌.)

    1. 第一次测试没问题,但是咱们都知道浏览器是有缓存的,当浏览器缓存js文件以后,下次在加载,直接从缓存里面加载了,如果是内嵌的,就没有这个优势了,
    2. 对于js,css可以开启gzip压缩,如果是内嵌的话,就没办法使用gzip压缩功能了。
    3. 后续维护是难题,因为现在页面里面有大量js代码后续维护可以说是噩梦

    • TAT.tennylv

      TAT.tennylv 2015 年 6 月 11 日

      1 可能解释的有点不准确,我这里特指的是在head引入js的话最好内嵌,已更改。
      2 尽管js css可以gzip压缩 pc上可能不明显 但是对于移动端每多发一次请求都会耗费大量的性能,另外html也会gzip压缩。
      3 这边内嵌js一般都不会直接在html页面里写js的 按正常的js文件编写,在构建的时候把js压缩并内嵌到html里面。

  10. 裕波 2015 年 5 月 23 日

    HTML,CSS,JavaScript 大小写能规范书写吗?

    • TAT.tennylv

      TAT.tennylv 2015 年 5 月 25 日

      OK

  11. C。 2015 年 5 月 13 日

    如果引入个不存在的js文件,使用defer的时候蓝红线始终在一起,使用async蓝线会先出现,defer没有async好用啊

  12. C。 2015 年 5 月 13 日

    如果css的url不对,蓝线有可能会在css文件下载过程中出现,所以“domComplete时间必须等待css解析完成”这个结论貌似不对啊

    • TAT.tennylv

      TAT.tennylv 2015 年 5 月 13 日

      如果css的url不对,css404,那么浏览器是下载不了css的 domComplete时间也就可css无关了 这里其实也就不用考虑css解析了

      • C。 2015 年 5 月 13 日

        可是浏览器在尝试下载失败后才知道是404啊,所以有可能dom没有等css解析完就Complete

        • TAT.tennylv

          TAT.tennylv 2015 年 5 月 14 日

          这里都没css了 就不属于此类情况的了

  13. 星情 2015 年 5 月 7 日

    很不错的文章

  14. 小无路 2015 年 5 月 6 日

    结论简单明了。。我稀饭

  15. Jation 2015 年 5 月 6 日

    nice

发表评论