• 浏览器的工作原理幕后揭秘的部分笔迹摘要


    以前或多或少看过几位比较牛逼的工程师写过浏览器工作原理的分析文章,虽然很好很强大的样子,但是看完总觉得自己对浏览器工作原理没有一个全局的度,总是欠缺了好多;

    耐不住寂寞啊,就跑去坚果看过去收藏的一篇旧文,一篇冗长的,长达数万字的文章,然后..........然后就把边看边给自己做一个摘要,以后需要那部分的知识就看哪里。文章部分内容为我断章取义和自己标注部分理解,原文在这里 

    浏览器主要组件

          用户界面 、 浏览器引擎 、 呈现引擎 、 网络 、 用户界面后端 、JavaScript 解释器、 数据存储  

       呈现引擎 

             解析html->dom树->绘制dom树结构(这期间附加style rules)->布局dom数据(reflow)->浏览器中绘制->呈现

     

        解析引擎

         通过解析器和词法分析器组合(其中格局各种规则、词汇、语法构建解析树,各种云云)     

      标记化算法

            (根据标记化算法生成html标记

        初始状态是数据状态。遇到字符 < 时,状态更改为“标记打开状态”。接收一个 a-z 字符会创建“起始标记”,状态更改为“标记名称状态”。这个状态会一直保持到接收 > 字符。在此期间接收的每个字符都会附加到新的标记名称上。在本例中,我们创建的标记是 html 标记。

        遇到 > 标记时,会发送当前的标记,状态改回“数据状态”。<body> 标记也会进行同样的处理。目前 html 和 body 标记均已发出。现在我们回到“数据状态”。接收到 Hello world 中的 H 字符时,将创建并发送字符标记,直到接收 </body> 中的 <。我们将为 Hello world 中的每个字符都发送一个字符标记。

        现在我们回到“标记打开状态”。接收下一个输入字符 / 时,会创建 end tag token 并改为“标记名称状态”。我们会再次保持这个状态,直到接收 >。然后将发送新的标记,并回到“数据状态”。</html> 输入也会进行同样的处理。

      

          构建dom树流程:

         initial mode->before html(创建一个 HTMLHtmlElement 元素,并将其附加到 Document 根对象上) -> before head(没有“head”标记,系统也会隐式创建一个 HTMLHeadElement,并将其添加到树中)->in head(构建head内的标签)->after head(创建并插入 HTMLBodyElement,插入document中)->in body(构建body内的标签,知道接受</body>结束并触发下一模式)->after body(接收 HTML 结束标记)->after after body(解析结束)。

      解析结束后的操作:

      在此阶段,浏览器会将文档标注为交互状态,并开始解析那些处于“deferred”模式的脚本,也就是那些应在文档解析完成后才执行的脚本。然后,文档状态将设置为“完成”,一个“加载”事件将随之触发。

      浏览器的容错机制:

    1.  非标准标记标签
    2. 元素之间的嵌套有误
    3. 离散表格
    4. 在一个表单元素中又放入了另一个表单
    5. 复杂的标记层次结构
    6. 放错位置的 html 或者 body 结束标记(在构建dom树的时候解析不是真正意义上的根据</body></html>停止解析,调用 end() 来执行关闭操作)等等

    CSS 解析:

      和 HTML 不同,CSS 是上下文无关的语法,解析器会将 CSS 文件解析成 StyleSheet 对象,且每个对象都包含 CSS 规则。CSS 规则对象则包含选择器和声明对象,以及其他与 CSS 语法对应的对象

    处理脚本和样式表的顺序

      脚本

      网络的模型是同步的。网页作者希望解析器遇到 <script> 标记时立即解析并执行脚本。文档的解析将停止,直到脚本执行完毕。如果脚本是外部的,那么解析过程会停止,直到从网络同步抓取资源完成后再继续。此模型已经使用了多年,也在 HTML4 和 HTML5 规范中进行了指定。作者也可以将脚本标注为“defer”,这样它就不会停止文档解析,而是等到解析结束才执行。HTML5 增加了一个选项,可将脚本标记为异步,以便由其他线程解析和执行。

      预解析

      Webkit 和 Firefox 都进行了这项优化。在执行脚本时,其他线程会解析文档的其余部分,找出并加载需要通过网络加载的其他资源。通过这种方式,资源可以在并行连接上加载,从而提高总体速度。请注意,预解析器不会修改 DOM 树,而是将这项工作交由主解析器处理;预解析器只会解析外部资源(例如外部脚本、样式表和图片)的引用。

      样式表

      另一方面,样式表有着不同的模型。理论上来说,应用样式表不会更改 DOM 树,因此似乎没有必要等待样式表并停止文档解析。但这涉及到一个问题,就是脚本在文档解析阶段会请求样式信息。如果当时还没有加载和解析样式,脚本就会获得错误的回复,这样显然会产生很多问题。这看上去是一个非典型案例,但事实上非常普遍。Firefox 在样式表加载和解析的过程中,会禁止所有脚本。而对于 Webkit 而言,仅当脚本尝试访问的样式属性可能受尚未加载的样式表影响时,它才会禁止该脚本。

     ..........还在进行中

  • 相关阅读:
    关押罪犯
    文化之旅
    [USACO11OPEN]玉米田迷宫Corn Maze
    排队布局
    最短路计数
    【模板】单源最短路径(标准版)
    最短路径问题
    无向图最小环
    localStorage的使用
    移动端如何引入日期插件
  • 原文地址:https://www.cnblogs.com/God-Shell/p/3234089.html
Copyright © 2020-2023  润新知