由于m.360zfw.com在google pagespeed的测试中
提示对于js阻塞,网上已经有很多文章,但是css阻塞的描述较少,于是对css阻塞进行深入研究。
写了一个测试demo,代码如下
late-css.php <?php header("Content-type: text/css; charset=utf-8"); sleep(intval(@$_GET[time])); $str = 'div{background:blue}'; echo $str; ?> late-js.php <?php header("Content-type: text/js; charset=utf-8"); sleep(intval(@$_GET[time])); $str = 'document.write("I'm the lazy note")'; echo $str; ?>
index3.html <html> <head> <style> div{background:red;width:200px;height:200px;} </style> <link rel="stylesheet" href="/lab/late/late-css.php?time=10&blue"> </head> <body> <div></div> </body> </html>
运行demo呈现的是页面需要等待10秒才能打开,而且直接打开的是蓝色方块。(证明css在页面中存在阻塞,但不确定是在解析DOM时阻塞还是渲染时阻塞)
index4.html <html> <head> <style> div{background:red;width:200px;height:200px;} </style> </head> <body> <div></div> </body> <link rel="stylesheet" href="/lab/late/late-css.php?time=10&blue"> </html>
运行demo呈现的是页面需要等待10秒才能打开,而且直接打开的是蓝色方块。(证明css在页面中存在的是阻塞渲染)
那么在我们设计页面的时候css,尽量将首屏显示的css直接放在html上面是最合适的,但是实际情况很难做到,比如一些导航的样式,未来在css文件中实现CDN,不得不将css放在外链中。
index.html <html> <head> <style> div{background:red;width:200px;height:200px;} </style> <link rel="stylesheet" href="/lab/late/late-css.php?time=5&blue"> </head> <body> <div><script src="/lab/late/late-js.php?time=10"></script></div> </body> <style> div{background:yellow;} </style> </html>
运行代码 (证明js,阻塞DOM解析,CSS作用于DOM解析到哪里,就渲染到哪里)
猜猜这是会显示什么?
先白色5秒,再蓝色5秒,再黄色
index2.html <html> <head> <style> div{background:red;width:200px;height:200px;} </style> </head> <body> <div><script src="/lab/late/late-js.php?time=10"></script></div> </body> <link rel="stylesheet" href="/lab/late/late-css.php?time=5&blue"> <style> div{background:yellow;} </style> </html>
运行代码 (证明css在下载时,不阻塞DOM解析,但是下载时阻塞渲染)
先红色,再黄色
总结:CSS和JS的下载都不会被解析阻塞,CSS下载时会阻塞渲染, 外部样式会阻塞后续脚本执行,直到外部样式加载并解析完毕。
1.没遇到JS阻塞的情况,CSS只会在DOM解析完后渲染。
2.遇到JS阻塞的情况,当DOM一旦遇到JS阻塞时,就会触发CSS渲染
那么现在有一个问题,css写在body前和body后有什么区别,
由上述可见,CSS无论是用STYLE标签还是link外链,
如果没有遇到jS阻塞,放哪里都一样,
如果遇到js阻塞,把CSS写在BODY上面,不会出现二次渲染,把CSS写在BODY下面,JS阻塞时,会出现一次渲染,等阻塞完毕会出现二次渲染(除非外链的CSS下载时间比阻塞时间长)。