【干货】十分钟读懂浏览器渲染流程

在之前写过的一篇《"天龙八步"细说浏览器输入URL后发生了什么》一文中,和大家分享了从在浏览器中输入网址URL到最终页面展示的整个过程。部分读者向我反馈对于最后的浏览器渲染布局这块不是很清晰,所以本文就浏览器渲染流程单独开篇讲解,希望大家都能有新的收获。

浏览器主要组件结构

(浏览器主要组件)

渲染引擎——webkit和Gecko

Firefox使用Geoko——Mozilla自主研发的渲染引擎。

Safari和Chrome都使用webkit。Webkit是一款开源渲染引擎,它本来是为linux平台研发的,后来由Apple移植到Mac及Windows上。

本文我主要以webkit渲染引擎来讲解,尽管webkit和Gecko使用的术语稍有不同,他们的主要流程基本相同。

(webkit渲染引擎流程)

关键渲染路径

关键渲染路径是指浏览器从最初接收请求来的HTML、CSS、javascript等资源,然后解析、构建树、渲染布局、绘制,最后呈现给客户能看到的界面这整个过程。

所以浏览器的渲染过程主要包括以下几步:

  1. 解析HTML生成DOM树。

  2. 解析CSS生成CSSOM规则树。

  3. 将DOM树与CSSOM规则树合并在一起生成渲染树。

  4. 遍历渲染树开始布局,计算每个节点的位置大小信息。

  5. 将渲染树每个节点绘制到屏幕。

构建DOM树

当浏览器接收到服务器响应来的HTML文档后,会遍历文档节点,生成DOM树。

需要注意的是,DOM树的生成过程中可能会被CSS和JS的加载执行阻塞。渲染阻塞问题下文会讲。

构建CSSOM规则树

浏览器解析CSS文件并生成CSS规则树,每个CSS文件都被分析成一个StyleSheet对象,每个对象都包含CSS规则。CSS规则对象包含对应于CSS语法的选择器和声明对象以及其他对象。

渲染阻塞

当浏览器遇到一个 script 标记时,DOM 构建将暂停,直至脚本完成执行,然后继续构建DOM。每次去执行JavaScript脚本都会严重地阻塞DOM树的构建,如果JavaScript脚本还操作了CSSOM,而正好这个CSSOM还没有下载和构建,浏览器甚至会延迟脚本执行和构建DOM,直至完成其CSSOM的下载和构建。


所以,script 标签的位置很重要。实际使用时,可以遵循下面两个原则:

CSS 优先:引入顺序上,CSS 资源先于 JavaScript 资源。
JS置后:我们通常把JS代码放到页面底部,且JavaScript 应尽量少影响 DOM 的构建。


当解析html的时候,会把新来的元素插入dom树里面,同时去查找css,然后把对应的样式规则应用到元素上,查找样式表是按照从右到左的顺序去匹配的。

例如: div p {font-size: 16px},会先寻找所有p标签并判断它的父标签是否为div之后才会决定要不要采用这个样式进行渲染)。
所以,我们平时写CSS时,尽量用id和class,千万不要过渡层叠。

构建渲染树

通过DOM树和CSS规则树我们便可以构建渲染树。浏览器会先从DOM树的根节点开始遍历每个可见节点。对每个可见节点,找到其适配的CSS样式规则并应用。


渲染树构建完成后,每个节点都是可见节点并且都含有其内容和对应规则的样式。这也是渲染树与DOM树的最大区别所在。渲染树是用于显示,那些不可见的元素当然就不会在这棵树中出现了,譬如。除此之外,display等于none的也不会被显示在这棵树里头,但是visibility等于hidden的元素是会显示在这棵树里头的。

渲染树布局

布局阶段会从渲染树的根节点开始遍历,然后确定每个节点对象在页面上的确切大小与位置,布局阶段的输出是一个盒子模型,它会精确地捕获每个元素在屏幕内的确切位置与大小。

渲染树绘制

在绘制阶段,遍历渲染树,调用渲染器的paint()方法在屏幕上显示其内容。渲染树的绘制工作是由浏览器的UI后端组件完成的。

