如何解决移动端300ms延迟的问题

如何解决移动端300ms延迟的问题

声明一下:300ms只是行业内部的统称,其实应该在300ms-350ms之间的一个数值。

移动端300ms延迟的前世今生

背景: 2007 年初。苹果公司在发布首款iPhone前夕,遇到一个问题:当时的网站都是为大屏幕设备所设计的。于是苹果的工程师们做了一些约定,应对iPhone这种小屏幕浏览桌面端站点的问题。

这当中最出名的,当属双击缩放(double tap to zoom)。顾名思义,即用手指在屏幕上快速点击两次,iOS自带的Safari浏览器会将网页缩放至原始比例。如下图所示:


这是一个很好的设计啊!那它和延迟有什么关系呢? 我们假定一个场景。当用户看到一张图片,而此时图标又刚好是一个链接地址。用户点击到图片之后,并不能立即判断用户是要打开链接,还是说想观看图片的细节。因此Safari 就等待300毫秒,判断用户是否再次点击了屏幕。这也是会有上述 300 毫秒延迟的主要原因。

由于iPhone的这一成功,许多浏览器厂商开始支持这一功能。但是随着技术的发展,性能的提升。慢慢的出现了混合开发,web应用在某些场景一开始逐渐替代了原生开发。此时所有的单击事件都有300毫秒延迟,必然是不可接受的,那怎么去解决这个问题呢?

方法一、禁用缩放

既然大家都觉得缩放没有意义,那就提供一个属性去控制它。在HTML文档头部添加如下meta标签

<meta name="viewport" content="user-scalable=no">
<meta name="viewport" content="initial-scale=1,maximum-scale=1">

有一个小小的缺点需要说一下,由于图片和文字都是一比一的比例显示的,而且禁用了缩放功能。在某些情况下,需要放大某张图片或者某段文字,就是无法实现图片的双击放大了。(除非js脚本)

方法二、更改默认的视口宽度

还是在HTML文档头部添加如下meta标签

<meta name="viewport" content="width=device-width">

这个方法跟方法一有些许不一样,他将页面的宽度设置成了,与显示屏同宽。需要网站做响应式布局。否则显示效果极易受到影响。还有他没有禁止缩放功能,所以,你可以用双指操作来放大页面。

方法三、CSS touch-action

html {
    touch-action: none
}

这是个CSS属性,如果值为 none 的话, 就表示禁用掉该元素上的浏览器代理的任何默认行为(缩放,移动, 拖拽),无300ms延迟。你也可以在html标签上面设置该属性,虽然该方法实现了禁用缩放。但是其他的触摸类型交互事件都被禁用了。导致页面无法滚动。

方法四、FastClick.js

熟悉移动端开发的同学,相信都见过这个轻量级库文件。我们引入库文件之后,添加如下代码就可以了。

window.addEventListener( "load", function() {
FastClick.attach( document.body );
}, false );

那FastClick的原理是什么呢? 其实就是FastClick在检测到touchend事件之后,会通过 DOM 自定义事件立即触发一个模拟 click 事件,并把浏览器在 300 毫秒之后真正触发的 click 事件阻止掉。

方法五、指针事件的polyfill

现在除了IE,其他大部分浏览器都还不支持指针事件。有一些JS库,可以让我们提前使用指针事件,比如

总结: 以上这五种方式基本支持日常的开发需求了,我个人比较推荐使用方法一加方法二,因为我目前所遇到的页面都对移动端做了专门的适应。

其实,关于移动端300ms的延迟问题,还引来一个比较经典的前面面试问题,我们下篇讲解!


编辑于 2021-03-29 16:32