渲染主循环(main loop)和requestAnimationFrame

requestAnimationFrame

  • 使用requestAnimationFrame而非setTimeout/setInterval绘制动画;
  • requestAnimationFrame:告诉浏览器JavaScript想发起一个动画帧,然后在动画帧绘制之前,需要做一些动作,这样浏览器可以根据需要来优化自己的 mainloop机制和调用时间点,以达到较好地平衡效果;
  1. var start = null;
  2. var element = document.getElementById("example");
  3. function step(timestamp) {
  4. if (!start) start = timestamp;
  5. var progress = timestamp - start;
  6. element.style.left = Math.min(progress/10, 200) + "px";
  7. if (progress < 2000) {
  8. window.requestAnimationFrame(step);
  9. }
  10. }
  11. window.requestAnimationFrame(step);

渲染mainloop

mainloop过程

  • chromium是多进程的结构,Browser进程用户界面的mainloopRenderer进程的主线程的mainloop分别位于两个不同的进程,所以UI和渲染可以互相不影响;

  • 但是Renderer进程的渲染工作和JavaScript的执行工作都在其主线程中,由mainloop来负责调度完成,存在竞争;

  • 过程:大的循环加上一个事件队列

    * 当队列中有事件时,从队列中取出第一个事件,设置相应的状态信息,处理该事件及其对应的处理函数,直到该函数处理完后,才重新检查队列中是否有事件;

    * 如果有,继续处理;如果没有,则继续等待;

  • 存在问题:

    * 如果队列中事件多,很多事件可能来不及处理,造成比较大的延时,因而事件的平均等待时间会比较长;

    * 如果事件的处理函数需要的时间很长,就会造成后面的事件一直在等待,同样会增加事件的平均等待时间;

WebKitChromium中的实现

  • setTimeoutsetInterval的实现:

    * WebKit会为DOM中的每个setTimeoutsetInterval的调用创建一个DOMTimer,而后该对象会由存储TLS(thread localstorage)中的 ThreadTimers负责管理,其内部其实是一个最小堆,每次取timeout最小时间,同时,相同的Timer可以合并;

    * 当Timer超时后,Chromium清除该Timer对象,同时调用相应的回调函数,回调函数通常会更新页面的样式和布局, 这会触发relayout,从而触发立即重新绘制一个新帧;
  • setTimeoutsetInterval从不考虑浏览器内部发生了其他什么事,它只要求浏览器在某个时间之后调用它的回调函数,无论浏览器很繁忙或者页面被隐藏;
  • requestAnimationFrame的实现原理就是其会申请绘制下一帧, 时间由浏览器决定,只需要浏览器在绘制下一帧前执行其设置的回调函数,完成JavaScript对动 画所做的设置和逻辑即可;

    * JavaScript调用requestAnimationFrame,相应的webkitchromium会调度一个需要绘制下一证的事件,该事件会将requestAnimationFrame的调用上下文和回调函数记录下来;

    * 上面的请求会触发Chromium更新页面内容的事件,该事件被mainloop调度处理后,会检查是否需要调用动画的相关处理,如果有动画需要处理,就会依次调用那些回调函数,JavaScript引擎会更新相应的CSS属性或者DOM树修改;

    * Chromium触发重新计算layout,更新自己的Renderer树,而后绘制完成一帧的渲染;
  • 为了实现更好的性能,chromium中对requestAnimationFrame有三个设计原则:

    * 当页面不可见时,其回调函数不会被调用,这可以减少CPUGPU的使用率;

    * 其最大调用频率不会超过60hz,无论屏幕的刷新率是多少,;因而回调函数也不会每秒调用超过60次,这是因为60FPS已经能够满足UI流畅的要求了;

    * 只有当页面真正开始渲染时,回调函数才会被调用;

设计机制带来的编程考虑

  • 回调函数不能太大,不能占用太长时间,否则会影响页面的响应和绘制的频率;
  • requestAnimationFrame不需要设置间隔时间,不同刷新率的间隔时间不一样,这完全由浏览器来控制,而不需要操心;
  • 回调函数无需合并,可以在任意位置设置回调函数,它们可以被浏览器集中处理, 而无需要一个统一的入口;