reflow与repaint:

根据渲染树布局,计算CSS样式,即每个节点在页面中的大小和位置等几何信息。HTML默认是流式布局的,CSS和js会打破这种布局,改变DOM的外观样式以及大小和位置。这时就要提到两个重要概念:replaint和reflow。
replaint:屏幕的一部分重画,不影响整体布局,比如某个CSS的背景色变了,但元素的几何尺寸和位置不变。
reflow: 意味着元件的几何尺寸变了,我们需要重新验证并计算渲染树。是渲染树的一部分或全部发生了变化。这就是Reflow,或是Layout。
所以我们应该尽量减少reflow和replaint,我想这也是为什么现在很少有用table布局的原因之一。

display:none 会触发 reflow,visibility: hidden属性并不算是不可见属性,它的语义是隐藏元素,但元素仍然占据着布局空间,它会被渲染成一个空框,所以visibility:hidden 只会触发 repaint,因为没有发生位置变化。

有些情况下,比如修改了元素的样式,浏览器并不会立刻 reflow 或 repaint 一次,而是会把这样的操作积攒一批,然后做一次 reflow,这又叫异步 reflow 或增量异步 reflow。
有些情况下,比如 resize 窗口,改变了页面默认的字体等。对于这些操作,浏览器会马上进行 reflow。

小结

本文我们就浏览器渲染流程逐步了解了一遍,相信大家一定都有所新的收获,如果大家对于浏览器渲染流程还有任何疑问,欢迎反馈,我们共同交流,共同学习,共同进步。

      

关注我的微信公众号,分享更多技术干货!


参考文献:

http://taligarsiel.com/Projects/howbrowserswork1.htm

https://segmentfault.com/a/1190000012960187

https://sylvanassun.github.io/2017/10/03/2017-10-03-BrowserCriticalRenderingPath/

https://www.zybuluo.com/lizlalala/note/435042


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

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

相关文章

控制台资费管理主菜单java_java毕业设计_springboot框架的高速公路收费管理系统...

今天介绍一个java毕设题目, 题目内容为springboot框架的高速公路收费管理系统, 是一个采用b/s结构的javaweb项目, 采用java语言编写开发工具eclipse, 项目框架jspspringbootmybatis, 高速公路收费管理系统的信息存储于mysql中, 并基于mybatis进行了orm封装, 该高速公路收费管理…

在Amazon EMR上运行Hadoop MapReduce作业

不久前,我发布了如何使用CLI设置EMR群集的信息。 在本文中,我将展示如何使用适用于AWS的Java SDK来设置集群。 展示如何使用Java AWS开发工具包执行此操作的最佳方法是展示完整的示例,因此,让我们开始吧。 设置一个新的Maven项目…

[JSConf EU 2018] 大脑控制 Javascript

先解释,本人为前端菜鸟,之前也未参加过类似的活动,没有翻译过什么文章,此次是好奇心使然,也是想尝试下,学习学习,英文很烂,全靠有道,但是视频整个看下来,还是…

JavaScript中不得不说的断言?

断言主要应用于“调试”与“测试” 一、前端中的断言 仔细地查找一下JavaScript中的API,实际上并没有多少关于断言的方法。唯一一个就是console.assert: // console.assert(condition, message)const a 1console.assert(typeof a number, a should be…

Java EE状态会话Bean(EJB)示例

在本文中,我们将了解如何在简单的Web应用程序中使用状态会话Bean来跟踪客户端会话中的状态。 1.简介 有状态会话Bean通常保存有关特定客户端会话的信息,并在整个会话中保留该信息(与无状态会话Bean相对)。 有状态EJB实例仅与一个…

起点海外版 Hybrid App-内嵌页优化实践

本文作者:刘文涛 原创声明:本文为阅文前端团队 YFE 成员出品,请尊重原创,转载请联系公众号 (id: yuewen_YFE) 获取授权,并注明作者、出处和链接。 今年年初我司开启了起点品牌的海外之旅,名为「 Webnovel 」…

aix 卸载mysql_AIX 删除数据库及集群软件

