移動端Click300毫秒點擊延遲的來龍去脈(轉)


原文地址:What Exactly Is….. The 300ms Click Delay

快速響應是所有 UI 實現的重中之重。研究表明,當延遲超過 100 毫秒,用戶就能感受到界面的卡頓。 然而,出於對手指觸摸滑動的區分,移動端頁面對於觸摸事件會有 300 毫秒的延遲,導致多數用戶感覺移動設備上基於 HTML 的 web 應用界面響應速度慢。 本文主要討論上述延時的來歷,瀏覽器生產商的考慮,以及我們作為開發者,當前應該如何處理這個問題。

300 毫秒延遲的來歷

這要追溯至 2007 年初。蘋果公司在發布首款 iPhone 前夕,遇到一個問題 —— 當時的網站都是為大屏幕設備所設計的。於是蘋果的工程師們做了一些約定,應對 iPhone 這種小屏幕瀏覽桌面端站點的問題。

這當中最出名的,當屬雙擊縮放(double tap to zoom)。這也是會有上述 300 毫秒延遲的主要原因。

雙擊縮放

雙擊縮放,顧名思義,即用手指在屏幕上快速點擊兩次,iOS 自帶的 Safari 瀏覽器會將網頁縮放至原始比例。

下面以這篇網站響應時間的文章頁面為例,剛一打開頁面,除了文章本身,我們還看到頂部通欄、菜單等非關鍵性要素。

 

iPhone 上展現被縮小的文章頁面

我們進入這個頁面的目的顯然是為了閱讀這篇文章。所以當我們雙擊屏幕時,Safari 會相當智能地縮放至主體文章。

同一張頁面在 iPhone 上雙擊放大后的效果,聚焦在文章主體內容

上述例子表明,iOS Safari 在雙擊后准確地定位到頁面主體文章,並將其縮放至適合比例展現。這也相當符合個人使用習慣。

那么這和 300 毫秒延遲有什么聯系呢?

假定這么一個場景。用戶在 iOS Safari 里邊點擊了一個鏈接。由於用戶可以進行雙擊縮放或者雙擊滾動的操作,當用戶一次點擊屏幕之后,瀏覽器並不能立刻判斷用戶是確實要打開這個鏈接,還是想要進行雙擊操作。因此,iOS Safari 就等待 300 毫秒,以判斷用戶是否再次點擊了屏幕。

於是,300 毫秒延遲就這么誕生了。

后 iPhone 時代的 300 毫秒延遲

鑒於 iPhone 的成功,其他移動瀏覽器都復制了 iPhone Safari 瀏覽器的多數約定,包括雙擊縮放。幾乎現在所有的移動端瀏覽器都有這個功能。 六年前,一個人們還在為通過移動設備上網而驚嘆的時期,如此性能損失並無大礙。然而如今,是個移動端開發的 web 應用性能可以同原生應用匹敵的時代,所有的單擊事件都有 300 毫秒延遲,必然是不可接受的。此外,隨着響應式設計的逐步推進,開發者們已經根據設備本身的尺寸對站點進行了優化,也就逐漸淘汰了諸如雙擊縮放的約定。

可喜的是,瀏覽器開發商已經意識到這個問題,並已相繼提出了一些解決方案。

注:iOS Safari 還有一個鮮為人知的約定。用戶可以在靠近屏幕頂部或底部約 1/4 范圍內的區域雙擊來滾動頁面內容。當你在一個放大了的頁面內豎向滾動的時候,是否有過不小心將頁面橫向滾動的經歷?雙擊滾動正是為解決這個問題而生的。盡管后續出現的移動端瀏覽器復制了雙擊縮放這一行為,它們並未復制雙擊滾動的行為。這是我們稍后將會討論到的很重要的一點。

瀏覽器開發商提供的解決方案

避免點擊延遲,提供一個響應迅速的移動端瀏覽器,可以說這是瀏覽器開發商的當務之急(當然,蘋果公司除外)。因此,開發商們提供了一些比較有意思的解決方案。

禁用縮放

首先來看一個一目了然的解決方案。既然雙擊縮放僅對那些可被縮放的頁面來說有存在意義,那對於不可縮放的頁面,直接去掉點擊延遲,何樂而不為呢?這里所說的不可縮放,是指使用了下述<meta>標簽的頁面。

Android 平台的 Chrome 瀏覽器率先做出了這一改變,Android 平台的 Firefox 瀏覽器隨后實踐之。其他瀏覽器開發商對這點優化暫無明確計划。

然而這個解決方案看似完美,但也帶來一個明顯的缺陷 —— 你必須完全禁用縮放來達到目的,而從移動端站點的可用性和可訪問性來看,縮放是相當關鍵的一環。你很可能已經遇到過這個問題,即你想要放大一張圖片或者一段字體較小的文本,卻發現無法完成操作。

只能說 Android 平台上的 Chrome 和 Firefox 瀏覽器提供的禁用縮放優化,僅適用於 web 游戲等某些特定的場景,但多數網站並不能從中獲益。

