浏览器从输入URL到页面渲染过程 ——页面渲染流程

之前我有总结过一篇经典面试题:浏览器从输入URL到页面渲染过程 ,接下里我将对某些知识点进行更细致的解析。

浏览器从输入URL到页面渲染过程 系列文章:

(一):浏览器从输入URL到页面渲染过程 —— 浏览器的进程与线程

————————————————————————————————————————————————————

浏览器从输入URL到页面渲染过程 ——页面渲染流程

浏览器的渲染机制很复杂,从输入HTML到页面输出大致分为以下这些步骤:

构建DOM树 > 构建styleSheets树 > 布局 > 分层 > 绘制 >分块 > 光栅化 > 合成
在这里插入图片描述
构建DOM树

  • 为什么要构建 DOM 树?

    因为浏览器无法直接理解和使用 HTML,所以需要将 HTML 转换为浏览器能够理解的结构——DOM 树。

    什么是树结构:节点与节点之间通过父子关系相连接。

    具体流程如下:
    在这里插入图片描述

我们在chrome的控制台输入:document ,便能看到此DOM树结构:
在这里插入图片描述
虽然 DOM树 和 HTML 看起来并没有什么的区别,但是DOM树在内存中是以树状结构存储的,可以被JS代码所查询操作。例如:

document.getElementsByTagName("p")[0].innerText = "black"

在这里插入图片描述
样式计算(构建styleSheets)

  • 为什么要构建 styleSheets ?

    和 HTML 文件一样,浏览器也是无法直接理解这些纯文本的 CSS 样式,所以当渲染引擎接收到 CSS 文本时,会执行一个转换操作,将 CSS 文本转换为浏览器可以理解的结构——styleSheets。

  • 什么是浏览器可以理解的style?

    rem/em ————> px
    color: blue ————> rgb(0, 0, 255)
    font-weight: blod ————> 700

  • CSS来源有哪些呢?

    1、通过 link 引用的外部 CSS 文件
    2、< style >标记内的 CSS
    3、元素的 style 属性内嵌的 CSS

在这里插入图片描述
如果这三个地方都有对同一标签进行样式定义,或者该标签没有被定义样式,那它的最终样式会是什么样的呢?这时候,就需要进行样式计算了。

样式计算规则:继承规则层叠规则

继承规则:当前标签的样式继承了其所有父标签的样式。
层叠规则:多个样式同时作用于该标签时,进行样式层叠。

在这里插入图片描述

当然,我们在控制台输入 document.styleSheets 看到styleSheets结构:
在这里插入图片描述
布局(构建render树)

有了 DOM树 和 styleSheets树,接下来我们就可以将两棵树进行合并,生成render树。

在这里插入图片描述
在生成render树时,浏览器首先遍历 DOM 树中的所有可见节点,并把这些节点加到布局树中,而不可见的节点会被布局树忽略掉,如 head 标签下面的全部内容,再比如 body.div.span 这个元素,因为它的属性包含 dispaly:none,所以这个元素也没有被包进布局树。

当然,这只是第一步,光有这些标签和对应的样式是无法绘出页面图的,渲染进程还需要计算出每一个标签所对应在页面上的物理位置,再将其位置存储到render树中。

分层

虽然有了render树及对应的物理坐标,但浏览器也不能直接进行页面绘制,因为页面上还涉及许多复杂的样式:transform, animation 动画、scroll,z-indexing改变层级等等,浏览器则为这些特殊的节点建立一个对应图层,生成图层树(LayerTree),将这些图层合并在一起,就是一整个页面的样式(类似于 photoshop 的图层)。

那什么时候会被提升为一个专门的图层,哪些应该被包含在同一图层?

1、拥有层叠上下文属性的元素

什么是层叠上下文?其实就是我们熟悉使用的z-index,MDN上是这么定义的:
在这里插入图片描述
其中有一句话很重要:

	重要的是,其子级层叠上下文的 z-index 值只在父级中才有意义。

不知你在使用z-index时,有没有遇到这样一个情况:

有时,你想要某一个图片或者文字 置于 某一块 的上方,于是使用z-index进行层级提升,但是就算设置了z-index确没有起作用。

正式因为 子级层叠上下文的 z-index 值只在父级中才有意义 ,只有当 父级的 position 为 absolut 或者 relative 时才有效。

2、需要剪裁的地方也会被创建为图层。

当父容器的宽高不足以撑起子容器的宽高,出现滚动条 或者 设置 父容器 为overflow :hode 等等,子容器页面就会被裁剪,这时浏览器也会为其创建出单独的图层。

