HTML、JS、CSS加载顺序

711 阅读3分钟

scr(source)

src 指的是外部资源的位置,在请求 src 资源时会将指向的资源下载并应用到文档中,例如:js 脚步、img 图片和 frame 等元素。但浏览器解析到该元素时,会暂停其他资源的下载和处理,直到资源加载编译完毕,图片和框架也是如此。这也是 js 脚步为什么放在而不是头部的原因

href(Hyper Text Refernce)

href 指的是网络资源所在的位置,建立和当前元素或当前文档之间的链接,浏览器识别该文档为css文件就会下载资源并且不会停止对当前文档的处理

CSS 引入方式

<!-- 行内样式 -->
<div style="color: green; margin-top: 30px;border: 1px solid red;width: 500px">行内样式实例1</div>
<!-- 内部样式表 -->
<style> 
    p { color: #6478de; border: red 1px solid; } 
</style>
<!-- 链入外部样式表 -->
<link rel="stylesheet" type="text/css" href="qt_02_style.css">\
<!-- 导入外部样式表 -->
<style>
    @import "qt_02_style.css"; 
</style>

<link>@import 的区别

<link> 引用 CSS 时,在页面载入的时候可以同时加载样式,样式加载和结构加载是异步操作。可以防止访问网页时先加载完文字、图片等结构数据,然后再加载样式的问题。@import 需要网页结构完全载入以后加载样式文件。

CSS 与 JS 关系

CSS会阻塞JS的执行,所以JS必须要等到CSSOM构建完成之后再执行。CSS不会阻塞DOM的解析,所以会阻塞DOM的渲染

JS 引入方式

在HTML中引入JS的方式一般有四种:

<script type="text/javscript">
    var a = 1;
</script>
<script src="..."></script>
<script src="..." async></script>
<script src="..." defer></script>

<script>(内部脚本)

HTML解析器在解析过程中如果遇到script标签,就会暂停解析,执行该脚本代码,执行完之后再继续解析HTML。

<scirpt>(默认脚本)

HTML解析器在解析过程中如果遇到script标签,就会暂停解析,先去请求下载script脚本,下载完接着执行该脚本代码,执行完之后再继续解析HTML。

所以script 阻塞了浏览器对 HTML 的解析,如果获取 JS 脚本的网络请求迟迟得不到响应,或者 JS 脚本执行时间过长,都会导致白屏,用户看不到页面内容。建议<script> 标签写在body标签的尾部

<script async>(异步脚本)

HTML解析器在解析过程如果遇到script async标签,该脚本的请求下载是异步的,不会阻塞HTML的解析,但是如果脚本下载回来时,HTML还没有解析完成,这时候会暂停HTML的解析,先去执行脚本内容,执行完成后,再继续解析HTML。

当然它还有一种情况就是当异步脚本下载回来时,HTML解析已经完成了,那该脚本就对HTML没啥影响,下载完直接执行就好了。

所以该方法的执行是不可控的,因为无法确定脚本的下载速度与脚本内容的执行速度,如果存在多个script async时,他们之间的执行的顺序也是不可控的,完全取决于各自的下载速度,谁先下载完成就先执行谁。

<script defer>(异步延迟脚本)

HTML解析器在解析过程如果遇到script defer标签,该脚本的请求下载是异步的,不会阻塞HTML的解析,并且在脚本下载完之后如果HTML还没解析完成,该脚本也不会阻塞HTML解析,而是会等HTML解析完成之后再执行(DOMContentLoaded事件触发执行之前)。

如果存在多个script defer标签时,他们之间的执行顺序会按他们在HTML文档中的顺序来进行,这样能够保证JS脚本之间的依赖关系。

image.png

总结

  • CSS 不会阻塞 DOM 的解析,但会阻塞 DOM 的渲染
  • CSS 会阻塞 JS 的执行,但不会阻塞 JS 的下载
  • JS 会阻塞 DOM 的解析,也就会阻塞 DOM 的渲染

建议

<link> 标签写在 <head> 里面, <script> 标签写在body标签的尾部。