39
Timers in Browser Etai

Timers in Browser

  • Upload
    j5726

  • View
    681

  • Download
    7

Embed Size (px)

DESCRIPTION

几个月前做的分享,关于浏览器计时器原理

Citation preview

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~

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