页面渲染过程
要了解页面渲染,先造一个html文档
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./b.css" />
</head>
<body>
<div>hhh</div>
<script>
let el = document.getElementsByTagName('div')[0];
console.log(el.style.cssText);
</script>
</body>
</html>
首先是用户输入url,浏览器通过DNS查询要访问页面的IP,查询到后,浏览器会替用户去向这个IP地址发送请求拉取html文件,浏览器会派GUI线程去解析加载回来的html文件
html解析过程:01机器码-》charter字符-》tokens令牌-》node节点-》dom树
详细了解可以click下方链接,我就不细说了。
了解构建对象模型过程
html解析的过程,我们可能需要加载一些css文件和js脚本,那浏览器是怎么去处理这些资源文件的?
首先遇到link标签会立刻发起请求【会查询link标签的rel属性,因为link标签本身是通过浏览器发起一个http线程去拉取外部资源,链接css文件的link标签的rel属性为stylesheet(样式表)】去拉取的这个过程是不会阻塞GUI线程解析DOM树,css资源回来会被立刻加载,构建CSSOM树。这里DOM树和CSSOM树的构建是同时进行的。
当DOM树和CSSOM树都构建好了,这时候页面开始渲染了。【DOMContentLoaded事件触发】
页面是渲染出来了,但是里面涉及了大学问。来问几个问题吧
JS加载与执行
1、js脚本什么时候执行和他的执行会有什么影响?
什么时候执行需要分情况讨论——我们首先明确js脚本的加载和执行是会阻塞DOM树的构建的
因为js脚本是可以操作DOM的,浏览器为了更加优化页面构建的过程,避免js修改DOM结构和页面解析原本dom结构之间的冲突,所以在js脚本的执行的时候【js脚本执行是js引擎负责的】,GUI线程会被挂起,给js引擎控制DOM的权限,这也就是js脚本执行会阻塞DOM解析的原因。
下面说说js脚本的执行时机
1、当script标签在文档头部 和的非尾部,会阻塞DOM解析,script便签提供了相应的属性去应对这样的情况。分别是defer和async。两者的共同点是都是异步去加载js脚本,但是执行的时机不同,defer是等待DOM树解析完了才执行,async是加载完了之后立刻执行
2、在所有有样式【包括默认样式】的html标签之后,这时候的DOM解析已经完成了,也就不存在阻塞DOM解析的情况了
CSS加载与解析
其中我们还涉及到了CSS资源的加载和解析,那CSS在文档的加载方式常见的有link标签和style样式内嵌@import
首先:CSS的加载和CSSDOM树的构建都会阻塞页面的渲染
- 链接link方式:head标签中使用link标签,利用href设置外部样式文件,还需要rel=stylesheet 来说明资源和页面的关系
- 导入@import方式:使用CSS规则,在css样式表(style标签 或者 CSS文件 )的最开头@import url('./style.css'); 语句不能错,否则无法正确导入文件。并且@import的文件,要等到当前CSS文件加载完了才进行加载,不能并行加载,而link方式是可以并行加载的
针对link链接方式,可以利用media媒体属性来处理这个问题,默认为all
<link href="style.css" rel="stylesheet"> => media="all"
<link href="print.css" rel="stylesheet" media="print">
<link href="other.css" rel="stylesheet" media="(min-width: 40em)">
<link href="portrait.css" rel="stylesheet" media="orientation:portrait">
//①阻塞
//②首次加载不阻塞,只在打印内容时或者想要重新改变布局时阻塞
//③符合的设备,css加载会阻塞
//④动态查询,将在网页加载时计算。根据网页加载时设备的方向,portrait.css 可能阻塞渲染,也可能不阻塞渲染。
重要:
- 不管怎么设置,css都需要加载的,只是加载CSS的时候是否阻塞渲染资源的加载
- link在js脚本之前,是会阻塞js脚本的执行
总结
1、html和css由GUI负责加载解析
2、JS脚本由JS引擎加载解析
3、CSS加载与解析会阻塞页面渲染,但不阻塞DOM解析
4、当CSS样式资源在JS脚本前时,会阻塞JS脚本执行
5、JS脚本执行时,GUI线程会被挂起,从而阻塞DOM解析
6、只有DOM树和CSSOM树,合并成Render树,页面才开始渲染,这也是DOMContentLoaded事件触发的时机
看了很多的文章,才搞懂其中的一些细节,如果文章还有说法不准确的地方,还望各位大神留言指出,感谢感谢,希望大家一起学懂浏览器底层的这些知识,欢迎评论!
感谢大神们的分享!
参考: