1. CSS和JS在网页中的放置顺序是怎样的?
- CSS一般放置在
<head>
标签内。如果放置在其他位置,可能会在加载时出现白屏和FOUC - JS一般放置在
</body>
标签之前,这是为了提高页面渲染的速度效率。浏览器在加载<script>
元素内部的JS代码将被从上至下依次解释,解释器对<script>
元素内部所有代码求值完毕之前,会阻塞其他资源的加载,页面的其余内容都不会被浏览器加载显示,如果放置在前面其他位置,会对页面内容的加载速度产生影响。
2. 解释白屏和FOUC
- 白屏,白屏的根本原因是浏览器在渲染的时候请求时间过长造成的。以下几种情况可能导致白屏:
- 如果样式在body底部被引入,对于IE浏览器和Chrome浏览器等(全部CSS文件加载并解析后才渲染,有可能等待时间长),在某些场景下(新窗口打开等)页面会出现白屏,而不是内容逐步展现。
- 如果CSS中使用@import引入其他CSS文件,会导致CSS文件无法并行加载:使用@import引用的文件只有在引用它的那个CSS文件被下载解析之后,浏览器才会知道还有另外一个CSS文件需要下载,这时才去下载,然后进行解析构建render tree等一系列操作。
- 当JS文件在body顶部被引入,由于JS文件无法并行加载,且阻止其他内容下载,也会造成白屏现象。
- FOUC,(Flash of Unstyled Content) 无样式内容闪烁,出现的原因是逐步加载无样式的内容,等CSS加载后页面突然展现样式,用户看到的页面的过程就是无样式内容闪烁。以下几种情况可能导致FOUC
- CSS文件在
</body>
之前被引入 - 使用
@import
引入CSS文件 - 部分浏览器如Firefox浏览器渲染机制导致
- CSS文件在
3. async和defer的作用是什么?有什么区别
- 默认情况下,
<script src="script.js"></script>
,页面中的JS加载的时候会立刻执行指定的脚本,因此会阻塞后面内容的加载。不过加上 async 或defer 就不一样了。 - async,
<script async src="script.js"></script>
,有 async时,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。 - defer,
<script defer src="script.js"></script>
,有 defer时,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。
如下图所示:

针对脚本,蓝色线代表网络读取,红色线代表执行时间,绿色线代表 HTML 解析。
- 由此图可总结出以下几点:
- defer 和 async 在网络读取(下载)这部分是一样的,都是异步(相较于 HTML 解析),它们的差别在于脚本下载完之后何时执行。
- async 则是一个乱序执行方式,对它来说脚本的加载和执行是紧紧挨着的,所以不管你声明的顺序如何,只要它加载完了就会立刻执行,async 对于应用脚本的用处不大,因为它完全不考虑依赖(哪怕是最低级的顺序执行),不过它对于那些可以不依赖任何脚本或不被任何脚本依赖的脚本来说却是非常合适的。
- defer 是最接近我们对于应用脚本加载和执行的要求的,它是按照加载顺序执行脚本。
4. 简述网页的渲染机制
- 解析HTML, 构建DOM树;
- 解析CSS, 构建CSSOM树;
- 把DOM树和CSSOM树组合成渲染树 (render tree);
- 在渲染树的基础上进行布局, 计算每个节点的几何结构;
-
把每个节点绘制到屏幕上 (painting)。
render tree
网友评论