浏览器渲染页面的整个过程【不懂就学】

1,266 阅读4分钟

页面渲染过程

要了解页面渲染,先造一个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事件触发的时机

看了很多的文章,才搞懂其中的一些细节,如果文章还有说法不准确的地方,还望各位大神留言指出,感谢感谢,希望大家一起学懂浏览器底层的这些知识,欢迎评论!

感谢大神们的分享!

参考:

不要使用@import

浏览器工作原理:输入url开始到页面加载完成

关键渲染路径CPR

css加载是否造成阻塞