浏览器渲染

作者: 好奇男孩 | 来源:发表于2018-03-24 23:05 被阅读4次

    1.浏览器如何工作

    当您在地址栏中输入“google.com”时,我们会看到会发生什么,直到您在浏览器屏幕上看到Google页面。

    浏览器的高级结构

    • 用户界面 - 包括地址栏,后退/前进按钮,书签菜单等。浏览器的每个部分都显示除了主窗口,您可以看到请求的页面。
    • 浏览器引擎 - 查询和操作渲染引擎的界面。
    • 渲染引擎 - 负责显示请求的内容。例如,如果请求的内容是HTML,则它负责解析HTML和CSS,并在屏幕上显示解析的内容。
    • 网络 - 用于网络呼叫,如HTTP请求。它具有与平台无关的接口,并在每个平台的底层实现。
    • UI后端 - 用于绘制组合框和窗口等基本小部件。它公开了一个不是平台特定的通用接口。它下面使用操作系统用户界面方法。
    • JavaScript解释器。用于解析和执行JavaScript代码。
    • 数据存储。这是一个持久层。浏览器需要保存硬盘上的各种数据,例如cookie。新的HTML规范(HTML5)定义了“web数据库”,它是浏览器中的完整(尽管是轻量级)数据库。
      注意:Chrome浏览器拥有多个渲染引擎实例 - 每个标签一个。每个选项卡是一个单独的过程。

    渲染引擎:即在浏览器屏幕上显示所请求的内容

    1..png

    1、解析HTML以构建DOM树:渲染引擎开始解析HTML文档,转换树中的html标签或js生成的标签到DOM节点,它被称为 -- 内容树。
    2、构建渲染树:解析CSS(包括外部CSS文件和样式元素以及js生成的样式),根据CSS选择器计算出节点的样式,创建另一个树 —- 渲染树。
    3、布局渲染树: 从根节点递归调用,计算每一个元素的大小、位置等,给每个节点所应该出现在屏幕上的精确坐标。
    4、绘制渲染树: 遍历渲染树,每个节点将使用UI后端层来绘制。
    范例Webkit的渲染流程


    2.png

    repaint 和 reflow

    • 渲染树的部分(或整个树)将需要重新验证,并重新计算节点维度。这被称为回流,即重新布局。
    • 屏幕的某些部分需要更新,或者是因为节点的几何属性发生了变化,或者是因为文体更改(如更改背景颜色)。此屏幕更新称为重绘
      范例:
      1.当你增加、删除、修改 DOM 结点时,会导致 Reflow 或 Repaint。
      2.当你移动 DOM 的位置,或是搞个动画的时候。
      3.当你修改 CSS 样式的时候。
      4.当你 Resize 窗口的时候(移动端没有这个问题),或是滚动的时候。
      5.当你修改网页的默认字体时。
      注:display:none 会触发 reflow,而 visibility:hidden 只会触发 repaint,因为没有发现位置变化。
      (由于与渲染树更改相关的重排和重绘费用很高,浏览器旨在减少负面影响。一种策略是简单地不做这项工作。至少不是现在,至少。浏览器将设置您的脚本需要的更改队列并批量执行它们。通过这种方式,每个需要回流的多次更改将被合并,并且只会计算一次回流。浏览器可以添加到排队的更改中,然后在一定时间过后或者达到一定数量的更改时刷新队列。)

    白屏和 FOUC

    • FOUC指无样式内容闪烁,白屏指页面会出现白屏;
    • 它们主要是由于不同浏览器处理,对于某些场景,处理的方式不同;比如如果把样式放在底部,
    • 等待CSS加载需要时间,浏览器可以选择,HTML文档直接执行渲染,逐步加载无样式的内容,等CSS加载后页面突然展现样式,这就是无样式内容闪烁;也可以等待CSS加载完成,才开始渲染页面,即页面会出现一段时间白屏。所以一般将CSS放在HTML头部位置。
    • 另外,如果不将JS放在底部,当没有延迟或异步,浏览器会立即加载并执行指定的脚本,立即”指的是在渲染该脚本标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加并执行。且只有执行完之后,才会渲染后面的文档,JavaScript放入页面顶部也可能会导致白屏现.
      注意;使用@import标签,即使CSS放入链接,并且放在头部,也可能出现白屏;

    异步加载脚本

    • 通过defer和async 可以使后续文档元素的加载渲染过程,与js脚本加载与执行,并行进行,这就是异步加载;
    • 若无defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行,这就是同步,它的影响就是只有这个脚本执行完成之后,后面的文档才能进行渲染;异步就无此副作用。
    • defer与async的区别:
      有defer的脚本执行要等到所有元素解析完成之后,DOMContentLoaded事件触发之前完成,而async不保证顺序;
    • 使用范例:
      <script async src="script.js"></script>
      script defer src="script.js"></script>

    通过写一个 server,验证白屏和 Fouc效果

    node index.js
    

    在浏览器中打开 http://localhost:8080/public/index.html

    修改 index.html 里面的引入的文件链接,加上参数 t=秒数,如

    <script src="a.js?t=3"></script
    

    表示延迟3秒加载 a.js

    [图片上传中...(2.png-adfd28-1521903854550-0)]
    2.png
    4.png
    3.png
    5.png
    6.png
    作者:彭荣辉
    链接:https://www.jianshu.com/u/0f804364a8a8
    來源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    相关文章

      网友评论

        本文标题:浏览器渲染

        本文链接:https://www.haomeiwen.com/subject/zmpccftx.html