CSS为什么要放在head底部,JavaScript为什么要放在body底部?
引入
在我们学习前端的时候,我们知道需要将css放在head底部,将js放在body的底部,当然绝大部分网站也都是这样做的。那么为什么要这么做呢?要理解其中的原理,首先我们需要了解浏览器是如何根据HTML、 CSS和JS来渲染页面的。
浏览器渲染页面
首先,当我们输入一个页面地址的时候,浏览器就会发送请求给服务器,服务器会以字节形式返回一个HTML文档。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<p>Hello</p>
</body>
</html>
CSS解析和HTML解析
浏览器会解析字节得到字符,根据W3C标准对字符进行识别,得到Token,有了Token进行词法分析得到带有属性和规则信息的节点,将这些节点根据规格进行连接,就会得到一个树形结构,这个树形结构就是我们常说的DOM(Document Object Model)。
为了渲染出页面,浏览器还需要知道页面元素的样式信息,样式信息又是通过css来控制的,浏览器会对CSS进行解析形成结构化数据,这个过程和解析HTML类似,解析后生成的树形结构是CSSOM。
body {
font-size: 16px;
}
p {
font-weight: bold;
}
现在有了DOM和CSSOM,分别表示页面的内容和样式,为了渲染出页面,浏览器会将DOM和CSSOM进行合并得到一个Render Tree,浏览器通过计算像素等最终绘制在屏幕上。
这里要注意一个问题:在构建DOM过程过如果遇到了CSS,浏览器会在该CSS解析生成CSSOM后在进行渲染,确保遇到的CSS都解析完成后浏览器才会进行渲染,这样就避免了页面渲染过程中先出现页面效果在进行样式渲染的情况(页面会闪烁,影响了用户体验)。
由此,CSS解析是一个会阻塞页面渲染的过程,先解析CSS生成CSSOM,页面解析生成DOM,样式和页面都有了,就可以一次渲染出页面效果了。
JS解析
首先,浏览器在解析HTML时遇到了JS,由于JS中可能会对DOM进行操作,因此,JS需要在此刻立即开始执行,等这段JS执行完毕后再继续加载HTML内容。同理,JS会阻塞页面解析。此外,JS在执行过程中,处理会操作DOM,还有可能会操作样式。那么,如果在执行JS的时候,CSS还没有解析完毕,那么浏览器会暂停JS执行,直到CSS解析完毕后在执行JS。
总结
JS需要等到CSS加载完毕以后,才会真正的开始执行,CSS会阻塞页面渲染,当浏览器遇到CSS时,会保证CSS加载完毕CSSOM后才会进行渲染;当浏览器遇到JS内容时,会停止DOM的构建,直到JS执行完毕,JS会查询、修改DOM CSSOM,因此浏览器会停止执行JS,直到CSSOM生成完毕。
那么,对于这个问题的回答可以使这样的:
1.首先,我们不希望用户看到没有样式的页面。如果css放在页面元素的后边,这些元素会先显示出来,样式加载后会再次渲染带有样式的效果。
2.JS会阻塞页面的渲染。我们希望用户尽快看到有内容的页面,如果JS放在body顶部,那么需要JS加载完毕之后才会显示出页面,影响用户体验。
3.JS可能会对DOM和CSSOM进行操作。放在body底部就保证了DOM和CSSOM加载完毕。
4.css放在head底部,js放在body底部是在为了获得更好的用户体验的同时,提升页面性能。