对用户输入事件的处理去抖动

用户输入事件处理函数是一个可能会导致web应用性能问题的因素,因为它们在运行时会阻塞帧的渲染,并且会导致额外且不必要的布局的发生。

一.Summary

避免使用运行时间过长的输入事件处理函数,它们会阻塞页面的滚动

避免在输入事件处理函数中修改样式属性

对输入事件处理函数去抖动,存储事件对象的值,然后在requestAnimationFrame 回调函数中修改样式属性

二.避免使用运行时间过长的输入事件处理函数

在理想情况下,当用户在设备屏幕上触摸了页面上某个位置时,页面的渲染层合并线程将接收到这个触摸事件并作出响应,比如移动页面元素。这个响应过程是不需要浏览器主线程的参与的,也就是说,不会导致JavaScript、布局和绘制过程的发生。

但是,如果你对这个被触摸的元素绑定了输入事件处理函数,比如touchstart、touchmove或者touchend,那么渲染层合并线程必须等待这些被绑定的处理函数的执行完毕之后才能被执行。因为你可能在这些处理函数中调用了类似preventDefault()的函数,这将会阻止输入事件(touch/scroll等)的默认处理函数的运行。事实上,即便你没有在事件处理函数中调用preventDefault(),渲染层合并线程也依然会等待,也就是用户的滚动页面操作被阻塞了,表现出的行为就是滚动出现延迟或者卡顿(帧丢失)。

简而言之,你必须确保对用户输入事件绑定的任何处理函数都能够快速执行完毕,以便腾出时间来让渲染层合并线程来完成它的工作。

三.避免在输入事件处理函数中修改样式属性

输入事件处理函数,比如scroll/touch事件的处理,都会在requestAnimationFrame之前被调用执行。

因此,如果你在上述输入事件的处理函数中做了修改样式属性的操作,那么这些操作会被浏览器暂存起来。然后在调用requestAnimationFrame的时候,如果你在一开始做了读取样式属性的操作,那么根据“避免大规模、复杂的布局”中所述,你将会触发浏览器的强制同步布局过程!

四.对滚动事件处理函数去抖动

有一个方法能同时解决上面的两个问题:对样式修改操作去抖动,控制其仅在下一次requestAnimationFrame中发生: 

1  function onScroll (evt) {
2
3  // Store the scroll value for laterz.
4  lastScrollY = window.scrollY;
5
6  // Prevent multiple rAF callbacks.
7  if (scheduledAnimationFrame)
8  return;
9
10  scheduledAnimationFrame = true;
11  requestAnimationFrame(readAndUpdatePage);
12  }
13
14  window.addEventListener('scroll', onScroll);

这么做还有一个额外的好处,就是能使你的事件处理函数变得轻量。这很关键,因为它能使包含复杂计算代码的页面也能快速响应scroll/touch事件!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏破晓之歌

移动web开发适配秘籍Rem(推荐) 原

9310
来自专栏小文博客

Jaguar——简约大气——WordPress主题

17980
来自专栏极客编程

简单介绍一下vue2.0

Vue是用于构建用户界面的渐进框架。作者尤雨熙特别强调它与其他的框架不同,Vue是渐进式的框架,可以逐步采用,不必一下就通过框架去重构项目。 另外Vue的核心库...

19520
来自专栏超然的博客

肢解 HTTP 服务器构建

所有请求数据都在 request对象中,数据解析,还需要 url, querystring模块

11210
来自专栏从零开始的linux

bash

显示当前系统的进程数 # pstree init─┬─AliHids───4*[{AliHids}] ├─AliYunDun───8*[{AliYun...

32280
来自专栏iOS开发笔记

cordova插件-Dialogs

添加插件 $ cordova plugin add cordova-plugin-dialogs ? 图 10如上则添加成功 插件的使用 Methods na...

28030
来自专栏前端人人

React第三方组件1(路由管理之Router的使用③传参)

本教程总共6篇,每日更新一篇,请关注我们!你可以进入历史消息查看以往文章,也敬请期待我们的新文章! 1、React第三方组件1(路由管理之Router的使用①...

34030
来自专栏Micro_awake web

Vue学习5:条件渲染

14830
来自专栏高爽的专栏

Flex事件机制(一)

Flex事件贯穿我们整个开发,事件分为两类,用户事件和系统事件,比如说我们在页面点击了一个按钮,这是用户触发的事件,当组件初始化完毕,会触发creationC...

20700
来自专栏Youngxj

强大的jQuery图片查看器插件使用教程

31650

扫码关注云+社区

领取腾讯云代金券