如何查看图层?

打开 chrome 控制台,选择 Layers, 点击旋转按钮,对图层进行拖拽到有一定的倾斜度时,便能很直观的看到页面的图层分布 :
在这里插入图片描述
绘制

创建完图层后,接下来就是对图层进行绘制绘制,简单的说就是将图层重叠在一起。

如果给我们一张图,我们会怎样进行绘制呢?
在这里插入图片描述
一般我们会对这张图进行拆分:

1、先画出最外层的红色框图
2、在画出中间层绿色框图
3、最后画出里面层黄色框图

浏览器也是如此,将这些图层拆分为一条条的指令,然后一条一条逐步执行,最后进行绘制:
在这里插入图片描述
分块

为什么需要分块? 再此之前我们需要了解一下什么是视口:我们在当前屏幕区域能看到的模块就叫视口。当页面内容很长时,页面就会出现滚动条,但是当前视口大小有限,我们只能看到一部分,所以在这种情况下,要绘制出所有图层内容的话,就会产生太大的开销,而且也没有必要。
在这里插入图片描述
这个时候渲染进程会再次将这些图层分成很多图块。
在这里插入图片描述

格珊化

什么是格珊化?

渲染进程将这些图层分成很多图块后,然后按照视口附近的图块来通过 栅格化 优先生成位图。所谓栅格化,是指将图块转换为位图。而图块是栅格化执行的最小单位。

最后,我们来看一张流程图:
在这里插入图片描述
之前的生成DOM树、styleSheets树、render 树、分层、绘制都是在渲染引起的主线程中运行的, 绘制列表记录好绘制顺序和绘制指令的列表后,将其提交给渲染引擎中的合成线程,渲染进程还维护了一个栅格化的线程池,所有的图块栅格化都是在线程池内执行的。通常,栅格化过程都会使用 GPU 来加速生成,使用 GPU 生成位图的过程叫快速栅格化,或者 GPU 栅格化,生成的位图被保存在 GPU 内存中。

合成与显示

一旦所有图块都被光栅化,合成线程就会生成一个绘制图块的命令——“DrawQuad”,然后将该命令提交给浏览器进程。浏览器进程里面有一个叫 viz 的组件,用来接收合成线程发过来的 DrawQuad 命令,然后根据 DrawQuad 命令,将其页面内容绘制到内存中,最后再将内存显示在屏幕上。

至此,整个渲染流程就走完了,总结为以下8步:

1、渲染进程将 HTML 内容转换为能够读懂的 DOM 树结构。
2、渲染引擎将 CSS 样式表转化为浏览器可以理解的 styleSheets树,并计算好 DOM 节点的样式。
3、将DOM与styleSheets树进行合成,创建布局(render)树,并计算元素的布局信息。
4、对布局树进行分层,并生成分层树。为每个图层生成绘制列表,并将其提交到合成线程。
5、合成线程将图层分成图块。
6、在光栅化线程池中将图块转换成位图。
7、合成线程发送绘制图块命令 DrawQuad 给浏览器进程。
8、浏览器进程根据 DrawQuad 消息生成页面,并显示到显示器上。

最后抛出两个问题:

1、为什么在优化 Web 性能的方法中,减少重绘、重排是一种很好的优化方式?

结合上文我们了解到,在布局这一过程中,将DOM树与styleSheets 合成render树后,渲染进程还需要计算出每一个标签所对应在页面上的物理位置,再将其位置存储到render树中,在执行下一步。

如果我们对页面进行了重排(改变标签的宽高、显示隐藏等物理层面的几何属性),那么渲染引擎将会把这一整套渲染流程重新跑一遍,浪费时间和空间。

如果我们对页面进行了重绘(改变标签的颜色、类名等样式属性),那么渲染引擎会直接进入 绘制 阶段,相较与重排,也提升了不少性能。

如果我们的操作不涉及重排和重绘,那么渲染引擎会直接进入 合成 阶段,大大的提高了性能。

2、如果下载 CSS/JS 文件阻塞了,会阻塞 DOM 树的合成吗?会阻塞页面的显示吗?

答案是肯定的,不论CSS还是JS文件下载阻塞,都会阻塞后续的流程。当从服务器接收HTML页面的第一批数据时,DOM解析器就开始工作了。
第一种情况:在解析过程中,如果遇到了JS脚本,如下所示:

<html><body>哈哈哈<script>document.write("--限制性js脚本")</script></body>
</html>

那么DOM解析器会先执行JavaScript脚本,执行完成之后,再继续往下解析。

