CSS和JS在网页中的放置顺序
一般而言,因为HTML是一种相对松散的文档类型,同时浏览器的容错性又非常高,所以CSS和JS可以放置在页面上的任何位置。但是在实际使用中CSS通常使用link标签引入样式放在head标签内部
<link href="text.css" rel="stylesheet" type="text/css">
放在页面底部由于浏览器渲染机制可能会出现白屏
JS文件使用script标签放在body底部 </body>之前
<script src="text.js"></script>
浏览器的解析器遇到JS脚本后会立刻开始执行JS脚本,这样就会阻塞后面内容的解析,浏览器出现白屏,只有当JS脚本执行完毕,才会继续后面文档的渲染,所以我们一般把JS放到HTML文档的尾部,这样就不会出现白屏现象。
白屏和FOUC(flash of unstyled content)
Webkit内核的浏览器的渲染过程中页面的绘制要等HTML和CSS都加载完毕才开始,所以如果这个加载过程时间过长浏览器会出现白屏现象。
- 如果把样式放在文档底部,对于IE浏览器,在某些场景下(新窗口打开,刷新等)页面会出现白屏,而不是内容逐步展现
- 如果使用 @import 标签,即使 CSS 放入 link, 并且放在头部,也可能出现白屏
- 对于图片和CSS, 在加载时会并发加载(如一个域名下同时加载两个文件). 但在加载 JavaScript 时,会禁用并发,并且阻止其他内容的下载. 所以把 JavaScript 放入页面顶部也会导致白屏现象.
Gecko内核的浏览器则是在加载过程中优先渲染HTML部分,在CSS加载的时候再次进行页面的二次渲染,这样渲染到页面上的无样式内容时就会不断的进行页面二次渲染,无样式内容就会闪烁,这就是FOUC现象。
- 如果把样式放在底部,对于IE浏览器,在某些场景下(点击链接,输入URL,使用书签进入等),会出现 FOUC 现象(逐步加载无样式的内容,等CSS加载后页面突然展现样式).对于 Firefox 会一直表现出 FOUC .
async和defer的作用和区别
<script src="script.js"></script>
没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。
<script async src="script.js"></script>
有 async,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。
<script defer src="script.js"></script>
有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但 script.js 的执行要在所有元素解析显示完成之后,DOMContentLoaded 事件触发之前完成。
defer:脚本延迟到文档解析和显示后执行,按照出现的先后顺序执行
async:不保证在页面中出现的顺序
简述网页的渲染机制
浏览器渲染的流程
-
呈现引擎将开始解析 HTML 文档,并将各标记逐个转化成“内容树”上的 DOM节点。同时也会解析外部 CSS 文件以及样式元素中的样式数据。HTML 中这些带有视觉指令的样式信息将用于创建另一个树结构:呈现树。
呈现树包含多个带有视觉属性(如颜色和尺寸)的矩形。这些矩形的排列顺序就是它们将在屏幕上显示的顺序。 -
呈现树构建完毕之后,进入“布局”处理阶段,也就是为每个节点分配一个应出现在屏幕上的确切坐标。下一个阶段是绘制, 呈现引擎会遍历呈现树,由用户界面后端层将每个节点绘制出来。
注:需要着重指出的是,这是一个渐进的过程。为达到更好的用户体验,呈现引擎会力求尽快将内容显示在屏幕上。它不必等到整个 HTML 文档解析完毕之后,就会开始构建呈现树和设置布局。在不断接收和处理来自网络的其余内容的同时,呈现引擎会将部分内容解析并显示出来。
默认的,浏览器会按照顺序从上到下的解析(parse)HTML页面。当遇到需要加载的资源时(如stylesheets, images or scripts),浏览器会并行的请求这些资源。
stylesheets和images不会阻止浏览器对HTML页面的进一步解析工作。也就是说在css文件加载和执行的过程中,浏览器对的其他工作正常进行。
<script>标签(先不讨论其具有defer或async属性),它在下载和执行(download and execute)的过程中,会阻止浏览器对HTML页面的解析。
解析 HTML 标签, 构建 DOM 树
解析 CSS 标签, 构建 CSSOM 树
把 DOM 和 CSSOM 组合成 渲染树 (render tree)
在渲染树的基础上进行布局, 计算每个节点的几何结构
把每个节点绘制到屏幕上 (painting)
解析 HTML 标签到Content Sink
这时,先加载Content Sink里面的内容,页面上会显示一个无样式的内容
循环加载css样式,每次加载一部分css样式后,都会重现渲染页面
网友评论