WebKit的一些笔记3(基础篇)
来源:互联网 发布:师洋淘宝店骂人 编辑:程序博客网 时间:2024/06/05 10:52
Webkit渲染基础
概述
Webkit是一个渲染引擎,而不是浏览器,它专注于网页内容的展示,其中渲染是其中的核心功能之一。
DOM称作文本对象模型,简单来说,是对HTML或者XML等文档的结构化表示方法,通过这种方式,用户可以通过接口访问HTML页面任何元素的相关属性,并可以对DOM进行相应的操作。
对于DOM树的可视节点,WebKit需要创建相应的RenderObject节点,这些节点构成了一颗Render树。基于Render树,WebKit根据某种规则会创建RenderLayer节点,构成一颗RenderLayer树。WebKit的布局计算,浏览器的渲染,GPU的硬件加速都依赖于Render树和RenderLayer树
DOM、Render树和RenderLayer树如下图所示:
Render树
Render树的建立
Render树节点和DOM树节点并不是一一对应的关系,如下情况需要建立Render节点:
- DOM树的document节点;
- DOM树中的可视化节点,例如HTML、BODY、DIV等;
- 某些情况下需要建立匿名的Render节点,该节点不对应DOM树上的任何节点
RenderObject类及其子类
RenderObject是Render树的节点基础类,提供了一组公共的接口。
RenderObject有很多子类,子类可能是DOM树中的节点,也可能是容器类,如RenderBlock,它是一个非常重要的类。
附上一张继承图:
匿名的RenderBlock对象
(这块不是很懂,先不写了)
RenderLayer树
RenderLayer树是基于Render树重新建立起来的一颗新的树。RenderLayer节点和Render节点是一对多的关系。
下面情况下,需要建立新的RenderLayer节点:
(这块也不是很了解,也先不写了)
渲染主循环(main loop)和requestAnimationFrame
背景
在JavaScript中有如下两个函数:
- setTimeout:在指定毫秒数之后调用函数或者表达式,只调用一次,如果需要多次调用,则调用setInterval(),或者让代码本身调用setTimeout();
- setInterval:按照指定的毫秒周期来调用某段代码。
我们可以通过以上两个函数让浏览器周期性的做一些事情,比如更新动画,但是会存在以下几个问题:
- 时间间隔不好控制,动画可能不平滑;
- 可能会受浏览器和平台不同等因素的影响;
- 回调函数的复杂性。
于是我们引入requestAnimationFrame方法,该方法告诉浏览器JavaScript想发起一个动画帧,然后在动画帧绘制前,需要做一些动作,这样浏览器可以根据需要来优化自己的mainloop机制和调用的时间点,已达到平衡的效果。
渲染mainloop
Browser进程UI的mainloop和Render进程的mainloop是两个进程,互不影响,但是问题依然存在。Render进程的渲染和JavaScript的执行都在其主线程中,由mainloop来调度。主线程采用一个大循环加上一个事件队列来处理这个竞争关系。
从上面可以看出:
- 如果队列中的事件过多,很多事件的来不及处理,会造成事件的平均等待时间会比较长;
- 如果事件的处理函数需要的时间很长,会造成后面的事件一直等待,也会造成延迟。
WebKit和Chromium中的实现
下面来看看setTimeout和setInterval的实现。
WebKit会为DOM中的每个setTimeout和setInterval的调用创建一个DOMTimer,而后对象会由ThreadTimers负责管理,内部实际上是一个最小堆,每次取timeout时间最小的,同时相同的Timer可以合并。
当Timer超时后,Chromium清除该Timer对象,同时调用它的回调函数,回调函数通常会更新页面的样式和布局,这会触发relayout,从而触发立即重新绘制一个新帧。
如上所述,这两个函数有如下不足:不考虑浏览器繁忙或者被隐藏,它们只要要求浏览器去做,造成了资源极大的浪费,而且浏览器帧间隔有可能比它们设置的间隔大,强制绘制的话,用户也是看不到的。
再来看看requestAnimationFrame的实现,其原理就是:申请绘制下一帧,至于什么时候绘制由浏览器来决定,浏览器会在绘制前调用回调函数。
基本过程(略)。
Chromium对requestAnimation有三大设计原则:
- 当页面不可见时,其回调函数不会被调用,减少CPU和GPU的消耗;
- 其调用频率不会超过60hz(显示器的刷新频率);
- 只有当页面真正开始渲染的时候,回调函数才会被调用。
编程时候的注意事项:
- 回调函数不能太大,不能太占用时间;
- requestAnimationFrame不需要设置时间间隔,由浏览器控制,不需要程序员担心;
- 回调函数无需合并。
0 0
- WebKit的一些笔记3(基础篇)
- WebKit的一些笔记1(基础篇)
- WebKit的一些笔记2(基础篇)
- webkit(qt)的一些问题
- 学习Webkit的一些博客
- 关于-webkit-的一些用法
- 《Mesos in Action》一些零碎的笔记(Mesos之于Kubernetes,犹如WebKit之于Chromium)
- 一些基础函数的笔记
- 最近的一些基础笔记
- [WebKit] JavaScriptCore解析--基础篇
- JNI 笔记 (总结一些基础的,常用的)
- Linux学习笔记(一)一些基础实用的东西
- webkit基础
- 有关webkit编译遇到的一些错误
- webkit手机浏览器的一些bug汇总
- 一些特殊的Webkit Idl属性
- 基础笔记:图的一些概念
- java基础学习的一些笔记
- C++ 模版类的单向链式线性表
- spring四种依赖注入方式
- Volley全解析
- android 实现代码混淆
- 深入理解HTTP Session
- WebKit的一些笔记3(基础篇)
- tabbarcontroller切换
- Listview 去除顶部阴影
- MathType在word中的使用方法
- Maven实战(八)---模块划分
- 使用JMF在java上使用媒体资源(播放音频等)
- Stm32f10x 新建工程详解
- poj 3258 River Hopscotch 二分搜索
- iGrimace IG 3.0 VX v3 iOS神器 新机 抹机 优步Uber 陌陌 微信 携程 同城旅游 美团 大众 一号专车