JavaScript 浏览器原理(一)

364 阅读7分钟

JavaScript 浏览器原理(一)

JavaScript 浏览器原理 向浏览器输入URL 后的解析过程

在我们的浏览器的渲染过程中,我们首先需要做的就是向我们的浏览器中输入一个 URL,或者输入一个域名

然后浏览器通过DNS 解析这个域名或者URL ,来实现访问我们的服务器主机,服务器主机就把静态资源实现返回

浏览器就会对这些静态资源进行下载实现,一般就是下载的是我们的 index.html

浏览器对其进行一步一步的解析,遇到了外部的 link 的CSS样式,那就又向服务器发送请求下载对应的CSS样式回来即可

image-20241106213605466.png

JavaScript 浏览器原理 浏览器渲染页面的流程

对静态资源解析的是谁呐???

实现解析这些静态资源就是使用的是我们的浏览器内核,浏览器内核是一个浏览器的核心

常见的浏览器内核含有:

  • Trident
  • Gecko
  • Presto
  • Webkit
  • Blink

浏览器内核指的是什么耶???

  • 排版引擎(layout engine)就是我们的浏览器内核
  • 其他的别名: 浏览器引擎(browser engine)|页面渲染引擎(rendering engine)|样板引擎

image-20241106220743924.png

解析流程一: 解析HTML

我们的客户端实现向服务端发送请求的时候,首先实现的是将 index.html 实现请求回来下载

解析的流程是从上到下实现的解析,在实现进行解析 HTML 的时候,会生成我们的 DOM Tree

如果说是遇到了从外部 link 的 CSS 样式,那就重新向我们的静态资源服务器发送请求进行下载

解析流程二:解析CSS

实现解析我们的 CSS 的时候,这个流程是不会阻塞解析HTML文档的继续解析的

在解析CSS的时候,浏览器实现的是重新开辟了一个线程实现的解析

同时在解析CSS的时候,同时实现生成CSS的规则

同时这个时候生成了我们的一个 CSSOM (CSS Object Model)【CSS对象模型】

解析流程三:生成Render Tree

image-20241106232358155.png

进行了上面两步的解析后,DOM Tree 和 CSSOM 实现绑定,共同生成了我们的 渲染树

在实现生成的渲染树,只是实现的是将元素的节点这些在页面上实现设置好,但是是不会涉及到元素的位置以及大小等信息的

所以说在实现解析CSS的时候,这一步的解析是不会阻塞DOM Tree 的生成的,但是是会阻塞渲染树的生成的,但是浏览器可以实现优化的

那为什么会阻塞呐???

  • 发生阻塞的话就是因为我们的 渲染树 Render Tree 是需要我们的CSSOM 的参与合成的,所以说CSS的解析会阻塞Render Tree的原因就是这样
  • 但是浏览器为了实现优化这个操作,浏览器可能就会把前面实现渲染好的部分直接先实现呈现出来

还需要注意的一点就是我们的 DOM Tree 和 Render Tree 并不是一一对应的:

比如说我们设置了我们的元素盒子的显示模式为: display: none,那么这个时候我们的这个元素就不会进入 Render Tree 中去的

解析流程四:布局|排版(Layout)

在 Render Tree 的基础之上,我们就需要布局(layout)来实现计算DOM Tree 生成的每一个节点的几何体

  • 渲染树表示的是我们在页面上面需要呈现那些节点以及样式的,但是是不会涉及到每一个节点的尺寸或者位置的信息的
  • 但是布局实现的就是我们的将每一个节点的宽度、高度、位置信息实现渲染

解析流程五:绘制(Paint)

在绘制阶段,浏览器将布局阶段实现计算好的每一个DOM Tree 中的节点的高度、宽度、位置信息转化为屏幕上的实际的像素点

包括将元素的可见部分实现重新绘制,比如文本、颜色、边框、阴影、替换元素等等

image-20241106233905308.png

JavaScript 浏览器原理 回流(reflow)和 重绘(rePaint)

JavaScript 回流【重排】(reflow|relayout)

第一次实现确定DOM Tree 中的节点大小和位置的,这个就是布局(Layout)

之后的每一次对节点的大小,位置修改,进行重新计算称之为回流

