浏览器原理

这篇博客详细介绍了浏览器的工作原理,包括浏览器的基本构成、浏览器内核、渲染引擎和JS引擎的工作流程,以及浏览器中的进程与线程。重点阐述了渲染引擎如何解析HTML、构建DOM树和Render树,以及JS引擎的作用。此外,还讨论了浏览器的多进程模型,如Browser进程、渲染进程、GPU进程,以及各进程间通信的方式。同时,文章深入解析了浏览器中的线程,如GUI渲染线程、JS引擎线程、事件触发线程、定时器触发线程和异步HTTP请求线程,并探讨了回流与重绘的概念以及优化策略。

浏览器构成

基本概念

1、浏览器分类(五个主流):chrome(内核:blink基于webkit)、
safari(webkit)、firefox(gecko)、ie(triddent)、opera(blink)

2、浏览器的构成:用户界面、浏览器引擎(查询与操作渲染引擎的接口)、渲染引擎、js解析、数据存储、网络(请求)、ui后端

浏览器内核构成:渲染引擎和js引擎(但是由于js引擎越来越独立,所以浏览器内核就单指渲染引擎)

渲染引擎
作用:解析html并显示出来
流程:解析html以构建dom树 -> 构建render树 -> layout布局render树 -> 绘制render树
dom树:html文档中的元素及其节点构成
render树:可见元素(比如head元素就是不可见)及其盒子、样式(displaynone属于不可见样式)

js引擎
这里有个nodejs引擎,这是基于谷歌浏览器js引擎(v8引擎)进行的封装)

3、浏览器作用:将用户选择的资源呈现出来

浏览器中的进程与线程

比喻:cpu-工厂 进程-车间 线程-工人
在这里插入图片描述
浏览器进程
浏览器有多个进程,一个主进程,如下:
1、browser进程:主进程,一个,作用协调、主控
2、浏览器渲染进程:每打开一个tab网页就相当于开了一个渲染进程实例,进程之间相互独立,不共享资源
3、第三方插件进程:一个,每一类插件对应一个进程,仅当使用该插件时才创建
4、GPU进程:3D绘制

多进程的优缺点:如果浏览器是单进程,那么某个 Tab 页崩溃了,就影响了整个浏览器,体验有多差;同理如果是单进程,插件崩溃了也会影响整个浏览器;当然内存等资源消耗也会更大

浏览器进程与浏览器内核进程的通信
a、Browser进程收到用户获取页面内容请求,将该任务通过RendererHost接口传递给Render进程
b、Renderer进程的Renderer接口收到消息,交给渲染线程,然后开始渲染
c、渲染线程接收请求,加载网页并渲染网页,可能需要Browser进程获取资源和需要GPU进程来帮助渲染,会有JS线程操作DOM(回流、重绘)
d、最后Render进程将结果传递给Browser进程
e、Browser进程接收到结果并将结果绘制出来