不過,Google Chrome 開發團隊最近提出了更好的方式。

width=device-width Meta 標簽

除了雙擊縮放的約定外,iPhone 誕生時就有的另一個約定是,在渲染桌面端站點的時候,使用 980 像素的視口寬度,而非設備本身的寬度(iPhone 是 320 像素寬)。

下面是一個非常簡單的頁面,展現一張小貓的照片,照片寬為 320 像素。

由於默認的視口寬度是 980 像素,在 iPhone 上會看到我們的小貓蜷縮在了左上角。

一個簡單的 web 頁面在 iPhone 上的默認渲染效果。視口寬度默認為 980 像素

當然,我們可以繼續用<meta>標簽來進行配置。

這條代碼告訴瀏覽器將視口大小設為設備本身的尺寸。這在 iPhone 上的效果就是把視口寬度從默認的 980 像素改為 320 像素。下面的截圖,即為添加這條代碼之后的效果,現在這張照片就撐滿整個屏幕寬度了。

使用 meta 標簽將剛才的頁面視口設為 320 像素寬的效果

注:上述默認視口尺寸的約定,也被后續其他瀏覽器開發商所復制。因此上述現象不止是針對 iPhone 和 iOS Safari 瀏覽器。

那這一約定又和 300 毫秒點擊延遲有什么聯系呢?

Chrome 開發團隊不久前宣布,在 Chrome 32 這一版中,他們將在包含 width=device-width 或者置為比 viewport 值更小的頁面上禁用雙擊縮放。當然,沒有雙擊縮放就沒有 300 毫秒點擊延遲。

深入之后,我們會發現這一做法還是相當有道理的。在我們還不知道響應式設計為何物的時代,雙擊縮放的誕生解決了在移動設備上瀏覽桌面端站點的問題。既然站點內包含了width=device-width這一<meta>標簽,也就意味着這個網站采用了響應式設計,因此也就消除了在該站點上可能潛在的雙擊縮放需求。

這一解決方案的另一個關鍵之處在於它只是去除了雙擊縮放,但用戶仍可以使用雙指縮放 (pinch to zoom)。可見,縮放功能並非被完全禁用,也就不存在可用性和可訪問性的問題了。

在我看來,這是一個令人振奮的方案,很好地提升了移動端站點的性能。當然,主要的問題是width=device-width這一優化目前僅被 Chrome 32 所支持。

那么其他瀏覽器是否也會實現這一優化?它所帶來的性能提升顯而易見,Firefox 很有可能會隨后跟上。至於 Internet Explorer,除非其開發團隊只看好指針事件 (pointer events,即將在下一節介紹)。這里最舉棋不定的還屬 iOS。

除了雙擊縮放,前面還提到 iOS Safari 是唯一一個提供雙擊滾動的移動端瀏覽器。如果 iOS 要實現上述優化,那勢必要去掉雙擊滾動。結果如何,還留待時間為我們解答。

以上就是使用<meta>標簽配置視口信息來解決 300 毫秒點擊延遲的全部內容了,但別急,還有一個值得討論的方案 —— 指針事件。

指針事件 (Pointer Events)

指針事件最初由微軟提出,現已進入 W3C 規范的候選推薦標准階段 (Candidate Recommendation)。指針事件是一個新的 web 事件系列,相應的規范旨在使用一個單獨的事件模型,對所有輸入類型,包括鼠標 (mouse)、觸摸 (touch)、觸控 (stylus) 等,進行統一的處理。

例如,你可以只去監聽一個元素的pointerdown事件,無需分別監聽其touchstartmousedown事件。對指針事件的深入解析已經超出了本文的討論范圍,但有一個和點擊延遲直接相關的實現 —— 一個名為touch-action的新 CSS 屬性。

根據規范touch-action屬性決定 “是否觸摸操作會觸發用戶代理的默認行為。這包括但不限於雙指縮放等行為”

從實際應用的角度來看,touch-action決定了用戶在點擊了目標元素之后,是否能夠進行雙指縮放或者雙擊縮放。因此,這也相當完美地解決了 300 毫秒點擊延遲的問題。

touch-action的默認值為auto,將其置為none即可移除目標元素的 300 毫秒延遲。例如,下面的代碼在 IE10 和 IE11 上移除了所有鏈接和按鈕元素的點擊延遲。

你甚至可以在<body>元素上設置touch-action: none,這就徹底禁用了雙擊縮放 (注:這也同時禁用了雙指縮放,因此也會帶來前面討論到的可訪問性和可用性問題。)

但就目前而言,只有 Internet Explorer 實現了指針事件,不過近期 Chrome 也宣布了將在未來的版本中提供支持

好消息是,我們現在已經有一些指針事件的 polyfills 可以在項目中使用了。接下來我們將討論當下可用的 polyfill 以及其他解決 300 毫秒延遲的方案。