第二种情况:我们内联的脚本替换成js外部文件,如下所示:

<html><body>哈哈哈<script type="text/javascript" src="foo.js"></script></body>
</html>

这种情况下,当解析到JavaScript的时候,会先暂停DOM解析,并下载foo.js文件,下载完成之后执行该段JS文件,然后再继续往下解析DOM。这就是JavaScript文件为什么会阻塞DOM渲染。

第三种情况,还是看下面代码:

<html><head><style type="text/css" src = "theme.css" /></head><body><p>哈哈哈</p><script>let e = document.getElementsByTagName('p')[0]e.style.color = 'blue'</script></body>
</html>

当我在JavaScript中访问了某个元素的样式,那么这时候就需要等待这个样式被下载完成才能继续往下执行,所以在这种情况下,CSS也会阻塞DOM的解析。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/515473.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿里发布2020农产品电商报告数字农业将成风口

完美日记创立于2017年&#xff0c;这家公司上线不到两年即成为天猫彩妆销冠&#xff0c;2019年成为11年来第一个登上天猫双十一彩妆榜首的国货品牌&#xff0c;包揽天猫2019全年彩妆销冠&#xff1b;2020年4月成为首个亮相天猫超级品牌日的国货彩妆品牌&#xff0c;同时勇破彩妆…

【干货】和你谈谈数据分析报告

前言&#xff1a; -更多关于数智化转型、数据中台内容请加入阿里云数据中台交流群—数智俱乐部 &#xff08;文末扫描二维码或点此加入&#xff09; -阿里云数据中台官网 https://dp.alibaba.com/index &#xff08;作者&#xff1a;数智从业者&#xff09; 在当今企业纷纷推动…

Vue3 安装axios使用报错:Uncaught TypeError: Cannot read property ‘use‘ of undefined

最近在学习Vue3&#xff0c;使用vue cli4搭建了一个demo项目&#xff0c;安装axios后&#xff0c;控制台报错&#xff1a; Uncaught TypeError: Cannot read property use of undefinedat eval (axios.js?be3b:59)at Module../src/plugins/axios.js (app.js:1229)at __webpac…

云原生五大趋势预测,K8s安卓化位列其一

作者 | 李响、张磊 Kubernetes 本身并不直接产生商业价值&#xff0c;你不会花钱去购买 Kubernetes 。这就跟安卓一样&#xff0c;你不会直接掏钱去买一个安卓系统。Kubernetes 真正产生价值的地方也在于它的上层应用生态。 “未来的软件一定是生长于云上的”&#xff0c;这是…

centos7 linux 安装 keeplived

文章目录一、简介部署总览1. 简介2. 部署总览二、安装实战2.1. 安装环境2.2. 下载软件包2.3. 同步软件包2.4. 解压、编译、安装三、系统服务3.1. 配置复制3.2. 脚本复制3.3. 服务开机启动四、配置修改4.1. 编辑配置4.2. 140 服务器配置4.3. 141 服务器配置4.4. 启动keepalived4…

阿里人脸识别安全技术获专利可防范3D人脸面具攻击

云栖号资讯&#xff1a;【点击查看更多行业资讯】 在这里您可以找到不同行业的第一手的上云资讯&#xff0c;还在等什么&#xff0c;快来&#xff01; 当人脸识别遇上3D技术&#xff0c;谁将是最后的胜利者?长期困扰人脸识别行业的安全问题有了最新的解法。日前&#xff0c;阿…

vue3中 使用 swiper 插件,自定义切换按钮, 将 前进后退 、左右切换 按钮放到容器外部

今天在使用 swiper 时&#xff0c;遇到一个 坑爹的 问题。 swiper 组件的本来样式长这样&#xff1a; 左右切换的按钮在滑动容器内部&#xff0c;但是我们想要它跑到容器外面去。 网上找了一堆方法都不好使 也不知道是不是因为 我使用的是 高版本原因 最终实验结果&#x…

一眼看尽5G江湖,Gartner发布5G网络基础设施魔力象限报告

作者 | 白告天来源 | 边缘计算社区头图 | 下载于视觉中国近日&#xff0c;国际权威分析机构Gartner发布了首份《通信运营商5G网络基础设施魔力象限》报告。以最直观的方式展示了这一领域内各家头部企业的力量对比情况。Gartner通信运营商5G网络基础设施魔力象限该魔力象限帮助通…

一篇小文带你走进RabbitMQ的世界

