前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >对用户输入事件的处理去抖动

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

作者头像
吴裕超
发布2018-12-12 16:04:31
8660
发布2018-12-12 16:04:31
举报
文章被收录于专栏:吴裕超吴裕超吴裕超
用户输入事件处理函数是一个可能会导致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事件!

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-11-13 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 用户输入事件处理函数是一个可能会导致web应用性能问题的因素,因为它们在运行时会阻塞帧的渲染,并且会导致额外且不必要的布局的发生。
  • 一.Summary
  • 二.避免使用运行时间过长的输入事件处理函数
  • 三.避免在输入事件处理函数中修改样式属性
  • 四.对滚动事件处理函数去抖动
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档