當前如何避免延遲

盡管瀏覽器開發商針對 300 毫秒延遲問題提出了一些解決方案,但目前並沒有簡單通用的方案。不過,已經有好多開發者考慮過這一問題,並帶來了一些基於 JavaScript 的跨平台解決方案。這些方案可以歸為兩類 —— 針對指針事件的 polyfill 和“快速點擊 (fast click)”。

首先來說說指針事件的 polyfill。

指針事件的 polyfill

指針事件的 polyfill 比較多,以下列出比較流行的幾個。

為避免 300 毫秒點擊延遲,我們主要關心這些 polyfill 是如何在非 IE 瀏覽器中模擬 CSStouch-action屬性的,這其實是一個不小的挑戰。由於瀏覽器會忽略不被支持的 CSS 屬性,唯一能夠檢測開發者是否聲明了touch-action: none的方法是使用 JavaScript 去請求並解析所有的樣式表。HandJS 也正是這么做的,但不管是從性能上來看還是其他一些復雜的方面,這都會遇到問題。

Polymer 則是通過判斷標簽上的touch-action屬性 (attribute),而非 CSS 代碼。下面的代碼展示了 Polymer 是如何在鏈接上模擬 CSStouch-action: none屬性的。

這對於我們開發者來說意味着什么?如果你比較感興趣,想深入指針事件,那上述 polyfill 就非常適合應用到手頭的項目中。然而,你若只想尋求一個解決 300 毫秒點擊延遲的方法,上述方案可能就有點過了,因為它們要么是資源密集型的方案,要么是touch-action屬性的非標准化模擬。所以,接下去我們要來看一些專門針對 300 毫秒延遲而生的解決方案。

注:上面這一節內容大多參考自 Points 這個 Polyfill 的 README 文件。感興趣的話不妨深入閱讀之。

FastClick

FastClick 是 FT Labs 專門為解決移動端瀏覽器 300 毫秒點擊延遲問題所開發的一個輕量級的庫。簡而言之,FastClick 在檢測到touchend事件的時候,會通過 DOM 自定義事件立即觸發一個模擬click事件,並把瀏覽器在 300 毫秒之后真正觸發的click事件阻止掉。

FastClick 的使用方法非常簡單,在 window load 事件之后,在<body>上調用FastClick.attach()即可。

attach()方法雖可在更具體的元素上調用,直接綁定到<body>上可以確保整個應用都能受益。當 FastClick 檢測到當前頁面使用了基於<meta>標簽或者touch-action屬性的解決方案時,會靜默退出。可以說,這是真正的跨平台方案出來之前一種很好的變通方案。

就目前而言,FastClick 非常實際地解決 300 毫秒點擊延遲的問題。唯一的缺點可能也就是該腳本的文件尺寸 (盡管它只有 10kb)。如果你非常在意這點文件大小,可以嘗試一下 Filament Group 的Tappy!,或者 tap.js。兩者都相當輕量,能夠通過監聽tap而非click事件來繞過 300 毫秒延遲。

Kendo UI Mobile

最后一點,如果你是 Kendo UI Mobile 的用戶,那你完全不必擔心上述問題。一個自定義的點擊延遲解決方案已經作為 Touch widget 的一部分打包好了。這個 touch widget 是一個跨平台的 API,幫助處理所有平台的用戶點擊事件,所有的 Kendo UI Mobile 組件都會默認調用它。

實際上,這也是為什么在 HTML5 Mobile Challenge 中,我們制作的這個名為 cuteness 的應用,很難分辨出它到底是一個 web 應用還是原生應用。如果你是第一次聽說,現在就可以在手機上打開cuteness.io來體驗一下。

小結

盡管蘋果公司創造的雙擊縮放行為,是一種在移動設備上訪問桌面端站點的不錯的解決方案,但隨之引入的 300 毫秒點擊延遲也成為了移動端網站讓用戶感覺卡頓的罪魁禍首之一。

與此同時,瀏覽器開發商也提出了一些解決方案。對於縮放被禁用的網站,Android 平台上的 Chrome 和 Firefox 瀏覽器會禁用雙擊縮放功能;如果站點內配置了內容為width=device-width<meta>標簽,Chrome 32 及以上版本的瀏覽器也會禁用雙擊縮放功能;Internet Explorer 則對元素引入了全新的 CSS 屬性,touch-action,若將其置為none,也會取消該元素上的點擊延遲。

由於這些解決方案較為零碎,社區里也有一些基於 JavaScript 的解決方案,包括一些指針事件的 polyfill,諸如 FastClick 之類專門為這個問題而生的腳本,以及類似 Kendo UI Mobile 等自主方案。

雖然 JavaScript 的方案很好地解決了延遲問題,但畢竟只是臨時的措施。瀏覽器本身所提供的方案,例如 Chrome 的width=device-width優化以及 Internet Explorer 的指針事件等,更屬長久之計。

未來發展如何,讓我們拭目以待。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM