{"action":"opened","issue":{"url":"https://api.github.com/repos/banshenghuiyi0623/blog/issues/4","repository_url":"https://api.github.com/repos/banshenghuiyi0623/blog","labels_url":"https://api.github.com/repos/banshenghuiyi0623/blog/issues/4/labels{/name}","comments_url":"https://api.github.com/repos/banshenghuiyi0623/blog/issues/4/comments","events_url":"https://api.github.com/repos/banshenghuiyi0623/blog/issues/4/events","html_url":"https://github.com/banshenghuiyi0623/blog/issues/4","id":395448252,"node_id":"MDU6SXNzdWUzOTU0NDgyNTI=","number":4,"title":"requestAnimationFrame","user":{"login":"banshenghuiyi0623","id":19149786,"node_id":"MDQ6VXNlcjE5MTQ5Nzg2","avatar_url":"https://avatars0.githubusercontent.com/u/19149786?v=4","gravatar_id":"","url":"https://api.github.com/users/banshenghuiyi0623","html_url":"https://github.com/banshenghuiyi0623","followers_url":"https://api.github.com/users/banshenghuiyi0623/followers","following_url":"https://api.github.com/users/banshenghuiyi0623/following{/other_user}","gists_url":"https://api.github.com/users/banshenghuiyi0623/gists{/gist_id}","starred_url":"https://api.github.com/users/banshenghuiyi0623/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/banshenghuiyi0623/subscriptions","organizations_url":"https://api.github.com/users/banshenghuiyi0623/orgs","repos_url":"https://api.github.com/users/banshenghuiyi0623/repos","events_url":"https://api.github.com/users/banshenghuiyi0623/events{/privacy}","received_events_url":"https://api.github.com/users/banshenghuiyi0623/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2019-01-03T03:35:39Z","updated_at":"2019-01-03T03:35:39Z","closed_at":null,"author_association":"OWNER","body":"## requestAnimationFrame\r\n当你调用requestAnimationFrame()函数时，即是在告诉浏览器在**将来的某个时间**调用作为第一个参数的函数。\r\n传统习惯来说，如果你想要js重复执行某个特定的任务（函数），你可以使用setInterval函数。但\r\nsetInterval与requestAnimationFrame还是有很大区别。\r\n1. 在现代浏览器中无论标签页是否被激活，其中的setInterval（func）函数都会反复调用func，而erquestAnimationFrame只有当标签页处于激活状态时才会生效，页面停止绘制，资源高效利用。\r\n2. 相当一部分的浏览器的显示频率是16.7ms。加入搞个10ms setTimeout,显示器在16.7ms刷新间隔之前发生了其他绘制请求(setTimeout)，导致所有第三帧丢失，继而导致动画断续显示（堵车的感觉），这就是过度绘制带来的问题。不仅如此，这种计时器频率的降低也会对电池使用寿命造成负面影响，并会降低其他应用的性能。这也是为何setTimeout的定时器值推荐最小使用16.7ms的原因（16.7 = 1000 / 60, 即每秒60帧）。而requestAnimationFrame就是为了这个而出现的。如果浏览设备绘制间隔是16.7ms，那就以这个间隔绘制；如果浏览设备绘制间隔是10ms, 那就以10ms间隔绘制。这样就不会存在过度绘制的问题，动画不会掉帧。\r\n\r\n### requestAnimationFrame 的实现原理\r\n* 注册回调函数\r\n* 浏览器更新时触发 animate\r\n* animate 会触发所有注册过的 callback\r\n这里的工作机制可以理解为所有权的转移，把触发帧更新的时间所有权交给浏览器内核，与浏览器的更新保持同步。这样做既可以避免浏览器更新与动画帧更新的不同步，又可以给予浏览器足够大的优化空间。\r\n\r\n"}}
{"actor":{"display_login":"banshenghuiyi0623"}}