浏览器中的线程
确切的应该是浏览器内核的线程,即渲染进程的线程,多个,每个tab页是有多线程的,线程如下:
1、GUI渲染线程
作用:将html文件渲染到浏览器界面
流程:构建 DOM 树、构建渲染树、布局、绘制、渲染层合成(composite) ,具体如下:
a、构建dom树:解析html和css,将元素与其节点构建DOM树和CSSOM树(css是由下载线程异步下载的,不会阻塞html解析,但是会阻塞render树和js解析,所以优化上把link标签的css放在顶部
b、构建render树:根据DOM树从根节点开始遍历可见节点;针对每个可见节点寻找CSSOM树中的几何属性样式;合成构建render树
c、布局(layout):根据构建好的render树进行位置和大小的计算(回流),根据计算好的几何属性进行layout布局
d、绘制(Paint):遍历渲染树,调用渲染器的 paint() 方法将布局中的节点转换成界面上的实际像素。该过程有一些不影响布局的 CSS 修改引起的屏幕局部重画,称为重绘(Repaint)。绘制过程是在多个层上完成的,这些层称为渲染层(RenderLayer)。
e、渲染层合成(composite):渲染层根据层叠顺序合并生成位图,交给显卡展示在屏幕上
在这里插入图片描述
回流与重绘

参考网址:https://www.cnblogs.com/chenjg/p/10099886.html
a、概念:
回流:dom树中的可见节点与cssom树中的样式结合起来后,还需要重新从根节点开始计算节点在设备视口(viewpoint)中位置和几何信息(大小等),这一计算的过程叫做回流。大部分回流是发生在布局之前的,一旦发生变化就会回流重新进行部分或者全部的布局。回流一定重绘
重绘:我们知道了可见节点以及可见节点的样式和位置信息,将渲染树中的每个节点都转换成屏幕上的具体像素,这一过程叫做重绘。重绘不一定回流

b、哪些操作会导致回流:
(1)浏览器的视口发生了变化
(2)页面第一次加载
(3)增删dom元素
(4)改变元素的几何属性(边距、填充、边框、宽度和高度等)
(5)元素位置发生变化
(6)内容变化(文本或者图片发生变化)

c、浏览器本身的优化:
浏览器维护了1个队列,把所有会引起回流、重绘的操作放入这个队列,等队列中的操作到了一定的数量或者到了一定的时间间隔,进行一个批处理。这样就会让多次的回流、重绘变成一次回流重绘。
但是当你请求向浏览器请求一些 style信息的时候,就会让浏览器flush队列:
offsetTop, offsetLeft, offsetWidth, offsetHeight
scrollTop/Left/Width/Height
clientTop/Left/Width/Height
width,height
请求了getComputedStyle(), 或者 IE的 currentStyle

d、性能优化:
(1)样式方面:合并css样式或者修改className,例子如下:

el.style.cssText += 'border-left: 1px; border-right: 2px; padding: 5px;';
el.className += ' active';

多使用f’lexbox流式布局,将元素定位在屏幕上
(2)dom节点方面:
方法一:先隐藏元素–>修改–>重新显示 (2次回流)

function appendDataToElement(appendToElement, data) {
    let li;
    for (let i = 0; i < data.length; i++) {
    	li = document.createElement('li');
        li.textContent = 'text';
        appendToElement.appendChild(li);
    }
}
const ul = document.getElementById('list');
ul.style.display = 'none';
appendDataToElement(ul, data);
ul.style.display = 'block';

方法二:使用文档片段(document fragment)在文档流外面创建一个子树,再将他拷贝回文档

const ul = document.getElementById('list');
const fragment = document.createDocumentFragment();  //创建文档片段子树
appendDataToElement(fragment, data);
ul.appendChild(fragment);

方法三:拷贝到一个脱离文档流的节点中,修改节点后再替代原始节点

const ul = document.getElementById('list');
const clone = ul.cloneNode(true);
appendDataToElement(clone, data);
ul.parentNode.replaceChild(clone, ul);

方法四:css3硬件加速(GPU加速,加速页面渲染,减少CPU的运行压力)
原理:合成层
使用css3硬件加速,不会触发回流与重绘,常见不触发属性如下:
transform
opacity
filters
Will-change
但是动画的bgc还是会导致回流与重绘的

composite

参考网址:https://blog.youkuaiyun.com/qq_40028324/article/details/102580363
概念:
(1)层合成
每个dom树中的节点对应一个渲染对象(render object),处于一个z轴坐标空间的渲染对象形成一个渲染层(render layer),渲染层根据层叠顺序合成就是层合成的概念。用来正确显示透明元素和层叠元素,这也是从树结构到屏幕显示的原理,本质是树结构到层结构的转变
在这里插入图片描述
(2)满足形成层叠上下文条件的渲染对象,浏览器会自动为其创建新的渲染层
根节点:document
定位:positon(relative,fixed,absolute)
透明:opcity<1
溢出:不为visible
css:过滤属性filter、reflection 属性、mask 属性、 transform 属性且值不为 none、backface-visibility 属性为 hidden、mix-blend-mode 属性且值不为 normal
css column-count 、column-width 属性且值不为 auto
当前有对于 opacity、transform、fliter、backdrop-filter 应用动画

(3)满足某些特殊条件的渲染层,浏览器升级为合成层
3D transform:translate 3d translateZ等
element.animate或者css动画实现的opcity动画转换
position:fixed
video、canvas、iframe等元素
具有will-change属性(优先使用)
对 opacity、transform、fliter、backdropfilter 应用了 animation 或者 transition

(4)图形层(graphicsLayer)处理合成层生成位图,共享内存中的位图将作为纹理交给GPU,GPU将多个位图合成通过显卡显示到屏幕上

(5)隐式合成:由于特殊情况浏览器将渲染层提升合成层,例子如下
z-index:3元素添加transform:translateZ(0)属性后会提升为合成层,在z-index:5元素上面,此时浏览器会将z-index:5的元素默认提升为合成层,避免出现元素层叠错乱的问题
在这里插入图片描述在这里插入图片描述在这里插入图片描述
(6)层爆炸和层压缩
层爆炸:给最底层的元素添加css3加速属性提升为合成层,那么它上面的都会提升,导致层爆炸,占用大量的GPU和内存资源,损耗页面性能
解决方法:
a、层压缩:浏览器自动调节行为,将上方的所有渲染层推进图形曾进行渲染,使上方的元素在一个高于最底层的合成层中
b、用户行为:可以给最低层提升合成层的元素添加z-index属性,给个很高的值即可避免
(7)查看合成层:
chrome devTools:
a、more tools—》rendering—》layer borders,合成层会包裹黄kuang
b、more tools—>layer—>左侧合成层,右侧实例,还有形成的原因
(8)合成层优点
a、使用GPU处理,比CPU处理快
b、当需要重绘时,不会影响其他层
c、对于 transform 和 opacity 效果,不会触发回流和重绘
(9)优化建议
a、动画使用transform代替left top
原因:left,top使得动画与document在同一个合成层,导致大量的回流与重绘,但是使用transform实现会使节点单独处于一个合成层,运行在GPU上,减少CPU的损耗
b、提升动画效果(移动、渐变等)的元素为合成层,可以使用属性:will-change 设置为opacity、transform、top、left、bottom、right等
c、减少隐式合成:避免层爆炸,可以设置高的z-index
d、减少绘制区域:比如固定不变的导航栏
e、减小合成层的尺寸,最后使用transform:scale(10)放大

 .top {
    width: 10px;
    height: 10px;
    transform: scale(10);
  }

2、js引擎线程
作用:解析script标签里的js代码
注意:js引擎线程与GUI线程是互斥的,由于js可以操纵dom,如果两者同时进行,结果不可预期。所以遇到js文件,GUI线程挂起,等js线程空闲才继续,所以如果js运行过程,会导致卡顿
解决:
js的异步加载:
a、script标签一般放置在body标签底部
b、使用defer属性:<script defer src="script.js" /> defer属性使得script加载与html解析同时发生,等html解析完成后才开始解析js
c. async属性:async属性和defer属性类似,也是会开启一个线程去下载js文件,但和defer不同的时,它会在下载完成后立刻执行,而不是会等到DOM加载完成之后再执行,所以还是有可能会造成阻塞。

3、事件触发线程
事件绑定后,js引擎线程通知事件触发线程注意查看该事件,当调用的时候放入js引擎线程的队列中执行
4、定时器触发线程
定时器设置后交给定时器触发线程,当到达设定时间后交给js引擎线程的任务队列等待执行
5、异步http请求线程
发起ajax请求后js线程交给异步http请求线程,等返回结果后交给js引擎线程的任务队列等待处理

相应的面试题:

1、css3特性中的transform:translateZ(0)有什么作用
这个是涉及GUI渲染线程在绘制过程中的优化。绘制是将渲染树根据节点转换成屏幕的真实尺寸,这个是在多个渲染层上完成的,transform:translateZ(0)可以将渲染成提升为合成层,图形层将合成层按照不同的层级顺序合成位图交给GPU通过显卡展示在屏幕上,降低了CPU的损耗,提升了性能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值