15158846557 在线咨询 在线咨询
15158846557 在线咨询
所在位置: 首页 > 营销资讯 > 网站运营 > ⭐⭐浏览器原理 之 页面形成的原理和性能优化篇

⭐⭐浏览器原理 之 页面形成的原理和性能优化篇

时间:2023-07-03 05:12:02 | 来源:网站运营

时间:2023-07-03 05:12:02 来源:网站运营

⭐⭐浏览器原理 之 页面形成的原理和性能优化篇:

(不想在本站重新排版,太麻烦了)

原本地址:




github地址:




> __大家好,我是林一一,这是一篇关于浏览器是如何渲染一个页面形成的原理,话不多说,直接开始阅读吧 __




## 001 浏览器的底层渲染页面篇

> 浏览器中的5个进程

![浏览器进程.jpg](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f91326ae9f994854a024b8cba9dc6f78~tplv-k3u1fbpfcp-watermark.image)




> 浏览器在获取服务器的资源后将 html 解析成 DOM 树,CSS 计算成 CSSOM 树,将两者合成 render tree。具体如下浏览器根据 render tree 布局生成一个页面。**需要理解的是浏览器从服务器获取回来的资源是一个个的字节码`3C 6F 6E 62 ....`等,浏览器会按照一套规范`W3C`将字节码最后解析一个个的代码字符串才成为我们看到的代码**。




### 浏览器加载资源的机制

* 浏览器会开辟一个 GUI 渲染线程,自上而下执行代码,专门用于渲染渲染页面的线程。




### 遇到 CSS 资源

* 遇到 `<style>` 内联标签会交给 GUI 渲染线程解析,但是遇到 `<link>` 标签会异步处理,浏览器会开辟一个 `HTTP` 请求处理的线程,GUI 渲染线程继续往下执行

* 如果遇到`@import` 时,也会开辟一个新的 `HTTP` 请求线程处理,由于 `@import` 是同步的 GUI 渲染线程会阻塞等待请求的结果。

> 需要注意 chrome 中,同一个源下,最多同时开辟 6-7 和 HTTP 请求线程。




### 遇到 JS 资源




![GUI渲染遇到script.jpg](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f7969f7044744ef4a2d2c00323208d74~tplv-k3u1fbpfcp-watermark.image)

> 最底部的线表示 GUI 线程的过程,渲染线程遇到不同情况下的script资源,有不同的处理。




* 遇到 `<script></script>` 资源,默认是同步的。 此时 GUI 渲染线程会阻塞。等待 JS 渲染线程渲染结束后,GUI 线程才会继续渲染。

* 如果遇到 `<script async></script>` 那么资源是异步的 `async`,浏览器也会开辟一个 `HTTP` 请求线程加载资源,这时 GUI 渲染线程会继续向下渲染,请求的资源回来后 JS 渲染线程开始执行,GUI 线程再次被阻塞。

* 如果遇到 `<script defer></script>` 和 async 类似都会开辟一个新的`HTTP`线程,GUI 继续渲染。和 async 不一样的地方在于,`defer` 请求回来的资源需要等待 GUI 同步的代码执行结束后才执行 defer 请求回来的代码。

> async 不存在资源的依赖关系先请求回来的先执行。defer 需要等待所有的资源请求回来以后,按照导入的顺序/依赖关系依次执行。







### 图片或音频

* 遇到 `<img/>` 异步,也会开辟一个新的 HTTP 线程请求资源。GUI 继续渲染,当 GUI 渲染结束后,才会处理请求的资源。




__需要注意的是:假设某些资源加载很慢,浏览器会忽略这些资源接着渲染后面的代码,在chrome浏览器中会先使用预加载器html-repload-scanner先扫描节点中的 src,link等先进行预加载,避免了资源加载的时间__




### 浏览解析资源的机制

* 浏览器是怎样解析加载回来的资源文件的? 页面自上而下渲染时会确定一个 `DOM树`,`CSSOM树`,最后 `DOM树` 和 `CSSOM树` 会被合并成 `render 树`,这些所谓的树其实都是js对象,用js对象来表示节点,样式,节点和样式之间的关系。




### DOM 树

> 所谓的 DOM 树是确定好节点之间的父子、兄弟关系。这是 GUI 渲染线程自上而下渲染结束后生成的,等到 CSS 资源请求回来以后会生成 CSSOM 样式树。




![DOM树.jpg](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a534130b659a4638a80de1400e2d7fc0~tplv-k3u1fbpfcp-watermark.image)




### CSSOM 树

> CSSOM(CSS Object Model), CSS 资源加载回来以后会被 GUI 渲染成 `样式树`




![样式树.jpg](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d19fa604ac094b428f7af6fd4dd6e02b~tplv-k3u1fbpfcp-watermark.image)




### Render tree 渲染树

> 浏览器根据 Render tree 渲染页面需要经历下面几个步骤。注意 `display:node` 的节点不会被渲染到 render tree 中




![renderTree.jpg](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0a7dbfeb2b654acd8bbe66b817f6c9ff~tplv-k3u1fbpfcp-watermark.image)

* layout 布局,根据渲染树 `计算出节点在设备中的位置和大小`。

* 分层处理。按照层级定位分层处理

* painting 绘制页面




![layout2.jpg](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f1f7cee1c99e484a82906f5dfa86b473~tplv-k3u1fbpfcp-watermark.image)

> 上面的图形就是浏览器分成处理后的显示效果




## 002 浏览器的性能优化篇

> 前端浏览器的性能优化,可以从CRP: 关键渲染路径入手

### DOM Tree

* 减少 DOM 的层级嵌套

* 不要使用被标准标签