一、 删除数据库1、用dbca自动删库在CRT上无法打开dbca图形界面,要安装一个Xmanage软件,用Xstart连接终端,并修改oracle用户的.profile,加上“export DISPLAY192.168.8.120:0.0”Xstart配置信息如下:2、手工删除数据库…

如何在github中的readme.md加入项目截图

1. 先在之前的本地项目文件夹里创建一个存放截图的文件夹。(如img文件夹) 2. 将新增的内容通过github desktop上传到github中 3. 在github中立马能看到刚刚上传的图片,打开图片,点击Download 4. 直接复制地址栏的网址 5. 最后在RE…

记表格设计规范整理与页面可视化生成工具开发

前言 公司有一个项目在维护,大概有300左右,其中表单与表格的页面占比大概百分之五六十,为了节省开发时间,避免多人协作时,出现多套冗余代码,我们尝试写了一下表单和表格的生成工具,从梳理到规范…

java仿qq空间音乐播放_完美实现仿QQ空间评论回复特效

评论回复是个很常见的东西,但是各大网站实现的方式却不尽相同。大体上有两种方式1.像优酷这种最常见,在输入框中要回复的人,这种方式下,用www.cppcns.com户可以修改。新浪微博则是在这个基础上,弹出好友菜单。这种方式…

使用签名保护基于HTTP的API

我在EMC上的一个平台上可以构建SaaS解决方案。 与越来越多的其他应用程序一样,该平台具有基于RESTful HTTP的API。 使用像JAX-RS这样的开发框架,构建这样的API相对容易。 但是, 正确构建它们并不容易。 建立基于HTTP的API的问题 问题不仅…

Python开发【模块】:Celery 分布式异步消息任务队列

前言: Celery 是一个 基于python开发的分布式异步消息任务队列,通过它可以轻松的实现任务的异步处理, 如果你的业务场景中需要用到异步任务,就可以考虑使用celery, 举几个实例场景中可用的例子: 你想对100台机器执行一…

iOS开发者的一些前端感悟

很多前端工程师会把自己比作“魔法师”,而对于JavaScript这门语言,我也想把它唤作一门“有魔力的语言”。因为这群有无限想法的人,真的在用它创造各种让你惊叹的事物。 Web三件套一、前言 几年前,笔者还是一名初涉编程的学生&…

windows下github 出现Permission denied (publickey)

github教科书传送门:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 再学习到"添加远程仓库"的时候遇到了 Permission denied (publickey) 这个问题, 总结来说以前的步骤如下所示: 1、git config --glo…

[UE4]嵌套Canvas

转载于:https://www.cnblogs.com/timy/p/9090642.html

写博客的这几个月,获益良多

1.前言 也将近过年了,看了那么多人搞了年会总结。自己活跃社区这几个月,改变了不少,收获也不少。就想写下这段时间写文章的一些总结,统计下‘成绩’,说下感想,就写了这篇文章。这次总结的关键词就是&#x…

shiro 权限 URL 配置细节

转载于:https://www.cnblogs.com/hwgok/p/9100277.html

2016 年崛起的 JS 项目

本文是我对中文版 risingstars2016 的整理,而本人就是中文版的译者,首发于知乎专栏 前端周刊。共 21384 字,读完需 30 分钟,速读需 5 分钟。长江后浪推前浪,如果你能花 30 分钟读完我 6 个小时翻译的内容,相…

php 开启命令模式,如何启用PhpStorm中的命令行工具

本篇文章主要给大家介绍如何使用phpstorm中的命令行工具。PhpStorm下载地址:PhpStorm使用命令行工具,我们可以直接从IDE调用命令!在我们使用任何命令行工具之前,我们必须在设置中启用它。涉及到的步骤如下:使用命令行工…

React Native项目自动化打包发布

今天这篇文章的目的是在rn项目的构建,并不会涉及到rn框架或者使用的讲解,说起构建,特别是前端构建大家应该很快会想到webpack、Grunt、 Gulp等。而这些工具在rn项目中就显得有些鸡肋。所以在此给大家分享一下不使用构建工具实现rn项目自动化打…