zoukankan      html  css  js  c++  java
  • 渲染引擎 & 页面渲染流程 & 阻塞

    文档对象模型(Document Object Model,简称DOM)

    浏览器渲染引擎

    • 一个渲染引擎 主要模块:
    • HTML 解析器

    解释 HTML 文档的解析器,将 HTML 文本 解析成 DOM 树

    • css 解析器

    级联样式的解析器,为 DOM 中的各个元素计算出样式信息,为布局提高基础设施

    • javascript 引擎

    使用 Javascript 代码可以修改网页的内容,也能修改 css 的信息

    javascript 引擎能够解释 javascript 代码,并通过 DOM 接口和 CSSOM 接口来修改网页内容和样式信息,从而改变渲染的结果。

    • layout 布局模块

    在 DOM 创建之后,Webkit 需要将其中的元素对象同样式信息结合起来,

    计算他们的大小位置等布局信息,形成一个能表达这所有信息的内部表示模型

    • 绘图模块

    使用 图形库 将布局计算后的各个网页的节点 绘制成 图像结果

    • 浏览器渲染页面的整个过程,浏览器会从上至下解析文档:

    以上这些模块依赖很多其他的基础模块,包括要使用到网络 存储 2D/3D图像 音频视频解码器 和 图片解码器。

    所以渲染引擎中还会包括如何使用这些依赖模块的部分。

    1. 遇见 HTML 标记

    调用 HTML 解析器解析为对应的 token (一个 token 就是一个标签文本的序列化)

    并构建 DOM 树(就是一块内存,保存着 tokens,建立它们之间的关系)

    2. 遇见 style/link 标记 调用 css 解析器 处理 CSS 标记并构建 内部表示结构 CSSOM 树

    CSS 解析器工作完成之后,在 DOM 树上附加解释后的样式信息,这就是 RenderObject 树

    RenderObject 在创建的同时,Webkit 会根据网页的结构创建 RenderLayer,同时构建一个绘图上下文

    根据 绘图上下文 生成最终的图像(这一过程需要依赖图形库)

    3. 遇见 script 标记 调用 javascript 解析器 处理 script 标记,绑定事件、修改 DOM 树 / CSSOM树 等

    4. 将 DOM 树 与 CSSOM 树 再次合并成一个渲染树 Render 树

    5. 根据 渲染树 来布局,以计算每个节点的几何信息____重排

    6. 将各个节点绘制到屏幕上____重绘

    • 上面介绍的是一个完整的渲染过程

    但现代网页很多都是动态的,这意味着在渲染完成之后,

    由于网页的动画或者用户的交互,浏览器其实一直在不停地重复执行渲染过程。(重绘重排)

    以上的数字表示的是基本顺序,这不是严格一致的,这个过程可能重复也可能交叉

    • 网页在加载和渲染过程会触发 "DOMContentLoaded" 和 "load" 事件

    ----> 分别在 DOM 树解析完成后,触发 "DOMContentLoaded"

    ----> DOM 树构建并且网页所有依赖资源都加载完成之后发生,触发 "load"

    • 实际测试

    浏览器加载资源是异步的

    用 <style> 内部样式表 写 css,是由 Parse HTML 异步解析的。

    一张图片分多次解析,其中 Parse HTML 这么快,体现了其异步执行,只是开启了一个任务,让它自己去请求资源并解析

    • css 阻塞 ---- 样式写在外部文件,在 index.css 中 link 导入

    通过 link 进来的样式 是同步解析的,由 Parse Stylesheet 进行解析

    正因为是同步解析,所以 css 解析器 会阻塞页面的渲染,从而避免了闪屏

    这也是为什么推荐使用 <style link='index.css'> 引入外部样式表

    • 阻塞
    • css 阻塞
    • <style> 标签中的样式

    1. 由 html 解析器进行解析

    2. 不阻塞浏览器渲染

    3. 不阻塞 DOM 解析

    • <link src='index.css'> 引入的外部 css 样式 (推荐使用 <link> 方式引入外部 css,可以避免闪屏现象)

    1. 由 CSS 解析器进行解析

    2. 会阻塞浏览器页面渲染(原因:避免闪屏)

    <link rel="stylesheet" href="css/my-sleep-3000-commen.css" />

    3. 不阻塞 DOM 结构的解析

    因为 DOM 解析 和 CSS 解析是两个并行的进程

    浏览器解析 DOM 生成 DOM Tree,解析 CSS 生成 CSS Tree

    最终组成 render Tree,再渲染页面,DOM 的解析,和 CSS的解析并行的。

    4. 会阻塞 js 的执行(但不会阻塞 js 等资源的加载)

    脚本在文档解析阶段会请求样式信息,如果 css 还没有完全加载解析完,脚本可能获得错误的回复

    • FireFox 会在样式表加载解析过程中,禁止所有脚本
    • 对于 WebKit 而言,仅当脚本尝试访问样式属性可能会得到错误的回复时,禁止脚本的执行

    优化方案:  (尽可能快的提高 css 加载速度)

    • 使用 CDN 加速
    • 对 css 进行压缩(用打包工具,比如 webpack, gulp 等,也可以通过开启 gzip 压缩)
    • 减少 http 请求数,将多个 css 文件合并
    • js 阻塞

    会阻塞 DOM 解析

    因为 js 可能会修改 DOM 树

    会阻塞 页面的渲染

    因为 js 代码可能会修改 DOM 树 / CSSOM 树 的结构

    js 会顺序执行,阻塞后续 js 逻辑的执行 (不阻塞 js 等其他资源的加载)

    维护依赖关系

    css 的解析 和 js 的执行 是互斥的 ( css 解析的时候 js 停止执行,js 执行的时候 css 停止解析)

    预解析

    WebKit 和 FireFox 都进行了这项优化。

    在执行 js 脚本时,其他线程会解析文档的其余部分 (只是检查,不影响原结构),找出并加载需要网络加载的其他资源

    使得这些资源在并行连接上加载,从而提高总体速度

    预解析器 不会修改 DOM 树,而是将这件事交给 主解析器 处理

    预解析器 只会解析外部资源的引用(例如外部脚本、样式、图片)

    提前发送请求,提前解析外部资源内容

     

    --------小尾巴 ________一个人欣赏-最后一朵颜色的消逝-忠诚于我的是·一颗叫做野的心.决不受人奴役.怒火中生的那一刻·终将结束...
  • 相关阅读:
    深入理解JVM内幕:从基本结构到Java 7新特性
    通过Java反射做实体查询
    Hadoop教程(一)
    很不错的js特效
    java utf8字符 导出csv 文件的乱码问题。
    spring MVC使用Interceptor做用户登录判断
    Bootstrap--全局css样式之图片
    Bootstrap-全局css样式之按钮
    Bootstrap--全局css样式之表单
    Bootstarp--全局CSS样式之表格
  • 原文地址:https://www.cnblogs.com/tianxiaxuange/p/10219347.html
Copyright © 2011-2022 走看看