浏览器渲染原理与弹幕
背景
随着弹幕数量越来越多,以及我们会不断的往视频上面添加越来越多的动画,如何让各种弹幕流畅的展示给我们的用户,成为了我们必须要考虑的问题。这要求我们需要了解浏览器底层的渲染原理,才能以最低的性能消耗来实现我们的各种弹幕效果,知道哪些性能消耗是我们前端可以避免的。
目标
通过此篇介绍,可以了解到:我们实现的动画,在浏览器上具体是怎么显示到屏幕上,以及可以通过减少哪些地方的消耗,来实现更加流畅的动画。
正文
(一)chrome多进程模型
1。1主要进程
各个进程具体负责的工作内容:
Browser负责浏览器的Chrome部分,包括导航栏,书签,前进和后退按钮。同时这个进程还会控制那些我们看不见的部分,包括网络请求的发送以及文件的读写Renderer默认每个Tab页面都会开启一个渲染进程,主要负责我们的html解析,js的执行Plugin主要是负责插件的运行,因为我们每个人都可以编写插件,chrome为了不使插件的崩溃影响到整个浏览器,它给每个插件都开启了一个独立的进程GPUChrome刚开始发布的时候是没有GPU进程的,而GPU的使用初衷是为了实现3DCSS的效果,只是随后网页、Chrome的UI界面都选择采用GPU来绘制,这使得GPU成为浏览器的普遍需求
除了上面列出来的进程,Chrome还有很多其他进程在工作,例如扩展进程(ExtensionProcess)和工具进程(utilityprocess)。
我们可以在浏览器右上角更多工具任务管理器,看到每个进程使用的cpu和内存情况:
1。2Chrome多进程架构的优劣
好处:
一:多进程可以使浏览器具有很好的容错性。
假如你有三个tab,你就会有三个独立的渲染进程。当其中一个tab的崩溃时,你可以随时关闭这个tab并且其他tab不受到影响。可是如果所有的tab都跑在同一个进程的话,它们就会有连带关系,一个挂全部挂。
二:可以提供安全性和沙盒性。
因为操作系统可以提供方法让你限制每个进程拥有的能力,所以浏览器可以让某些进程不具备某些特定的功能。例如,由于tab渲染进程可能会处理来自用户的随机输入,所以Chrome限制了它们对系统文件随机读写的能力。
劣处:
由于每个进程都有各自独立的内存空间,会占用大量内存。
改进:
一:为了节省内存,Chrome会限制被启动的进程数目,当进程数达到一定的界限后,Chrome会将访问同一个网站的tab都放在一个进程里面跑。
二:当Chrome在一些性能比较好的硬件中运行时,浏览器进程相关的服务会被放入不同的进程运行以提高系统的稳定性。相反如果硬件性能不好,这些服务就会被放在同一个进程里面执行来减少内存的占用。
(二)从输入URL到显示页面发生了什么?
2。1浏览器进程里执行了哪些任务
第一步:处理输入
浏览器的UI线程会进行一系列的解析来判定:输入的字符串是搜索的关键词还是一个url地址。
如果不是url地址,会调用浏览器的默认搜索引擎,执行搜索操作。
第二步:开始导航
如果是url地址:UI线程会叫网络线程初始化一个网络请求来获取站点的内容,也就是dns寻址、tcp三次握手、arp寻址等类似操作。
这时候tab上会展示一个资源正在加载中的loading图标。
ui线程也会通知浏览器进程去开启一个渲染进程,为渲染页面做准备。
第三步:读取响应
在获取到响应之后:如果网络线程收到服务器的301重定向,它就会告知UI线程进行重定向,然后它会再次发起一个新的网络请求。
如果是数据内容,它会先检测响应数据的具体媒体类型。
响应主体的媒体类型一般可以通过HTTP头部的ContentType来确定,不过ContentType有时候会缺失或者是错误的,这种情况下浏览器就要进行MIME类型嗅探来确定响应类型了。
如果拿到的响应数据是一个压缩文件,响应数据就会交给下载管理器来进行下载操作。
第四步:寻找一个渲染进程
如果响应的主体是一个HTML文件,网络线程会对内容做一些必要的安全检测,并寻找一个渲染进程。
第五步:提交导航
数据和渲染进程都已经准备好了,浏览器进程会通过IPC告诉渲染进程去提交本次导航。
除此之外浏览器进程还会将刚刚接收到的响应数据流传递给对应的渲染进程让它继续接收到来的HTML数据。
一旦浏览器进程收到渲染线程的回复说导航已经被提交了,导航这个过程就结束了,文档的加载阶段会正式开始。
到了这个时候,导航栏会被更新,也会生成当前tab的会话历史。
第六步:渲染进程继续接收数据并解析
当导航提交完成后,渲染进程会继续接收html数据,并解析、加载页面相关的资源,一旦所有资源都onload之后,渲染进程会通知浏览器进程,所有资源已经加载完成,这时候,UI线程就会停止导航栏上的loading图标。
(三)渲染进程与gpu进程执行的任务
3。1渲染进程作用
渲染进程的主要任务是将HTML,CSS,以及JS转变为我们可以进行交互的网页内容。
渲染进程里面的主要线程:
一个主线程负责html、css解析以及js的执行一个合成线程负责分割,生成帧数据,接收用户事件一个光栅线程池将分割的图块转换为位图几个工作线程例如webworker和serviceworker线程
3。2主线程任务
渲染进程在接收到html数据后,首先会在主线程执行:转换成字符流,经过词法分析,生成token序列(这时候,浏览器会做一个优化,会把识别出来的资源地址,提前交给网络线程去加载数据),然后是语法分析,解析html,生成DOM树,解析css生成css规则树。
3。2。1生成DOM树之后,会逐次生成的4种树结构,首先是结合DOM树和css规则树生成的布局树
主线程会遍历DOM树,结合css规则树,确定每个DOM节点的计算样式。
然后还会再遍历一次DOM树,根据DOM节点的计算样式计算出一个布局树。布局树上每个节点会有它在页面上的x,y坐标以及盒子大小的具体信息。布局树长得和先前构建的DOM树差不多,不同的是这颗树只有那些可见节点的信息。
举个例子,如果一个节点被设置为了display:none,这个节点就不会出现在布局树上面但是visibility:hidden的节点会出现在布局树上面。同样的,如果有一个伪元素节点是显示状态,它也会出现在布局上,但不会出现在DOM树上。
3。2。2绘画阶段,由布局树生成绘画树
主线程会遍历之前得到的布局树来生成一系列的绘画记录。绘画记录是对绘画过程的注释,例如首先画背景,然后是文本,类似我们用canvas绘画图形的时候,从一个点画到另一个点的操作记录。
如图,我们可以看到,布局树生成绘画树会少一些节点:
这里,我们先看一个现象:
如图所示,a节点和b节点在文档结构上是并列的关系,然后我们通过负margin来把a,b节点设置为重叠,然后会出现这种情况:b的背景会盖到a的背景上,但是却没有覆盖到a的文字上,这是由于a和b不满足下面列的几点要求,没有形成自己的绘画层,他们公用一个绘画层,而绘画记录生成的顺序是先画背景再画文字,所以就会出现这种情况。
要想拥有独立的绘画层,需要满足以下条件:
1。页面的根对象
2。具有显式CSS位置属性(相对、绝对或转换)
3。是透明的
4。有CSS过滤器
5。具有三维(WebGL)上下文或加速二维上下文的canvas元素
6。video元素
3。2。3合成阶段,由绘画树生成图形树,每个图形层也就是我们平时所说的合成层
它和上面介绍的布局树到绘画树的过程类似,只有满足特殊条件的绘画层,才能形成自己的图形层,否则,会使用它第一个祖先元素的图形层。
要想拥有独立的合成层,需要满足以下条件:
1。层具有三维或透视变换CSS属性
2。层由使用加速视频解码的video元素使用
3。层由具有3D上下文或加速2D上下文的canvas元素使用
4。层用于合成插件
5。层使用CSS动画作为其不透明度,或使用动画webkit变换
6。层使用加速CSS过滤器
7。层的子体是合成层
8。层有一个具有较低z索引的同级,该同级有一个合成层(换句话说,该层与合成层重叠,应在其上渲染)
像我们平时使用的:
我们可以在chrome的控制台查看当前页面的所有图形层。
css3动画在执行的时候,浏览器其实只是移动对应的图形层。
3。3合成线程任务
分割将图层分割为256x256或者512x512的图块栅格化是指将图块上的绘画记录转换为位图,位图存在gpu的内存里绘画四边形包含图块在内存的位置以及图层合成后图块在页面的位置之类的信息合成帧代表页面一个帧内容的绘画四边形集合
合成线程会将每个图层分别分割为图块,然后把图块数据发送给一系列光栅线程,合成线程也会给不同的光栅线程赋予不同的优先级,进而使那些在视窗中的或附近的图块可以先被栅格化。光栅线程会栅格化每个图块并且把它们存储在GPU的内存中。当我们使用css3动画,并提升合成层之后,每个合成层在做动画的时候,直接操作的是栅格化后的图层,而不需要每次都栅格化。
顺便说一下:栅格化分为软件栅格化,和硬件栅格化,现在的新版浏览器基本上都是采用GPU硬件栅格化,又称为快速栅格化。当图层上面的图块都被栅格化后,合成线程会收集图块上面叫做绘画四边形的信息来构建一个合成帧,然后合成线程会生成一系列的指令调用。由于沙盒的限制,渲染器进程不能直接调用操作系统提供的3Dapi。因此,需要一个单独的进程来访问,这就是前面所说的GPU进程。
3。4gpu进程
合成线程生成一系列的指令调用都会被序列化并存入一个共享内存中,然后gpu进程从共享内存中提取序列化命令,解析它们并执行适当的图形调用。
GPU渲染完成后会将渲染结果存入帧缓冲区,视频控制器会按照VSync信号逐帧读取帧缓冲区的数据,经过数据转换后最终由显示器进行显示。
(四)弹幕实现原理
首先,我们会有一个弹幕列表,用来维护当前视频的所有弹幕,然后我们会逐帧去获取下一帧将要展示的弹幕,这边有个判断,是否有缓存的dom节点,如果没有,我们会创建一个dom节点,并把弹幕填充进去。然后,获取该条弹幕的宽高,来和已经出现在屏幕上的弹幕做碰撞检测,确定该条弹幕应该展示在哪一条轨道上,之后开始做位移动画。当弹幕已经完全运动出显示区域,我们会把这条弹幕的dom节点缓存起来,然后给后面的弹幕复用(因为创建dom节点也是一个很消耗性能的操作)。
本期作者
雪人
哔哩哔哩资深开发工程师
来源:微信公众号:哔哩哔哩技术
出处:https:mp。weixin。qq。comsQLeqqSmLgZxy82m9fC7Cig
冬季知性优雅风才是真高级!会穿毛衣才是关键,简约却显气质相信很多人都比较喜欢优雅风的搭配,和性感风以及可爱风相比,优雅风的造型更能够体现时髦感,而且更加耐看一些,如果你想要成为气质女神,在今年冬季可以给自己选择毛衣,会穿毛衣的女人的……
自然之宝是什么牌子哪国的?以前总是了解什么零食最好吃,什么地方最好玩,而今考虑得最多的是什么保健品可以养生,什么保健品可以美容,真的是岁月不饶人,下面给大家介绍的就是一个保健品品牌自然之宝自然之宝是什么……
如何在家中进行刮痧按摩,让面部轮廓恢复活力水粉面部按摩是面部皮肤年轻化的有效方法。推荐给所有想要拥有光滑、有光泽的面部和肩部皮肤的人。众所周知,皮肤状况会随着年龄的增长而恶化。与年龄有关的变化是由许多因素造成的。在面部……
摩罗丹是保健品还是药?属于处方药保健品和药品的区别还是蛮大的,很多人分不清摩罗丹是保健品还是药,下面5号网的小编为你们介绍摩罗丹是保健品还是药?属于处方药。摩罗丹是保健品还是药摩罗丹是蜚声中外的胃病良药……
女排联赛4强排位确定,半决赛对阵出炉!14队积分排行榜更新2021至2022赛季中国女排超级联赛开始第二阶段最后一轮比赛争夺,在引人注目的津沪大战中,全主力阵容出战的天津女排直落三局以3:0横扫实力有所保留的上海女排,以全胜战绩结束了……
虾青素怎么吃?不建议过量食用虾青素是一种非常养生的保健品,吃了它不仅可以美容养颜,还可以防治糖尿病,高血压等等身体问题,也可以抵御身体的老化,那么虾青素应该怎么吃呢?虾青素怎么吃虾青素的胶囊,一次吃……
前列腺炎可以吃伟哥吗?前列腺炎可以吃肾宝片吗?由于现在很多男性的生活习惯都特别差,所以患上前列腺炎的人越来越多,对生活的影响很大。下面5号网小编给大家讲讲前列腺炎可以吃伟哥吗?前列腺炎可以吃肾宝片吗?前列腺炎可以吃伟哥吗……
海藻钙好还是碳酸钙好?效果不同海藻钙和碳酸钙都是钙,很多人拿来比较,究竟哪种更胜一筹呢,下面5号网的小编为你们介绍海藻钙好还是碳酸钙好?效果不同。海藻钙好还是碳酸钙好海藻钙好还是碳酸钙好呢?关于这个问……
异彩纷呈三场跨年晚会今晚播出《长津湖之水门桥》主创团队今年各地方卫视的跨年晚会可谓异彩纷呈!江苏卫视2022跨年演唱会第五次在澳门金光综艺馆全球直播,主题为用奋斗点亮幸福;浙江卫视跨年晚会想把我唱给……
粉刺会自己消失吗?粉刺会痒吗?粉刺是比较令人头疼的皮肤问题,很多人不清楚粉刺不管他会不会消失,下面5号网的小编为你们介绍粉刺会自己消失吗?粉刺会痒吗?粉刺会自己消失吗放任不管当然有两种情况啦,一种就是……
傲世龙城玉魂怎样激活屠龙传说傲世龙城玉魂介绍嗨,各位玩家们大家好啊,欢迎来到【新会展生活圈】,宝鼎传奇手游傲世龙城玉魂是怎样激活的呢,傲世龙城玉魂介绍跟随小编一起来看看吧,希望能够给大家带来帮助哦!龙城岁月,千人攻……
秋天可以钓龙虾吗?几月份可以钓龙虾?夏秋两季是吃龙虾的旺季,吃虾的人多,钓虾的人自然也会比较多。因此,毫无疑问秋季是可以钓龙虾的。那么,秋季钓龙虾怎么钓呢?有什么技巧呢?秋天可以钓龙虾吗秋天可以钓龙虾……