渲染主循环(main loop)和requestAnimationFrame
requestAnimationFrame
- 使用
requestAnimationFrame
而非setTimeout/setInterval
绘制动画; -
requestAnimationFrame
:告诉浏览器JavaScript
想发起一个动画帧,然后在动画帧绘制之前,需要做一些动作,这样浏览器可以根据需要来优化自己的mainloop
机制和调用时间点,以达到较好地平衡效果;
var start = null;
var element = document.getElementById("example");
function step(timestamp) {
if (!start) start = timestamp;
var progress = timestamp - start;
element.style.left = Math.min(progress/10, 200) + "px";
if (progress < 2000) {
window.requestAnimationFrame(step);
}
}
window.requestAnimationFrame(step);
渲染mainloop
mainloop
过程
chromium
是多进程的结构,Browser
进程用户界面的mainloop
和Renderer
进程的主线程的mainloop
分别位于两个不同的进程,所以UI
和渲染可以互相不影响;但是
Renderer
进程的渲染工作和JavaScript
的执行工作都在其主线程中,由mainloop
来负责调度完成,存在竞争;过程:大的循环加上一个事件队列
* 当队列中有事件时,从队列中取出第一个事件,设置相应的状态信息,处理该事件及其对应的处理函数,直到该函数处理完后,才重新检查队列中是否有事件;
* 如果有,继续处理;如果没有,则继续等待;存在问题:
* 如果队列中事件多,很多事件可能来不及处理,造成比较大的延时,因而事件的平均等待时间会比较长;
* 如果事件的处理函数需要的时间很长,就会造成后面的事件一直在等待,同样会增加事件的平均等待时间;
WebKit
和Chromium
中的实现
-
setTimeout
和setInterval
的实现:
*WebKit
会为DOM
中的每个setTimeout
和setInterval
的调用创建一个DOMTimer
,而后该对象会由存储TLS(thread localstorage)
中的ThreadTimers
负责管理,其内部其实是一个最小堆,每次取timeout
最小时间,同时,相同的Timer
可以合并;
* 当Timer
超时后,Chromium
清除该Timer
对象,同时调用相应的回调函数,回调函数通常会更新页面的样式和布局, 这会触发relayout
,从而触发立即重新绘制一个新帧; -
setTimeout
和setInterval
从不考虑浏览器内部发生了其他什么事,它只要求浏览器在某个时间之后调用它的回调函数,无论浏览器很繁忙或者页面被隐藏; -
requestAnimationFrame
的实现原理就是其会申请绘制下一帧, 时间由浏览器决定,只需要浏览器在绘制下一帧前执行其设置的回调函数,完成JavaScript
对动 画所做的设置和逻辑即可;
*JavaScript
调用requestAnimationFrame
,相应的webkit
和chromium
会调度一个需要绘制下一证的事件,该事件会将requestAnimationFrame
的调用上下文和回调函数记录下来;
* 上面的请求会触发Chromium
更新页面内容的事件,该事件被mainloop
调度处理后,会检查是否需要调用动画的相关处理,如果有动画需要处理,就会依次调用那些回调函数,JavaScript
引擎会更新相应的CSS
属性或者DOM
树修改;
*Chromium
触发重新计算layout
,更新自己的Renderer
树,而后绘制完成一帧的渲染; - 为了实现更好的性能,
chromium
中对requestAnimationFrame
有三个设计原则:
* 当页面不可见时,其回调函数不会被调用,这可以减少CPU
和GPU
的使用率;
* 其最大调用频率不会超过60hz
,无论屏幕的刷新率是多少,;因而回调函数也不会每秒调用超过60次,这是因为60FPS
已经能够满足UI
流畅的要求了;
* 只有当页面真正开始渲染时,回调函数才会被调用;
设计机制带来的编程考虑
- 回调函数不能太大,不能占用太长时间,否则会影响页面的响应和绘制的频率;
-
requestAnimationFrame
不需要设置间隔时间,不同刷新率的间隔时间不一样,这完全由浏览器来控制,而不需要操心; - 回调函数无需合并,可以在任意位置设置回调函数,它们可以被浏览器集中处理, 而无需要一个统一的入口;
浏览器-04 WebKit 渲染2的更多相关文章
-
浏览器-03 WebKit 渲染1
WebKit是一个渲染引擎,而不是一个浏览器; DOM是对HTML或者XML等文档的一种结构化表示方法,通过这种方式,用户可以通过提供标准的接口来访问页面中的任何元素的相关属性,并可对DOM进行相应的 ...
-
WebKit 渲染过程
webkit笔记,主要来自 朱永盛 <WebKit技术内幕> 学习笔记,转载就注明原著,该书是国内仅有的Webkit内核的书籍,学习的好导师,推荐有兴趣的朋友可以购买 Webkit渲染过程 ...
-
浏览器的 16ms 渲染帧
标签 归档 关于arttle Land 浏览器的 16ms 渲染帧 DOM JavaScript 异步 性能 重绘 由于现在广泛使用的屏幕都有固定的刷新率(比如最新的一般在 60Hz), 在两次硬件刷 ...
-
浏览器的 16ms 渲染帧--摘抄
由于现在广泛使用的屏幕都有固定的刷新率(比如最新的一般在 60Hz), 在两次硬件刷新之间浏览器进行两次重绘是没有意义的只会消耗性能. 浏览器会利用这个间隔 16ms(1000ms/60)适当地对绘制 ...
-
聊聊浏览器(webkit)资源加载机制
一些准备 在开始这个话题之前,我们有必要简单回顾一下 浏览器(webkit)的网页渲染过程(如果想要详细了解这个过程,可以戳我几年前写的一篇文章.): 我们知道,浏览器在渲染过程中,如遇到节点需要依赖 ...
-
document.compatMode(判断当前浏览器采用的渲染方式)
转载自:http://www.cnblogs.com/fullhouse/archive/2012/01/17/2324706.html IE对盒模型的渲染在 Standards Mode和Quirk ...
-
浏览器内核-Webkit
关键字:浏览器内核,浏览器引擎,Browser,Webkit,Blink,Chromium. 本文简单介绍一下各种浏览器内核.着种介绍一下Webkit.顾名思义,浏览器内核就是浏览器的核心部分,也可以 ...
-
【repost】浏览器内核、渲染引擎、js引擎
[1]定义 浏览器内核分成两部分渲染引擎和js引擎,由于js引擎越来越独立,内核就倾向于只指渲染引擎 渲染引擎是一种对HTML文档进行解析并将其显示在页面上的工具[2]常见引擎 渲染引擎: firef ...
-
浏览器内核、渲染引擎、js引擎
[1]定义 浏览器内核分成两部分渲染引擎和js引擎,由于js引擎越来越独立,内核就倾向于只指渲染引擎 渲染引擎是一种对HTML文档进行解析并将其显示在页面上的工具 [2]常见引擎 渲染引擎: fire ...
随机推荐
-
VS使用技巧——统计代码行数
通常为了统计一个文件或者一整个解决管理方案中代码行量,可能会选择定位来获取行量,但是当文件尤其大时,传统方式就不行了,这里推荐使用正则表达式搜索统计,可以快速获取目标文档的总代码量. Tips: ct ...
-
兼容iOS 10:配置获取隐私数据权限声明
原文链接 iOS 10的一大变化是更强的隐私数据保护.在文档中是这么描述的: You must statically declare your app’s intended use of protec ...
-
PHP和Golang使用Thrift1和Thrift2访问Hbase0.96.2(ubuntu12.04)
目录: 一.Thrift1和Thrift2的简要介绍 1) 写在前面 2) Thrift1和Thrift2的区别 二.Thrift0.9.2的安装 1) 安装依赖插件 2) Thrift0.9.2的 ...
-
【jquery】 API讲解 内部培训资料
资料在百度云盘 一.jquery API讲解 1.jquery api如何使用 jquery api http://www.hemin.cn/jq/ 2.常用api讲解 选择器: 通过$()获取 ...
-
Use Node.js DDP Client on Arduino Yun to Access Meteor Server
Use Node.js DDP Client on Arduino Yun to Access Meteor Server 概述 在Arduino Yun上安装 Node.js, 并測试与 Meteo ...
-
Node.js之使用Buffer类处理二进制数据
Node.js之使用Buffer类处理二进制数据 Buffer类可以在处理TCP流或文件流时处理二进制数据,该类用来创建一个专门存放二进制数据的缓存区. 1. 创建Buffer对象 1.1 直接创建: ...
-
2 将mybatis配置到springmvc中
为了更方便的连接数据库,将mybatis配置到springMVC中 1). 首先是jar包 多了3个jar druid 这个是阿里的数据库连接包 mybatis和 mybatis- ...
-
Python简单试题
1,相乘次数 题目要求描述: 一个整数每一位上的数字相乘,判断是否为个位数,若是则程序结束 ,不是则继续相乘,要求返回相乘次数. 例:39 > 3*9=27 > 2*7=14 > 1 ...
-
xamarin.forms之实现ListView列表倒计时
做商城类APP时经常会遇到抢购倒计时的功能,之前做小区宝iOS的时候也有类似的功能,想着参考iOS做的思路,自定义一个Cell,在Cell中每秒刷新一下控件的文本值,但使用xamarin.forms实 ...
-
Groovy 类名称赋值为变量使用(newInstance &; new)
类创建实例一般方式 http://groovy-lang.org/objectorientation.html#_class class Person { String name Integer ag ...