移动端300ms点击延迟问题

4,188 阅读3分钟

前言

最近在做一个移动端的react项目,验收时被提到一个优化问题,就是列表的active状态切换太慢了,而且在安卓和PC上都是没延迟的,就ios上有,大概就是这样一个常见的列表:

image

针对这个现象我搜索了一下无果在我们前端讨论群了说了一下,有两个小伙伴都甩给了我同一个解决方案:引入react-fastclick

import initReactFastclick from 'react-fastclick';
initReactFastclick();

像这样安装模块引入之后ios上的点击延迟就真的消失了诶,可是为什么呢?怀着好奇的心查了一堆资料得知原来我这个就是传说中的点击事件300ms延迟造成的。 (虽然之后听过,但没遇到过,也没处理过,哈哈)。

移动端点击事件为什么会有300ms延迟

简单来说,就是早期苹果为了判断移动端上的双击缩放事件而加的,在touchendclick事件之间加300ms的延迟来判断用户到底是点击还是双击。

谷歌开发者文档原文是这样说的:

For many years, mobile browsers applied a 300-350ms delay between touchend and click while they waited to see if this was going to be a double-tap or not, since double-tap was a gesture to zoom into text.

怎么解决300ms延迟呢

  • fastclick

    就是我文章开头提到的我司小伙伴给我提供的方案,也算是一种比较简单粗暴的方案。fastclick是专门为解决移动端浏览器300毫秒点击延迟问题所开发的一个轻量级的库。fastclick的原理是在检测到touchend事件的时候,会通过DOM自定义事件立即触发模拟一个click事件,并把浏览器在300ms之后的click事件阻止调。

  • 禁用缩放 通过下面的hack技巧,不添加fastclick也能修复延迟的问题

    • 适用场景:
      • Chrome on Android (all versions)
      • iOS 9.3
    • 处理代码
    <meta name="viewport" content="user-scalable=no" />
    

    这种方案经过实测,在高版本安卓上市没问题的,但在ios上就要看webview了,如果使用的是UIWebView那也还是会有延迟的,如果用的WKWebView就没有延迟了。关于ios的WKWebView想了解更多的大家可以自行搜索,总之就是性能会比UIWebView好的一个新的webview,在iOS 8 上提出的,ios的微信端目前已经采用了WKWebView

使用fastclick的坑

因为我第一次使用这个库,所以还没具体遇到过,但从这篇文章描述的情况来看大体能猜到一些什么样的场景容易掉坑里,那就是页面比较复杂,不仅仅是有点击事件的事件,原理上面讲了。

总结

我在自己项目中最终选择的解决方案就是禁用缩放,因为我们ios客户端最近正好更新了WKWebView,哈哈哈。这样可以避免一些不可预料的坑,也能少引入一些代码。在安卓上只要我们把缩放禁用就不会出现延迟了。

如果是在UIWebView的场景的情况下,大概率还是会出现300ms延迟的,这个时候如果页面不是太复杂,也是可以引入fastclick的。

参考