本文主要讲的是基于requestAnimationFrame的函数节流技巧。

如果你还不熟悉requestAnimationFrame,你可以看一下msdn上的这篇文章基于脚本的动画的计时控制。

requestAnimationFrame有助于我们创建丝滑柔顺的动画,同时也有利于优化性能和节约电能。然而我们创建的很多动画都要依赖于DOM事件,像mousemove,resize,scroll等这些事件调用函数的频率却远远比浏览器重绘的频率快,这就造成了和使用setTimeout或setInterval创建动画相似的弊端。举个栗子,比如在一个画布里,我们要创建一个跟随鼠标雪花不断飘落的动画效果。鼠标每移动一下,我们就通过科赫曲线绘制若干随机大小雪花来模拟新产生的雪花。使用科赫曲线画雪花无疑是密集型计算,而mousemove每秒触发上百次,结果就是看到巨卡无比的动画。当然这个方法有很多需要优化的地方,比如你可以缓存一个雪花,用drawImage来替换每次重新绘制路径,然后通过放缩来产生不同大小的雪花;或者用webgl来加速……本文就聚焦于优化mousemove事件。

先做个试验,看看mousemove事件每秒触发多少次。

<!DOCTYPE html>
<html>
<head><title></title>
</head>
<body><script>var time = [], i = 0;function listener() {time[time.length] = Date.now();if (time[time.length - 1] - time[0] > 1000) {console.log(i);document.removeEventListener("mousemove", listener);}i++;}document.addEventListener("mousemove", listener);</script>
</body>
</html>

用浏览器打开这个HTML文档,鼠标晃动个一两秒,打开控制台,在我这里显示的是125。

结果就是在短短的一秒内listener函数调用了高达125次,远超浏览器每秒60次的重绘频率。

下面来看一个特殊的节流函数。

function throttle(fn) {var handle;return function () {var context = this, args = arguments;cancelAnimationFrame(handle);handle = requestAnimationFrame(function () {fn.apply(context, args);handle = null;});};
}

我们先来看这个节流函数对优化mousemove事件的作用,然后再解释它是怎么工作的。

<!DOCTYPE html>
<html>
<head><title></title>
</head>
<body><script>var time = [], i = 0, lis = throttle(listener);document.addEventListener("mousemove", lis);function throttle(fn) {var handle;return function () {var context = this, args = arguments;cancelAnimationFrame(handle);handle = requestAnimationFrame(function () {fn.apply(context, args);handle = null;});};}function listener() {time[time.length] = Date.now();if (time[time.length - 1] - time[0] > 1000) {console.log(i);document.removeEventListener("mousemove", lis);}i++;}</script>
</body>
</html>

重复一样的步骤,控制台上这次显示的是61,接近完美的数字。

现在我们来看看throttle函数的原理。用一个比喻来阐释一下:你要调戏一下KFC,重复给宅急送打电话订餐。假设电话老是占线,你平均1分钟才能打进一次。一个固定的快递负责你们小区。如果客服发现快递还没送到你又打电话进来,客服想这个王八蛋又来催了,直接就挂了你的电话。结果就是一小时你最多只能拿到60份。如果快递1分钟内送不到你手上,你连60份也拿不到。如果快递30秒就送到了,你电话1分钟才能打进一次,也只能拿到60份。你打电话就好比throttle被调用,无论被调用的有多快,requestAnimationFrame只能以接近60fps的速度调用你给定的函数。如果你的给定函数还要执行很长时间,那么一秒内它总共执行的次数就少于60次;如果你给定的函数执行很快,一秒内总执行次数也不会多于60。

