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脚本之间的依赖关系。
总结
- CSS 不会阻塞 DOM 的解析,但会阻塞 DOM 的渲染
- CSS 会阻塞 JS 的执行,但不会阻塞 JS 的下载
- JS 会阻塞 DOM 的解析,也就会阻塞 DOM 的渲染
建议
<link>标签写在<head>里面,<script>标签写在body标签的尾部。