### CSSOM

* 尽量不要使用 `@import`,会阻碍`GUI`渲染线程。

* CSS 代码量少可以使用内嵌式的`style`标签,减少请求。

* 减少使用`link`,可以减少 HTTP 的请求数量。

* CSS 选择器链尽可能短,因为CSS选择器的渲染时从右到左的。

* 将写入的 link 请求放入到`<head></head>` 内部,一开始就可以请求资源,GUI同时渲染。




### 其他资源

* `<script></script>` 中的同步 js 资源尽可能的放入到页面的末尾,防止阻碍`GUI`的渲染。如果遇到 `<script async/defer></script>` 的异步资源,GUI 渲染不会中断,但是JS资源请求回来以后会中断 GUI 的渲染。

* `<img />` 资源使用懒加载,懒加载:第一次加载页面时不要加载图片,因为图片也会占据 HTTP 的数量。还可以使用图片 base64,代表图片。




## 003 回流和重绘篇

> layout 阶段就是页面的回流期,painting 就是重绘阶段。第一次加载页面时必有一次回流和重绘。




* 浏览器渲染页面的流程

> 浏览器会先把 `HTML` 解析成 `DOM树` 计算 `DOM` 结构;然后加载 `CSS` 解析成 `CSSOM`;最后将 `DOM 和 CSSOM` 合并生成渲染树 `Render Tree`,浏览器根据页面计算 layout(重排阶段);最后浏览器按照 `render tree` 绘制(painting,重绘阶段)页面。




### 重排(DOM 回流)

> 重排是指 `render tree` 某些 `DOM` 大小和位置发生了变化(页面的布局和几何信息发生了变化),浏览器重新渲染 `DOM` 的这个过程就是`重排(DOM 回流)`,重排会消耗页面很大的性能,这也是虚拟 DOM 被引入的原因。




#### 发生重排的情况

* 第一次页面计算 layout 的阶段

* 添加或删除DOM节点,改变了 `render tree`

* 元素的位置,元素的字体大小等也会导致 DOM 的回流

* 节点的几何属性改变,比如`width, height, border, padding,margin等`被改变

* 查找盒子属性的 `offsetWidth、offsetHeight、client、scroll`等,浏览器为了得到这些属性会重排操作。

* 框架中 `v-if` 操作也会导致回流的发生。

* 等等







#### 一道小题,问下面的代码浏览器重排了几次(chrome新版浏览器为主)?

``` js

box.style.width = "100px";

box.style.width = "100px";

box.style.position = "relative";

```

> 你可能会觉得是3次,但是在当代浏览器中,浏览器会为上面的样式代码开辟一个渲染队列,将所有的渲染代码放入到队列里面,最后一次更新,所以重排的次数是1次。 问下面的代码会导致几次重排

``` js

box.style.width = "100px";

box.style.width = "100px";

box.offsetWidth;

box.style.position = "relative";

```

> 答案是2次,因为 `offsetWidth` 会导致渲染队列的刷新,才可以获取准确的 `offsetWidth` 值。最后 `position` 导致元素的位子发生改变也会触发一次回流。所以总共有2次。







### 重绘

> 重绘是指 页面的样式发生了改变但是 `DOM` 结构/布局没有发生改变。比如颜色发生了变化,浏览器就会对需要的颜色进行重新绘制。




#### 发生重绘的情况

* 第一次页面 painting 绘制的阶段

* 元素颜色的 `color` 发生改变




### 直接合成

> 如果我们更改了一个不影响布局和绘制的属性,浏览器的渲染引擎会跳过重排和重绘的阶段,直接合成

* 比如我们使用了CSS 的 transform 属性,浏览器的可以师姐合成动画效果。




__重排一定会引发重绘,但是重绘不一定会导致重排__




#### 重排 (DOM回流)和重绘吗?说一下区别

> 思路:先讲述浏览器的渲染机制->重排和重绘的概念->怎么减少重排和重绘。。。

#### 区别

> 重排会导致 `DOM结构` 发生改变,浏览器需要重新渲染布局生成页面,但是重绘不会引发 DOM 的改变只是样式上的改变,前者的会消耗很大的性能。




#### 如何减少重排和重绘

* 1. 避免使用 `table` 布局,因为 `table` 布局计算的时间比较长耗性能;

* 2. 样式集中改变,避免频繁使用 style,而是采用修改 class 的方式。

* 3. 避免频繁操作 DOM,使用vue/react。

* 4. 样式的分离读写。设置样式`style`和读取样式的`offset`等分离开,也可以减少回流次数。

* 5. 将动画效果设计在文档流之上即 `position` 属性的 `absolute` 或 `fixed` 上。使用 GPU 加速合成。










## 参考

《浏览器工作原理与实践》




[Render Tree页面渲染](探网络系列(1)-TCP三次握手&Render Tree页面渲染=>从输入URL到页面显示的过程?)




## 结束

>__感谢阅读到这里,如果这篇文章能对你有点启示或帮助欢迎给 ,我是林一一,下次见。__







**浏览器原理篇:[本地存储和浏览器缓存](浏览器原理-浏览器缓存和本地存储篇)**




**Vue 原理篇:[Vue高频原理详细解答](Vue 高频原理面试篇+详细解答)**




**webpack原理篇: [编写loader和plugin](编写 loader 和 plugins)**




[github文章合集](lurenacm/againJS)



关键词:原理,性能,形成,浏览

74
73
25
news

版权所有© 亿企邦 1997-2025 保留一切法律许可权利。

为了最佳展示效果,本站不支持IE9及以下版本的浏览器,建议您使用谷歌Chrome浏览器。 点击下载Chrome浏览器
关闭