CSS和JS在网页中的放置顺序是怎样的?
- CSS应该放在页面顶部的head标签中
由于Render Tree是由DOM树和CSSOM树组合成的,html页面需要等到CSS解析完后才能完成渲染,所以CSS应放在head标签内,优先下载解析,以避免页面元素由于样式缺失造成瞬间的白页或者给用户闪烁感。
- JS应该放在body的底部
因为浏览器需要一个稳定的dom树结构,而且js中很有可能有代码直接改变了dom树结构,浏览器为了防止出现js修改dom树,需要重新构建dom树的情况,所以就会阻塞其他的下载和呈现。
将JavaScript放在head内和body底部的区别也在于此,放在head里面,由于浏览器发现head里面有JavaScript标签就会暂时停止其他渲染行为,等待JavaScript下载并执行完成才能接着往下渲染,而这个时候由于在head里面这个时候页面是白的;如果将JavaScript放在页面底部,render Tree已经完成大部分,所以此时页面有内容呈现,即使遇到JavaScript阻塞渲染,也不会有白屏出现 - 如果CSS和JS都在head标签内,则应将JS放在所有CSS的前面
JS的执行有可能依赖最新样式。比如,可能会有var width=$('#id').width,这意味着,JS代码在执行前,浏览器必须保证在此JS之前的所有CSS(无论外链还是内嵌)都已下载和解析完成。
把JS放在CSS后会导致页面阻塞,去等待CSS的下载。
另外如果要在head引入JS尽量将JS内嵌。
解释白屏和FOUC
当把CSS样式放在底部或者使用@import方式引入样式、或将JS放在头部造成其他内容阻塞加载时:
1.一些浏览器例如chrome,他的加载和渲染机制是等头部的JS和底部的CSS全部加载解析完后再渲染展示页面,而这个等待的时间就为白屏。
2.另一些浏览器例如Firefox,他会在CSS未加载前先展现页面,等css加载后再重绘一次,这就造成了FOUC (无样式内容闪烁)。
*所以为了避免这些问题,最好使用link标签将CSS样式表放在文档的head中,将JS放置在</body>标签之前、body标签中html内容的后面。
async和defer的作用是什么?有什么区别
- script :浏览器会立加载并执行相应脚本,阻塞后续文档的加载。
- script async :后续文档的加载和渲染与js加载和执行同步进行,即异步执行。
async是一个乱序执行方式,对它来说脚本的加载和执行是紧紧挨着的,所以不管你声明的顺序如何,只要它加载完了就会立刻执行,async 对于应用脚本的用处不大,因为它完全不考虑依赖(哪怕是最低级的顺序执行),不过它对于那些可以不依赖任何脚本或不被任何脚本依赖的脚本来说却是非常合适的。 -
script defer :后续文档的加载和渲染与js加载并行,js在后续文档加载完毕后执行。
简述网页的渲染机制
1.解析CSS构建CSSOM树
2.把DOM和CSSOM组合成渲染树(Render Tree)
3.在渲染树的基础上进行布局,计算每个节点的几何结构(Layout Tree)
4.把每个节点绘制到屏幕上(Painting)