网站加载的整个完整过程了。
-
首先浏览器从服务器接收到html代码,然后开始解析html
-
构建
DOM
树(根据html代码自顶向下进行构建),并且在同时构建渲染树 -
遇到
js
文件加载执行,将阻塞DOM
树的构建;遇到css
文件,将阻塞渲染树的构建
(script
标签中的defer
属性:构建DOM
树的过程和js文件的加载异步(并行)进行,但是js文件执行需要在DOM
树构建完成之后
script
标签中的async
属性:构建DOM
树、渲染树的过程和js
文件的加载和执行异步(并行)进行)
综上所述,script
标签最好放在</body>
标签的前面,因为放在所有body
中的标签后面就不会出现网页加载时出现空白的情况,可以持续的给用户提供视觉反馈,同时在有些情况下,会降低错误的发生。
而css标签应该放在<head></head>
标签之间,因为如果放在</body>
标签的前面,那么当DOM树构建完成了,渲染树才构建,那么当渲染树构建完成,浏览器不得不再重新渲染整个页面,这样造成了资源的浪费。效率也不高。如果放在<head></head>
之间,浏览器边构建边渲染,效率要高的多。
CSS与JavaScript文件的位置
1、CSS
尽量放置在head
标签中。
原因:
- 避免浏览器重新渲染;
- 避免阻塞JS文件的执行。
注:CSS选择器的解释顺序是 从右向左 的,所以尽量减少选择器的层级。
2、JS
尽量放置在</body>
之前。
原因:
- 避免阻塞html的加载、解析与渲染(因为js的执行时单线程的)。
关于html,css,js
三者的加载顺序问题
<head lang="en">
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="css/*.css">
<script src="js/*.js></script>
</head>
DOM文档的加载顺序是由上而下的顺序加载;
1、DOM加载到link
标签
css文件的加载是与DOM的加载并行的,也就是说,css在加载时Dom还在继续加载构建,而过程中遇到的css
样式或者img
,则会向服务器发送一个请求,待资源返回后,将其添加到dom
中的相对应位置中;
2、DOM加载到script
标签
由于js文件不会与DOM
并行加载,因此需要等待js整个文件加载完之后才能继续DOM
的加载,倘若js脚本文件过大,则可能导致浏览器页面显示滞后,出现“假死”状态,这种效应称之为“阻塞效应”;会导致出现非常不好的用户体验;
而这个特性也是为什么在js文件中开头需要$(document).ready(function(){})
或者(function(){})
或者window.onload
,即是让DOM
文档加载完成之后才执行js
文件,这样才不会出现查找不到DOM
节点等问题;
js阻塞其他资源的加载的原因是:浏览器为了防止js修改DOM树,需要重新构建DOM树的情况出现;
3、解决方法
前提,js是外部脚本;
在script
标签中添加 defer=“ture”
,则会让js与DOM并行加载,待页面加载完成后再执行js
文件,这样则不存在阻塞;
在scirpt
标签中添加 async=“ture”
,这个属性告诉浏览器该js
文件是异步加载执行的,也就是不依赖于其他js
和css
,也就是说无法保证js文件的加载顺序,但是同样有与DOM
并行加载的效果;
同时使用defer
和async
属性时,defer
属性会失效;
可以将scirpt
标签放在body
标签之后,这样就不会出现加载的冲突了。