浏览器原理:7.1DOM树的构建

DOM树是什么

众所周知,现代浏览器采取的是客户端+服务端的形式,客户端向服务端发送请求,服务端响应请求,将请求的内容放在响应主体里面。但浏览器中的网络进程收到从服务端发送过来的数据一般是 HTML 文件字节流,这是无法被浏览器中的渲染引擎直接读取响应的,所以需要对这个HTML文件进行转换,将其转换为渲染引擎能够理解的结构,就比如我们写的高级语言都需要通过编译/解释后才能被CPU来执行。渲染引擎能够理解的这个结构就是DOM树。

在渲染引擎中,DOM的作用

  • DOM 是生成页面的基础数据结构
  • DOM向JS提供了接口,使JS可以对DOM结构进行访问,从而动态改变DOM
  • DOM是一道安全防护,一些不安全的内容在 DOM 解析阶段就被拒绝了

DOM 树是怎样生成的?

在渲染引擎内部,存在一个 HTLM 解析器(html parser)的模块,专门负责将HTML字节流转换为DOM结构,但注意,HTML解析器采取的是边加载数据边解析的方式。解析详细流程如下

  • 网络进程在接收到响应头后,根据响应头的 content-type 字段判断文件类型,若是 text/html,浏览器会判断这是一个 html 类型的文件
  • 浏览器接着就会为该文件准备一个渲染进程,可能是选择已有的,也可能是fork一个新的
  • 渲染进程准备好之后,网络进程和渲染进程之间就会建立起一个共享数据的管道,用来传输HTML字节流,同时渲染进程也会边接受,边加载。

关于HTML字节流如何转换成DOM树,则涉及到编译原理的内容。

当HTML解析器遇见 script标签内嵌JS代码时

因为 HTML 有 script标签,且script标签几乎可以插在任何地方,当HTML解析器遇到script标签时,它会暂停自己的工作,将控制权交给JS引擎,并执行script标签中的JS代码,当JS代码执行完成后,控制权交还给HTML解析器,继续解析,直至生成最终的DOM树

当HTML解析器遇见外部加载JS代码的script标签时

当 HTML 解析器执行到script标签时,还是会暂停自己的工作,但是这里因为没有JS代码,所以无法执行,需要先去下载该代码,下载完成后再来执行JS代码,后面的流程就跟上面基本一样了。但是浏览器这样的抉择无疑会带来性能问题,即JS代码的下载,阻塞了DOM树的解析,阻塞了页面的生成。所以现代浏览器对于这一块做了大量的优化,Chrome采取的最主要的优化就是预解析操作。

  • 当渲染引擎接受到字节流之后,会开启一个预解析线程,用来分析HTML文件中的JS文件、CSS等相关文件
  • 解析到这些文件之后,该线程会提前下载这些文件,这样就能够缩减DOM解析的时间

同样,开发者也可以采取设置异步加载JS的方式来优化,通过 async 或者 defer 来设置,二者的区别在于

  • async 标志的脚本文件一旦加载完成就会立刻执行
  • defer 标记的需要在 DOMCotentLoaded 事件之前执行
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值