title

当我们在浏览器里输入一个 URL 后,最终会呈现一个完整的网页。会经历以下几个步骤:
1、HTML 的加载页面上输入 URL 后,会先拿到 HTML 文件。HTML是一个页面的基础,所以会在最开始的时候下载它,下载完毕后就开始对它进行解析
2、其他静态资源的下载HTML 在解析的过程中,如果发现 HTML 文本里面有一些外部的资源链接,比如 CSS、JS 和图片等,会立即启用别的线程下载这些静态资源。在 head 中遇到 JS 文件时,HTML 的解析会停 下来,等 JS 文件下载结束并且执行完,HTML 的解析工作再接着来,防止 JS 修改已经完成的解析结果
知识拓展由上得知,JS 文件放在 head 中属于同步加载,会阻塞 DOM 树的构建,进而影响页面的加载。当 JS 文件较多时,页面白屏的时间也会变长
那如何避免这个问题呢?下面有三个解决方案
1、 script 放在 body 里(一般是上面)
由于 DOM 是自上而下解析的,因此 JS 不会阻塞 DOM 的解析,而且这时候可以在 JS 中操作 DOM
2、设置 defer 属性
通过给 script 标签设置 defer 属性,将脚本文件设置为延迟加载,当浏览器遇到带有 defer 属性的 script 标签时,会再开启一个线程去下载 JS 文件,同时继续解析 HTML,等 HTML 全部解析完、DOM 加载完成之后,再去执行加载好的 JS 文件。只适用于引用外部 JS 文件,并且可以确保所有加了 defer 属性的脚本会按顺序执行
3、设置 async 属性
async 属性和 defer 属性类似,也是会开启一个线程去下载js文件,但和 defer 不同的是,aysnc 会在 JS 加载完成后立刻执行,而不是会等到 DOM 加载完成之后再执行,所以还是有可能会造成阻塞。同样的也是只适用于外部 JS 文件,如果有多个设置了 aysnc 的 JS 文件,不能像 defer 那样保证按照顺序执行
4、动态创建脚本
这样去动态创建文件也不会影响到页面的加载,以下是百度统计的demo
3、DOM 树的构建
DOM 的全称是:文档对象模型(document Object Model),在 HTML 解析时,解析器会把解析完的 HTML转化成 DOM 对象,再进一步构建 DOM 树
4、CSSOM 树的构建
当 CSS 下载完,CSS 解析器就开始对 CSS 进行解析,把 CSS 解析成 CSS 对象,然后把这些 CSS 对象组装成一颗 CSSOM 树
5、渲染树的构建
DOM 树和 CSSOM 树都构建完成以后,浏览器会根据这两棵树构建出一棵渲染树
6、布局计算
渲染树构建完成以后,所有元素的位置关系和需要应用的样式就确定了。这时候浏览器会计算出所有元素的大小
和绝对位置
7、渲染
布局计算完成以后,浏览器就可以在页面上渲染元素了,经过渲染引擎的处理后,整个页面就显示在了屏幕上
上面是一个浏览器渲染页面的大概过程,接下来就来把这个过程的几个重要部分再详细讲下
DOM 树的构建
页面中的每一个 HTML 标签,都会被浏览器解析成一个对象,我们称它为文档对象(document Object)。HTML
本质是一个嵌套结构,在解析的时候会把每个文档对象用一个树形结构组织起来,所有的文档对象都会挂在一个叫做 document 的东西上,这种组织方式就是 HTML 最基础的结构–文档对象模型(DOM),这棵树里面的每个文档对象就叫做 DOM 节点。
在 HTML 加载的过程中,DOM 树就在开始构建了。构建的过程是先把 HTML 里每个标签都解析成 DOM 节点(每
个标签的属性、值和上下文关系等都在这个文档对象里),然后使用深度遍历的方法把这些对象构造成一棵树。
我们以下面的 HTML 文件为例:
document
header
title