必考面试题:浏览器怎么渲染页面的
在分析浏览器渲染过程之前,我们先了解进程和线程:
- 什么是进程?
进程是CPU进行资源分配的最小单位 - 什么是线程?
线程是CPU调度的最小单位,是建立在进程的基础上的运行单位,共享进程的内存空间,通俗点解释线程就是程序中的一个执行流,一个进程可以有多个线程
那么我们可以得出结论:进程会占用系统资源,在一个进程内可以存在一个或多个线程,这就是单线程和多线程,但是无论是单线程还是多线程,都是在一个进程内。
JS为什么是单线程?
JS的单线程,与它的用途有关,作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM,这决定了它只能是单线程,否则会带来很复杂的同步问题
比如,假定 JavaScript 同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?
浏览器的多进程
浏览器是多进程的,不同类型的标签页都会开启一个新进程,相同类型的标签页会合并成一个进程。
浏览器各个进程的主要作用如下:
- 浏览器进程 (主进程,该进程只有一个)
1.负责各个标签页的管理,创建和销毁其他进程
2.负责浏览器界面显示,与用户交互。如前进,后退等
3.负责网络资源的管理与下载 - 第三方插件进程
每种类型的插件对应一个进程,当使用该插件时才创建 - GPU进程
该进程也只有一个,负责3D/动画绘制和硬件加速 - 浏览器渲染进程
1.即通常所说的浏览器内核(Renderer进程,内部是多线程)
2.每个Tab页面都有一个渲染进程,互不影响
3.主要负责页面渲染,脚本执行,事件处理等
浏览器内核
浏览器内核就是浏览器渲染进程,从接收下载文件后再到呈现整个页面的过程,由浏览器渲染进程负责,主要的流程如下:
1.解析HTML文件和CSS文件,加载图片等资源文件,渲染成用户看到的页面。
2.执行解析js文件脚本代码。
在该过程中浏览器渲染进程会开启多个线程协作完成,主要的线程以及作用如下:
- GUI渲染线程
- js引擎线程
- 事件触发线程
- 异步http请求线程
- 定时器线程
注:GUI渲染线程与JS引擎线程是互斥的,因为JS引擎线程在执行过程中可能会发生重绘和回流,所以GUI渲染线程执行时候,JS引擎线程会被挂起,等待GUI渲染线程执行完毕才会执行;JS引擎线程执行时候同理。
渲染主流程
GUI渲染线程渲染的过程主要分为下面几步(以Chrome为例):
- 解析获取到的HTML文档,构建DOM树,同时浏览器主进程负责下载。
- CSS文件下载完成,解析CSS文件,构成层叠样式表模型CSSOM(CSS Object Model)的CSS规则树。然后结合DOM树合并成RenderObject树
- 将DOM树和CSSOM合并为渲染树(Rendering tree)。
- 有了Rendering Tree,浏览器已经能知道网页中有哪些节点、各个节点的CSS定义以及他们的从属关系,从而去计算出每个节点在屏幕中的位置,它被称之为布局layout。浏览器使用一种流式处理的方法布局。
- 按照算出来的规则,通过显卡,将渲染树的各个节点绘制到屏幕的像素信息,这一步被称为绘制painting。
- 再接下来是我们这最后一步合成( composite ),浏览器主进程将默认图层和复合图层交给GPU进程,GPU进程再将各个图层合成,最后显示出页面.
术语解释:
默认图层
: 默认图层大家就可以理解为普通文档流,因为里面不管添加多少元素,其实都是在同一个图层中,absolute 布局、 fixed 也一样,虽然可以脱离普通文档流,但它仍然属于 默认图层。
复合图层
:可以独立于普通文档流中,改动后可以避免默认图层的重绘和回流,提升性能,但也不要大量使用复合图层,否则由于资源消耗过度,页面反而会变的更卡,因小失大,最常用的方式是 transform 或者<canvas><webgl>
等元素。
Webkit的渲染流程图如下所示:
注意:
Render Tree和DOM Tree不完全对应。
DOM中不可见标签元素不会放到渲染树中,就像
<head></head>
或 display:nonevisibility: hidden的元素在渲染树中
了解GUI渲染线程的执行过程后,我们可以根据其渲染原理进行渲染优化:
- 尽可能提前引入css文件,例如在头部引入css文件。
- 简化并优化CSS选择器,尽量将嵌套层减少到最小。
- 尽可能早加载css文件中引用的资源,例如自定义字体文件,可以使用预加载,在link标签加入’rel=”preload” as=”font”‘该元素属性,不然会造成渲染阻塞。
- 在DOM和CSS渲染之后加载js文件,例如在尾部加载js文件,或者使用该元素属性”defer”和”async”,进行js文件异步加载,但是在不同浏览器会有兼容性问题。
回流和重绘(reflow和repaint)
说到资源的阻塞我们清楚的是,现代浏览器总是并行加载自语言。例如当HTML解析器被脚本阻塞时,解析器虽然会停止构建DOM,但仍然会辨识该脚本后面的资源,并进行预加载。且由于以下两点。浏览器会延迟 JavaScript 的执行和 DOM 构建:
- reflow(回流)
当浏览器发现某个部分发生了点变化影响了布局,需要倒回去重新渲染,内行称这个回退的过程叫 reflow。reflow 会从 这个 root frame 开始递归往下,依次计算所有的结点几何尺寸和位置。reflow 几乎是无法避免的。现在界面上流行的一些效果,比如树状目录的折叠、展开(实质上是元素的显 示与隐藏)等,都将引起浏览器的 reflow。鼠标滑过、点击……只要这些行为引起了页面上某些元素的占位面积、定位方式、边距等属性的变化,都会引起它内部、周围甚至整个页面的重新渲 染。通常我们都无法预估浏览器到底会 reflow 哪一部分的代码,它们都彼此相互影响着。 - repaint(重绘)
改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性时,屏幕的一部分要重画,但是元素的几何尺寸没有变。
注意:
- display:none 的节点不会被加入Render Tree,而visibility: hidden 则会,所以,如果某个节点最开始是不显示的,设为display:none是更优的。
- display:none 会触发 reflow,而 visibility:hidden 只会触发 repaint,因为没有发现位置变化。
- 有些情况下,比如修改了元素的样式,浏览器并不会立刻reflow 或 repaint 一次,而是会把这样的操作积攒一批,然后做一次 reflow,这又叫异步 reflow 或增量异步 reflow。但是在有些情况下,比如resize 窗口,改变了页面默认的字体等。对于这些操作,浏览器会马上进行 reflow。
如何减少和避免回流重绘
回流开销太大了,那么我们肯定是要优化的:
- 减少逐项更改样式,最好一次性更改 style,或者将样式定义为 class 并一次性更新
- 避免循环操作DOM,让DOM离线后再修改
1.创建一个 documentFragment ,在它上面应用所有DOM操作,最后再把它添加到 window.document
2.先把DOM节点 display:none ( 会触发一次 reflow),然后做修改后,再把它显示出来
3.克隆一个DOM节点在内存里,修改之后,与在线的节点相替换 - 避免多次读取offset等属性,无法避免则将它们缓存到变量
- 将复杂的元素绝对定位或固定定位,使得它脱离文档流,否则回流代价会很高
- 改变字体大小也会引发回流,所以尽可能减少这种操作
- table布局,一个小改动会造成整个table的重新布局,所以,少用为好
总之,说来说去,回流重绘,特别是回流,特别耗费资源,尽量避免就好
必考面试题:浏览器怎么渲染页面的相关推荐
- 2018 BAT最新《前端必考面试题》
2018 BAT最新<前端必考面试题> 1.Doctype作用? 严格模式与混杂模式如何区分?它们有何意义? (1). 声明位于文档中的最前面,处于 标签之前.告知浏览器的解析器,用什么文 ...
- (一)梳理前端知识体系,搞定大厂必考面试题
梳理前端知识体系,搞定大厂必考面试题 常见面试题 JS基础知识 变量类型和计算 原型和原型链 作用域和闭包 异步和单线程 运行环境 HTTP协议 总结 常见面试题 JS基础知识 变量类型和计算 typ ...
- java comparator_【面试题】Java必考面试题全集(15)
Java基础面试题(15) 1:Comparator 与Comparable 有什么不同? 2:Object中有哪些方法? 3:说下jdk8中的一些新特性 4:在64 位 JVM 中,int 的长度是 ...
- Vue是如何渲染页面的,渲染过程以及原理代码
Vue是如何渲染页面的,渲染过程以及原理代码:https://www.cnblogs.com/ypinchina/p/7238402.html 转载于:https://www.cnblogs.com/ ...
- 金九银十专供 | 175 道 Go 工程师必考面试题 + 详细解答
随着云计算时代的到来,Go 的应用越来越广泛,已然成为首选编程语言,而且,薪资也水涨船高. 以字节跳动为例,Go 语言是字节跳动内部使用最多的编程语言.为啥?因为字节跳动更看重效率,上手简单,学习难度 ...
- 浏览器是如何渲染页面的?
渲染的流程如下: 1.解析HTML文件,创建DOM树. 自上而下,遇到任何样式(link.style)与脚本(script)都会阻塞(外部样式不阻塞后续外部脚本的加载). 2.解析CSS. 优先级:浏 ...
- 阿里菜鸟二面:高级java面试题和答案!含阿里必考面试题赠送!
阿里菜鸟一面面试题目: 1.你比较了解的机器学习的算法有哪些,说一下这些算法的过程和区别 2.网络的体系结构分为哪五层,每层分别有哪些协议 3.TCP和UDP的区别是什么,如果想发送即时消息应该用哪种 ...
- 机器学习面试必考面试题汇总—附解析
问题:xgboost对特征缺失敏感吗,对缺失值做了什么操作,存在什么问题 不敏感,可以自动处理,处理方式是将missing值分别加入左节点 右节点取分裂增益最大的节点将missing样本分裂进这个节点 ...
- c语言必考面试题,c语言面试最必考的十道试题,求职必看!!!
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 6.free()函数 问:下面的程序会在用户输入'freeze'的时候出问题,而'zebra'则不会,为什么? #include int main(int ...
最新文章
- android上的i-jetty (1)环境搭建
- ESP32的FLASH、NVS、SPIFFS、OTA等存储分布以及启动过程
- Spring 天天用,bean 懒加载原理你懂吗?
- 怎么给国外的客户开Invoice?
- JVM内存分为哪几部分?各个部分的作用是什么?
- hadoop学习3 查找块的位置
- Java 并发编程之 CopyOnWriteArrayList
- Unity 官方教程 学习
- No space left on device 磁盘空间提示不足解决办法
- centos mysql无法启动 sock_CentOS通过yum安装MariaDB(MySQL)无法启动服务或者找不到mysql.sock...
- linux下的raid及mdadm的命令详解
- 使用微PE制作启动U盘重装系统教程
- 使用git上传代码遇到关于remote: Support for password authentication was removed on August 13, 2021.的问题
- [javascript|基本概念|Underfined]学习笔记
- 机器学习第三课--LWR的疑惑与想法
- Python实现头条自动发文章,赚点广告费!
- java源码 - SpringMVC(9)之 其他Resolver
- python适合做游戏的背景音乐是什么_适合做游戏的背景音乐
- 自上而下的因果关系:数学结构与观察者
- istio-jaeger部署