Top Banner
Timers in Browser Etai
39

Timers in Browser

Jan 20, 2015

Download

Technology

j5726

几个月前做的分享,关于浏览器计时器原理
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Timers in Browser

Timers in BrowserEtai

Page 2: Timers in Browser

Content

• 定时器 / 误差

• 优化

• 几个 Bug

Page 3: Timers in Browser

Content

• 定时器 / 误差• JS 运行机制

• 时钟精度

• 优化

• 几个 Bug

Page 4: Timers in Browser

定时器

setTimeout

返回值 : (number) ID

clearTimeout(ID)

setInterval

返回值 : (number) ID

clearInterval(ID)

Page 5: Timers in Browser

浏览器“线程”

浏览器工作进程: 界面渲染

JS 脚本执行

HTTP 连接

JS 引擎:单线程执行

Page 6: Timers in Browser

异步事件

鼠标、键盘等事件响应

Ajax 回调

延时 / 定时 (setTimeout/setInterval)

Page 8: Timers in Browser

setTimeout vs setInterval

异步回调函数被加入队列等待执行

若回调不能立即执行,将被推迟到下次机会

如果执行延迟过长, setInterval 回调会堆积从而无间隔执行

Page 9: Timers in Browser

时钟

硬件时钟: CPU 运行频率

系统时钟: OS 为软件运行提供的时钟 API

Page 10: Timers in Browser

时钟精度

系统时钟的最小时间间隔

Windows

默认时钟精度: 15.6ms

multimedia API : 1ms

Mac

默认系统时钟:动态,最小约 4ms

利用 gettimeofday : 1ms

Page 11: Timers in Browser

浏览器处理

旧版本:依赖系统时钟

HTML5: 4ms

IE9/Chrome/FF5/safari5.1/Opera11 已实现

电池供电时, Chrome/IE9+ 切换到系统时钟

FF5+/Chrome 11+/IE10+ 空闲标签变为 1000ms

Safari on iOS 5 / Silk on Kindle Fire: 切出应用时冻结

Timer resolution in browsers

Page 12: Timers in Browser

影响

setTimeout(fn, 0);

setInterval(fn, 0);

Page 13: Timers in Browser

Content

• 误差从哪里来

• 优化• 实现方式优化

• 误差校正

• 几个 Bug

Page 14: Timers in Browser

setTimeout or setInterval ?

容易引起堆积的,用 setTimeout 模拟 密集操作 ( 动画等 )

高能耗运算

交互复杂的页面 ( 外部影响 )

BOM 操作

Page 15: Timers in Browser

setTimeout(function(){

/* do sth.. */

setTimeout(arguments.callee, 10);

}, 10);

Page 16: Timers in Browser

requestAnimationFrame

Mozilla 、 Google 发起

专为网页动画设置

实现有差异,未标准化

Page 17: Timers in Browser

时间校正

客户端时间

服务端时间

Page 18: Timers in Browser

取客户端时间校正

var timeLeft = 123456ms,

timeStart = new Date().getTime();

// after some time …

var timeNow = new Date().getTime();

timeLeft = timeLeft – (timeNow – timeStart) ;

Page 19: Timers in Browser

取客户端时间校正

优点: 简单、高效

缺点: 用户可以修改本地时间造成干扰

Page 20: Timers in Browser

取服务器时间校正

发送 Ajax 空响应轮询,取得响应头时间

或搭车其他 Ajax 轮询

Page 21: Timers in Browser

空响应 / 取响应头

xhr.onreadystatechange = function(){

if (xhr.readyState == 4) {

serverDate = new

Date(xhr.getResponseHeader(‘date’));

//校正}

};

xhr.open('HEAD', '/?'+Math.random());

xhr.send(null);

Page 22: Timers in Browser

服务端校准

优点: 准确

缺点 资源消耗

需要考虑网络延迟

Page 23: Timers in Browser

Content

• 误差从哪里来

• 优化

• 几个 Bug

Page 24: Timers in Browser

当 setInterval 遇到 页面跳转

Page 25: Timers in Browser

故障后果

每到 10:00 ,服务器就开始宕机

影响淘江湖几十台服务器

5 天后才找到原因

P1

Page 26: Timers in Browser

代码

setInterval(function(){

//…

if(condition){

location.href = ‘xxx’;

}

}, 100)

Page 27: Timers in Browser

成因

IE: 页面 unload 之前, interval 持续运行

location.href 本页跳转,接收到新页面内容后,旧页面才 unload

大量用户的页面加载时间大于 100ms

持续发起新的页面跳转,服务器请求拥塞

Page 28: Timers in Browser

优化方案

严谨的条件判断

使用 setTimeout 替代

Page 29: Timers in Browser

变量覆盖

Page 30: Timers in Browser

代码

var a = setTimeout(fn0, 1000);

//…

a = setTimeout(fn1, 3000);

Page 31: Timers in Browser

代码

var a = setTimeout(fn0, 1000);

//…

a = setTimeout(fn1, 3000);

//

clearTimeout(a);

Page 32: Timers in Browser

成因

setTimeout/setInterval 返回值: (number) ID

覆盖的是 ID ,不是计时器

clearTimeout/clearInterval 参数: (number)

ID

只能清除最后设置的 ID

Page 33: Timers in Browser

setTimeout(fn, 0)

Page 34: Timers in Browser

作用

将操作脱离队列

等待 (文档内容 )稳定后执行

alert(1);

setTimeout("alert(2)", 0);

alert(3);

Page 35: Timers in Browser

场景

操作 DOM ,等待 UI稳定后继续操作 解决 IE6 DOM更新常不同步问题

低优先级操作

Page 36: Timers in Browser

替代方案

setImmediate

作用:线程空闲时执行操作

微软提出,尚未纳入标准

var id = setImmediate(function(){

//do sth

});

Page 37: Timers in Browser

替代方案

web workers : HTML5 多线程方案

主线程 :

var worker = new Worker( url )

worker.postMessage( data )

worker.onmessage

worker.terminate()

新线程 postMessage( data )

onmessage

Page 38: Timers in Browser

web workers 的局限

不能跨域加载 JS文件

worker 代码不能直接访问 DOM

浏览器实现不一致

Page 39: Timers in Browser

Thanks~

将图片拖动到占位符,或单击添加图标