1. CSS和JS在网页中的放置顺序是怎样的?
- 将css放在顶部
一般来说应该放在网页头部<head></head>
之间,用<style></style>
定义,也可以放在一个单独的文件(文件后缀名为.css),然后在网页头部用<link>
引用,如<link href="/css/main.css" rel="stylesheet" type="text/css">
当然,由于浏览器对HTML代码格式的容错性,你放在网页的任何地方定义都行。最好使用<link>
标签把css文件放在<head>
中,把JS放在<script>
标签中。
如果CSS放在后面可能页面会出现闪跳的感觉,或者是白屏或者布局混乱直到CSS加载完成。 - JS最好放在底部
对于Javascript来说,因为它在执行过程中会阻塞页面的渲染,所以,最好不要放在顶部,我们要把它放在页面的结尾。
2. 解释白屏和FOUC
- 1.如果把样式放在底部,对于IE浏览器,在某些场景下(新窗口打开,刷新等)页面会出现白屏,而不是内容逐步展现。
2.如果使用 @import 标签,即使 CSS 放入 link, 并且放在头部,也可能出现白屏。
3.JavaScript 放入页面顶部,脚本会阻塞后面内容的呈现也会导致白屏现象。 - FOUC (Flash of Unstyled Content) 无样式内容闪烁
如果把样式放在底部,对于IE浏览器,在某些场景下(点击链接,输入URL,使用书签进入等),会出现 FOUC 现象(逐步加载无样式的内容,等CSS加载后页面突然展现样式).对于 Firefox 会一直表现出 FOUC 。
3. async和defer的作用是什么?有什么区别。
<script src="script.js"></script>
没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行,脚本会阻塞后面内容的呈现。<script async src="script.js"></script>
有 async,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。标记为async的脚本并不保证按照指定它们的先后顺序执行。对它来说脚本的加载和执行是紧紧挨着的,所以不管你声明的顺序如何,只要它加载完了就会立刻执行。async 对于应用脚本的用处不大,因为它完全不考虑依赖(哪怕是最低级的顺序执行),不过它对于那些可以不依赖任何脚本或不被任何脚本依赖的脚本来说却是非常合适的。<script defer src="script.js"></script>
有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成,它是按照加载顺序执行脚本的。二者区别
两者的差别在于脚本下载完之后何时执行,显然 defer 是最接近我们对于应用脚本加载和执行的要求的。defer是立即下载但延迟执行,加载后续文档元素的过程将和脚本的加载并行进行(异步),但是脚本的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。async是立即下载并执行,加载和渲染后续文档元素的过程将和js脚本的加载与执行并行进行(异步)。
4. 简述网页的渲染机制
1.解析 HTML 标签, 构建 DOM 树,浏览器按从上到下的顺序扫描解析文档。
-
DOM,即文档对象模型(Document Object Model)。DOM树,即文档内所有节点构成的一个树形结构。
2.解析 CSS 标签, 构建 CSSOM 树。
- CSSOM,即CSS对象模型(CSS Object Model)。CSSOM树,与DOM树结构相似,只是另外为每一个节点关联了样式信息。
3.把 DOM 和 CSSOM 组合成 渲染树 (render tree)
-
渲染树,代表一个文档的视觉展示,浏览器通过它将文档内容绘制在浏览器窗口,展示给用户,它由按顺序展示在屏幕上的一系列矩形对象组成,这些矩形对象都带有字体,颜色和尺寸,位置等视觉样式属性。对于这些矩对象,FireFox称之为框架(frame),Webkit浏览器称之为渲染对象(render object, renderer),后文统称为渲染对象。
4.在渲染树的基础上进行布局(Layout), 计算每个节点的几何结构
- 通过渲染树中渲染对象的信息,计算出每一个渲染对象的位置和尺寸,将其安置在浏览器窗口的正确位置,而有些时候我们会在文档布局完成后对DOM进行修改,这时候可能需要重新进行布局,也可称其为回流(reflow,relayout),本质上还是一个布局的过程,每一个渲染对象都有一个布局或者回流方法,实现其布局或回流。
5.把每个节点绘制到屏幕上 (painting)
- 浏览器UI组件将遍历渲染树并调用渲染对象的绘制(paint)方法,将内容展现在屏幕上,也有可能在之后对DOM进行修改,需要重新绘制渲染对象,也就是重绘,绘制和重绘的关系可以参考布局和回流的关系。