我们发生回流的条件是什么呐???

  • 页面中的元素的节点的消失或者大小的变化

  • 页面中元素属性的改变导致元素整体的重新渲染

  • 实现回流的最重要的一步就是元素会重新布局才会引发回流

    • 比如说修改一个元素中的文本颜色,这样的修改是不会引发回流的

引发回流的情形:

  • 页面中的 DOM 树发生了变化(添加节点或者移除节点)
  • 修改节点的布局导致大小或者位置的改变,这个就会重新进行计算,引发回流(width, height,padding,left)
  • 窗口的 resize(窗口大小的改变)
  • 通过getComputedStyle 方法获取的尺寸,位置信息的修改

需不需要避免回流耶???

  • 答案的话,那肯定是需要的
  • 如果说对页面进行重新计算大小位置等信息的话,这个时候引发回流,那么页面有需要进行重新绘制
  • 这个实际上是一个非常吃性能的操作,所以说尽量避免回流或者说减少实际开发中导致回流的操作即可

如何可以实现减少触发回流的概率呐???

  • 修改样式一次性进行修改

    • 直接通过DOM操作的添加CSS来实现一次性修改
    • 不要通过DOM操作 style 来进行修改样式
  • 不要频繁的操作 DOM

    • 对于原生开发来说,平时除了操作DOM,我还可以做什么耶???
    • 对的原生开发的的确确是避免不了操作DOM的
    • 但是在后期的 Vue 和 React 的开发框架中,其最大的一点就是尽可能的减少我们对DOM的操作,后面就是使用的 虚拟DOM了
  • 减少使用 getComputedStyle 来实现获取节点的尺寸和位置等信息

  • 可以实现将某些元素设置为 position 为 absolute 或者 fixed

    • 注意这个还是可能会引发回流,但是只不过的话,在一定的程度上是实现了减少性能的开销

JavaScript 重绘(repaint)

第一次渲染内容称为绘制

之后实现的重新绘制就是重绘

引发重绘的条件是什么耶???:

  • 修改背景颜色
  • 修改文字颜色
  • 修改边框颜色
  • 修改一些不会引发回流的样式

我们的重绘是不会引发回流的,但是回流是一定会触发重绘

所以说重绘消耗的性能方面的话是比回流消耗的性能要小的

JavaScript 浏览器原理 特殊解析 - composite合成

绘制的过程中,可以将布局后的元素实现会知道同一个合成层中(CompositingLayer

  • 这个是浏览器提供的一种优化手段

  • 当我们的网页中存在多个层级的时候,可能导致的就是网页中因为这个原因,有很多 DOM Tree中的节点不用呈现出现

    • 这个时候,浏览器做的就是只将需要进行渲染的节点实现渲染绘制出来即可
    • 这样的处理模式在很大的程度上实现了我们的性能的优化
  • 浏览器对每个合成层的处理规则

    • 每一个的合成层的话都是实现的是单独实现渲染
    • 我们是可以通过 GPU 优化来实现加速绘制过程的

引发合成层的情形

  • 3D transforms
  • video | canvas | iframe
  • opacity 动画转换时
  • position: fixed
  • animation 或者 transition 设置了 opacity 、transform

如何通过浏览器调试者工具观看 layer

  • 首先先进行鼠标右键,选择检查
  • 然后选择调试者工具中的一个选项

image-20241107012843525.png

  • 点击进入选择 More tools

image-20241107012940739.png

  • 选择 layers

image-20241107013109973.png

  •     <!doctype html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport"
                  content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
            <meta http-equiv="X-UA-Compatible" content="ie=edge">
            <title>Document</title>
            <style>
                .box, .container {
                    width: 200px;
                    height: 200px;
                }
        ​
                .box {
                    background-color: skyblue;
                }
        ​
                .container {
                    position: fixed;
                    background-color: red;
                }
            </style>
        </head>
        <body>
        <div class="box"></div>
        <div class="container"></div>
        </body>
        </html>
    

image-20241107013449687.png

**本章节先结束,后面继续分析浏览器的其他原理,哈哈哈!!! **😄 😄😄

这个就是我们的浏览器的一些渲染原理,本次主要讲解渲染静态页面的一些操作,但是JS的浏览器的原理还没有进行讲解,下一篇补充讲解!!!