赞
踩
平台: WIN10
调试工具: vs2019
chromium: 78.0.3904.108
解析网站: www.so.com
(有条件的小伙伴建议根据文章里的断点,自己调试,分析堆栈和查看数据的结构,可能会有不同的理解)
下图是 chromium webkit 构建 dom 树时,主要用到的类,我们会在下图中部分类的实现中,进行跟踪,分析 dom 的构建过程
(src\third_party\blink\renderer\core\loader\document_loader.cc)
在 DocumentLoader 类的构造函数 DocumentLoader::DocumentLoader 打断点,查看堆栈:
根据堆栈,可以看出从 LocalFrame 初始化到 DocumentLoader 构造的堆栈过程。
(src\third_party\blink\renderer\core\html\parser\html_tree_builder.cc)
在 HTMLTreeBuilder 类的 HTMLTreeBuilder::ConstructTree 实现中 打断点,查看构造tree 的堆栈:
DocumentLoader::FinishedLoading 完成加载 html 资源后,调用 HTMLDocumentParser::Finish
HTMLDocumentParser 可以理解为管理类,通过 HTMLDocumentParser 调用其他工作的类 开始解析 html。
(src\third_party\blink\renderer\core\html\parser\html_document_parser.cc)
在 HTMLDocumentParser::PumpPendingSpeculations 的开头打断点,然后跟到下图处:
其中, speculations_ 保存的是 html 信息,由 BackgroundHTMLParser::PumpTokenizer() 调用 EnqueueTokenizedChunk 拆成多组并保存。如下图堆栈:
拆分的逻辑遇到以下特征时,则进行拆分,代码如下:
将数据存放到 speculations_ 后,循环解析,在 HTMLDocumentParser::PumpPendingSpeculations 中 while 循环解析,堆栈如下:
跟踪到 HTMLDocumentParser::ProcessTokenizedChunkFromBackgroundParser 中,从 speculations_ 中的每组数据中,进行分别解析。
我们可以先看下 www.so.com 的资源:
解析 speculations_ 的第一组数据,包括如下:
观察 tokens 中的数据,便是 www.so.com 中每个元素解析后的数据:
(\src\third_party\blink\renderer\core\html\parser\html_construction_site.cc)
跟踪从 HTMLDocumentParser::ProcessTokenizedChunkFromBackgroundParser 中每个token 的之后的逻辑,
会执行到 HTMLConstructionSite::ExecuteQueuedTasks() ,堆栈如下:
将 token 中的元素进行解析构建,知道把 www.so.com 的第一个 <html class="w3c"> 解析完成后,dom tree 结构如下:
在图中可以看到,open_elements_ 中的 stack_depth_ 深度为1。
此处入栈和出栈的规则如下:
1. 遇到起始的 token,则入栈
2. 遇到结束的 token,则出栈
譬如,我们执行到下图中的 title 时
查看堆栈及数据结构:
tree_ 中 open_elements_ 为三层,之前的 meta 标签已经出栈。
将 www.so.com 的 html 资源全部解析完成后,变完成了 dom tree 的构造过程。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。