我有特殊的节能技巧,处理事件的时候我会装作四处看风景相关推荐

  1. xd使用技巧_魔兽世界怀旧服老玩家才会的治疗技巧,这四个技能需要看时机选择...

    游戏中我们是朋友,聊天侃地,在这里我们可以无拘无束的发言,不会有任何人阻挠,还有大家最喜欢吐槽的小编,请把口水收集好,随时准备和小编一起吐槽! 魔兽世界怀旧服老玩家才会的治疗技巧,这四个技能需要看时机 ...

  2. 如何开搓饵不掉钩_钓鱼技巧!学会这4步!看懂搓饵装钩方法!

    原标题:钓鱼技巧!学会这4步!看懂搓饵装钩方法! 搓饵是学习中的必修课,搓饵看似简单,但是真正搓好并不容易,怎样做到鱼饵不散,下水雾化效果也好? 现在将搓饵的一些心得体会和注意事项介绍给各位钓友,希望 ...

  3. 大学英语b级和计算机b,网络统考丨大学英语B级,6大题型及答题技巧!【零基础学员必看】...

    原标题:网络统考丨大学英语B级,6大题型及答题技巧![零基础学员必看] 试卷结构与题型 [交际用语] 交际用语的会话技能完成对话部分主要是要求考生了解英语日常生活.学习和工作中的会话情景,并能运用英语 ...

  4. UG分模技巧经验总结!模具人速看

    在UG建模模块下使用实体分割时,其中产品内部有碰穿的分型面时,其相应的部分需做一方块实休整 与外面所作的毛坯料做求差运算,里面的方体外型需充分大于产品相应部分,保证方体产品移除后不会被分成多个实体,在 ...

  5. 如何使用facenet详解_如何使用冰箱更节能 使用冰箱节能技巧介绍【详解】

    很多朋友都很喜欢夏天,因为夏天有龙虾烧烤.啤酒西瓜,和各色各样的美食,同时夏天也有冰箱和空调,让夏天不再炎热枯燥,当然这带来的还有高昂的电费,那么怎么样使用冰箱等家电更加节能省电呢?今天小编就来给大家 ...

  6. 苹果打字怎么换行_iPhone实用小技巧,安卓转苹果的同学看完收获尤其大

    苹果iOS系统名声在外两大特点一个是流畅另一个就是交互体验好,从安卓换苹果的小伙伴应该可以明显的感觉到系统的流畅度,但是交互体验好在哪?很多小伙伴都感受不到.所以今天小树特意给大家整理一下iOS的几个 ...

  7. 车内看车头正不正技巧_车内看车头正不正技巧,判断车头正不正看雨刷

    对于不少初学者来说,开车难在如何在车内看车头正不正,有些教练会建议看雨刷来判断车头正不正,这能不能行呢?下面我们来看一下判断车头正不正技巧. 看雨刷来判断车头正不正没有问题,通过雨刷与路面标识作为对比 ...

  8. 【开发技巧】-- 一篇女朋友也能看懂的Spring整合第三方支付(微信支付-扫码支付实现篇)

    1.1 为什么要在项目中使用微信支付? 众所周知,支付宝与财付通(微信支付)是如今第三方支付的两大领头企业,同是微信是一个拥有大量用户群体的一个软件,在项目中整合微信支付在一定程度上可以方便用户购物支 ...

  9. Git小技巧——修改commit的注释内容——一看就会

    在使用git提交commit时需要对本次代码改动进行简要的注释.但有时候需要这些注释进行修改.现在展示2种操作方式: 1.idea版 选择version control,然后选择log,之后选择想修改 ...

最新文章

  1. oracle for 记录数,可视化工具dbForge Documenter for Oracle全新上线!让您轻松记录Oracle数据库...
  2. 三代测序之全长转录本
  3. 【学习笔记】关于DOM4J:使用DOM4J解析XML文档
  4. Windows 技术篇-cmd强制关闭端口、解除端口占用方法,cmd查询端口相关的进程pid并杀死进程实例演示
  5. ELF Format 笔记(七)—— 符号表
  6. Create new Fiori catalog group via personalization
  7. 程序人生:什么是“对用户友好”
  8. 机器人编程与python语言的区别_一分钟看懂“机器人编程”和“少儿编程”的区别!...
  9. 如何调整标题字体大小_软网推荐:找回调整Windows 10字号功能
  10. P2388 阶乘之乘
  11. Hive性能优化(全面)
  12. extjs Ext.XTemplate
  13. B站网站后台工程源码泄露 用户信息还安全吗?
  14. 计算机1级b知识点,初中信息技术等级考试知识点
  15. 计算广告中的名词解释
  16. python+pytesseract本地pdf识别转文字,图片识别转文字,避坑大量识别转文字时的内存泄露问题解决
  17. 前端分页功能(通用)
  18. ele input事件 输入后0.5秒触发
  19. Win10电脑关机后立即自动重启怎么办
  20. 如何点亮QQ邮箱图标 - 龙 炫家族特权

热门文章

  1. 【附源码】计算机毕业设计SSM线上拍卖系统设计
  2. wave文件格式详解
  3. win10系统5小时休眠—windows日志查看 判断非法关机
  4. linux8怎么搭建本地yum仓库,CentOS8 创建本地YUM存储库
  5. Crawling is going on - Beta版本测试报告
  6. GloVe 教程之实战入门+python gensim 词向量
  7. 软件工程理论与实践——吕云翔 课后习题第三章答案
  8. JAVA 佳博热敏打印机利用TSCLIB.dll动态链接库打印物料条码
  9. 军事仿真新纪元——全数据实时驱动视景仿真
  10. 3天破9亿!上万条评论解读《西虹市首富》是否值得一看