云栖号资讯&#xff1a;【点击查看更多行业资讯】 在这里您可以找到不同行业的第一手的上云资讯&#xff0c;还在等什么&#xff0c;快来&#xff01; 说到消息中间件&#xff0c;大部分人的第一印象可能是Kafka。毕竟Kafka自问世以来&#xff0c;就顶着高并发&#xff0c;大流…

nginx高可用方案:keepalived+nginx vip 动态位移

文章目录一、部署总览常用命令1. 部署总览2. 常用命令二、软件安装配置2.1. 安装keepalived2.2. 安装nginx2.3. 配置静态文件三、测试3.1. 启动nginx3.2. 验证四、vip动态位移测试4.1. 140验证4.2. 141验证4.3. 140停止kp服务4.4. 141 验证4.5. 140 重新启动kp服务一、部署总览…

多角度分析平台即服务?PaaS的类型和用例

云栖号资讯&#xff1a;【点击查看更多行业资讯】 在这里您可以找到不同行业的第一手的上云资讯&#xff0c;还在等什么&#xff0c;快来&#xff01; 没有适合所有人的单一PaaS。即使云计算已经发展了10多年&#xff0c;但对云计算服务模型的定义仍然相当模糊。通常&#xff0…

未来,边缘计算的功能支柱是 Kubernetes

来源 | SDNLAB责编 | 寇雪芹头图 | 下载于视觉中国编者按在数字化转型时代&#xff0c;5G网络是一个飞跃。5G正在推动边缘计算的发展&#xff0c;而Kubernetes则是5G与边缘计算之间的粘合剂。云计算的十年云计算之于信息技术(IT)产业&#xff0c;就像石油之于汽车工业一样。云让…

如何在工作中快速成长?致工程师的10个技巧

云栖号资讯&#xff1a;【点击查看更多行业资讯】 在这里您可以找到不同行业的第一手的上云资讯&#xff0c;还在等什么&#xff0c;快来&#xff01; 作者 | 江建明 阿里巴巴高级无线开发专家 导读&#xff1a;精英人数的增长速度持续加快后&#xff0c;很多人开始焦虑&#…

在新项目中使用 Vue3 使用总结

一、使用背景 最近公司需要搭建一个新项目&#xff0c;用于做官网。因为作为官网&#xff0c;首先项目不算大&#xff0c;一共只有十来个页面&#xff0c;并且想要用户体验感很好&#xff0c;所以最终选定以 Vue 作为技术栈。 虽然 Vue3 &#xff08;中文官网&#xff09;刚问…

2020年从架构谈起到Mesh结束

作者 | 张羽辰&#xff08;同昭&#xff09;阿里云交付专家 导读&#xff1a;如今&#xff0c;几乎所有的事情都离不开软件&#xff0c;当你开车时&#xff0c;脚踩上油门&#xff0c;实际上是车载计算机通过力度感应等计算输出功率&#xff0c;最终来控制油门&#xff0c;你从…

Mendix:低代码平台四大常见用例开发

编辑 | 宋慧 供稿 | Mendix 头图 | 付费下载于视觉中国 如今&#xff0c;低代码对很多人来讲可能已经不再是一个陌生的名词。创新的低代码开发平台实现了低级别编码的抽象化和人工流程的自动化。低代码通过可视化开发工具和可重用组件&#xff0c;缩短了定制化网络和移动应用的…

下架已上线的小程序;2.设置不允许被用户搜索到

下架已上线的小程序&#xff1a; 登录微信开发者后台【设置】-【功能设置】-【暂停服务设置】-【暂停服务】&#xff0c;如图 设置小程序不允许被用户搜索到&#xff1a; 登录微信开发者后台【设置】-【功能设置】-【隐私设置】-【关闭】&#xff0c;如图 操作过程中遇到的问题…

5G新基建边缘计算乘风破浪

2019年6月6日&#xff0c;工信部向中国电信、中国移动、中国联通、中国广电发放5G商用牌照&#xff0c;这意味着中国正式进入5G元年。一年以来&#xff0c;随着基站的建设与用户认知的提升&#xff0c;5G应用如雨后春笋般涌现。而在今年上半年频繁被提及的“新基建”中&#xf…

那些年,我在阿里当数据开发

前言&#xff1a; -更多关于数智化转型、数据中台内容请加入阿里云数据中台交流群—数智俱乐部 &#xff08;文末扫描二维码或点此加入&#xff09; -阿里云数据中台官网 https://dp.alibaba.com/index &#xff08;作者&#xff1a;数据从业者 &#xff09; 我是阿里数据部…