浏览器-04 WebKit 渲染2的更多相关文章

  1. 浏览器-03 WebKit 渲染1

    WebKit是一个渲染引擎,而不是一个浏览器; DOM是对HTML或者XML等文档的一种结构化表示方法,通过这种方式,用户可以通过提供标准的接口来访问页面中的任何元素的相关属性,并可对DOM进行相应的 ...

  2. WebKit 渲染过程

    webkit笔记,主要来自 朱永盛 <WebKit技术内幕> 学习笔记,转载就注明原著,该书是国内仅有的Webkit内核的书籍,学习的好导师,推荐有兴趣的朋友可以购买 Webkit渲染过程 ...

  3. 浏览器的 16ms 渲染帧

    标签 归档 关于arttle Land 浏览器的 16ms 渲染帧 DOM JavaScript 异步 性能 重绘 由于现在广泛使用的屏幕都有固定的刷新率(比如最新的一般在 60Hz), 在两次硬件刷 ...

  4. 浏览器的 16ms 渲染帧--摘抄

    由于现在广泛使用的屏幕都有固定的刷新率(比如最新的一般在 60Hz), 在两次硬件刷新之间浏览器进行两次重绘是没有意义的只会消耗性能. 浏览器会利用这个间隔 16ms(1000ms/60)适当地对绘制 ...

  5. 聊聊浏览器(webkit)资源加载机制

    一些准备 在开始这个话题之前,我们有必要简单回顾一下 浏览器(webkit)的网页渲染过程(如果想要详细了解这个过程,可以戳我几年前写的一篇文章.): 我们知道,浏览器在渲染过程中,如遇到节点需要依赖 ...

  6. document.compatMode(判断当前浏览器采用的渲染方式)

    转载自:http://www.cnblogs.com/fullhouse/archive/2012/01/17/2324706.html IE对盒模型的渲染在 Standards Mode和Quirk ...

  7. 浏览器内核-Webkit

    关键字:浏览器内核,浏览器引擎,Browser,Webkit,Blink,Chromium. 本文简单介绍一下各种浏览器内核.着种介绍一下Webkit.顾名思义,浏览器内核就是浏览器的核心部分,也可以 ...

  8. 【repost】浏览器内核、渲染引擎、js引擎

    [1]定义 浏览器内核分成两部分渲染引擎和js引擎,由于js引擎越来越独立,内核就倾向于只指渲染引擎 渲染引擎是一种对HTML文档进行解析并将其显示在页面上的工具[2]常见引擎 渲染引擎: firef ...

  9. 浏览器内核、渲染引擎、js引擎

    [1]定义 浏览器内核分成两部分渲染引擎和js引擎,由于js引擎越来越独立,内核就倾向于只指渲染引擎 渲染引擎是一种对HTML文档进行解析并将其显示在页面上的工具 [2]常见引擎 渲染引擎: fire ...

随机推荐

  1. primefaces 查询 点击按钮 加载 动画 ajax loader

    只要在/WEB-INF/template.xhtml中body 里面加入: <ui:insert name="status"> <p:ajaxStatus sty ...

  2. BootStrap的一个标准框架的内容解释——来源于bootstrap官网

    <!DOCTYPE html><!--HTML5的定义--><html lang="zh-cn"> <head> <meta ...

  3. 挣值管理(PV、EV、AC、SV、CV、SPI、CPI) 记忆

    挣值管理法中的PV.EV.AC.SV.CV.SPI.CPI这些英文简写相信把大家都搞得晕头转向的.在挣值管理法中,需要记忆理解的有三个参数:PV.AC.EV.     PV:计划值,在即定时间点前计划 ...

  4. Extjs 学习总结-Ext.define自定义类

    本教程整理了extjs的一些基本概念及其使用,包括自定义类(Ext.define).数据模型.代理等.本节介绍使用Ext.define自定义类 使用Ext.define自定义类 1. 首先看看js中自 ...

  5. 学习MySQL之单表操作(二)

    ##单表操作 ##创建表 CREATE TABLE t_employee( empno ), ename ), job ), MGR ), Hiredate DATE DEFAULT '0000-00 ...

  6. Node.js Stream - 实战篇

    邹斌 ·2016-07-22 11:04 背景 前面两篇(基础篇和进阶篇)主要介绍流的基本用法和原理,本篇从应用的角度,介绍如何使用管道进行程序设计,主要内容包括: 管道的概念 Browserify的 ...

  7. PHP Strom 配置less 并设置编译后在远程开发模式下自动上传css文件

    ctrl+alt+s ->File Watchers->add-> 其中Argument中的-x代表最后编译过后的css文件为压缩过的 此时就可以用了,但是编译过后less可以自动上 ...

  8. 非常简单的升级phpnow自带的php版本到5.3的方法

    下载PHP5.3 下载地址百度一下“PHP5.3下载”就有很多网站提供下载的,也可以去官网下载最新的,记得下载ZIP压缩的噢 2 解压与命名 将下载的PHP5.3压缩包解压至phpnow的安装目录,命 ...

  9. python多线程学习记录

    1.多线程的创建 import threading t = t.theading.Thread(target, args--) t.SetDeamon(True)//设置为守护进程 t.start() ...

  10. 配置nginx+php

    一般这样配置 此时很多教程会教大家这样配置Nginx+PHP: server { listen 80; server_name foo.com; root /path; location / { in ...