WebKit技术内幕(第五章读书笔记)

78 阅读3分钟

HTML解释器

捕获.PNG HTML解释器的工作就是将网络或者本地磁盘获取的HTML网页和资源从字节流解释成DOM树结构。 首先是字节流,经过解码之后是字符流,然后通过词法分析器会被解释成词语(Tokens),之后经过语法分析器构建成节点,最后这些节点被组建成一棵DOM树。

词法分析

(1)在进行词法分析之前,解释器首先要做的事情就是检查该网页内容使用的编码格式,以便后面使用合适的解码器
如果解释器在HTML网页中找到了设置的编码格式,WebKit会使用相应的解码器来将字节流转换成特定格式的字符串。如果没有特殊的格式,词法分析器HTMLTokenizer类可以直接进行词法分析

XSSAuditor验证词语

当词语生成之后,WebKit需要使用XSSAuditor来验证词语流(Token Stream)。XSS指的是Cross Site Security,主要是针对安全方面的考虑。 根据XSS的安全机制,对于解析出来的这些词语,可能会阻碍某些内容的进一步执行,所以XSSAuditor类主要负责过滤这些被阻止的内容,只有通过的词语才会作后面的处理。

词语到节点

经过词法分析器解释之后的词语随之被XSSAuditor过滤并且在没有被阻止之后,将被WebKit用来构建DOM节点

节点到DOM树

从节点到构建DOM树,包括为树中的元素节点创建属性节点等工作由HTMLConstructionSite类来完成。

线程化的解释器

线程化的解释器就是利用单独的线程来解释HTML文档。因为在WebKit中,网络资源的字节流自IO线程传递给渲染线程之后,后面的解释、布局和渲染等工作基本上都是工作在该线程,也就是渲染线程完成的。

JavaScript的执行

在HTML解释器的工作过程中,可能会有JavaScript代码(全局作用域的代码)需要执行,它发生在将字符串解释成词语之后、创建各种节点的时候。这也是为什么全局执行的JavaScript代码不能访问DOM树的原因——因为DOM树还没有被创建完呢。

JavaScript代码可能会调用例如“document.write()”来修改文档结构,所以JavaScript代码的执行会阻碍后面节点的创建,同时当然也会阻碍后面的资源下载,这时候WebKit对需要什么资源一无所知,这导致了资源不能够并发地下载这一严重影响性能的问题

1.将“script”元素加上“async”属性,表明这是一个可以异步执行的JavaScript代码。 2.另外一种方法是将“script”元素放在“body”元素的最后,这样它不会阻碍其他资源的并发下载,

这样的网页被大量的使用,WebKit有什么办法能够处理这样的情况呢?WebKit使用预扫描和预加载机制来实现资源的并发下载而不被JavaScript的执行所阻碍。

DOM的事件机制

事件的工作过程

事件在工作过程中使用两个主体,第一个是事件(event),第二个是事件目标(EventTarget)。 每个事件都有属性来标记该事件的事件目标。当事件到达事件目标(如一个元素节点)的时候,在这个目标上注册的监听者(Event Listeners)都会被触发调用。 事件处理最重要的部分就是事件捕获(Event capture)和事件冒泡(Event bubbling)这两种机制。

影子DOM

影子DOM的规范草案能够使得一些DOM节点在特定范围内可见,而在网页的DOM树中却不可见。 当使用JavaScript代码访问HTML文档的DOM树的时候,通常的接口是不能直接访问到影子DOM子树中的节点的,JavaScript代码只能通过特殊的接口方式