隨著智慧型手機與平板電腦的普及,我們的應用程式在行動裝置上的流量佔比持續攀升。然而,將原本為桌面端設計的豐富互動介面移植到行動瀏覽器上,往往會面臨許多意想不到的挑戰。在眾多行動裝置中,iOS 系統上的 Safari 瀏覽器擁有其獨特的渲染機制與觸控事件處理邏輯。近期,我們收到了大量使用者的回饋,指出在 iPhone 或 iPad 上瀏覽應用程式的特定資料列表區塊時,捲動體驗非常糟糕,經常出現卡頓、生硬,甚至整個頁面被意外拖曳的狀況。為了提供跨平台一致的優質體驗,我們決定針對行動裝置的捲動機制進行深度優化。
在著手解決這個問題時,我們踩入了一個行動網頁開發中非常經典的坑。為了在頁面內部實現局部區塊的捲動(例如一個固定高度的列表),我們最初使用了標準的 CSS 屬性 overflow: scroll。在桌面瀏覽器上,這通常運作得相當完美,會自動顯示捲動條並允許滑鼠滾輪進行平滑捲動。然而,當這套樣式應用到 iOS Safari 時,災難就發生了。
我們發現,當使用者用手指在觸控螢幕上滑動這個 overflow: scroll 的區塊時,捲動動作顯得極為僵硬,完全失去了 iOS 系統原生的那種帶有慣性(Momentum)的滑順感。更糟糕的是,如果使用者在列表捲動到頂部或底部時繼續滑動,會觸發 iOS 著名的「橡皮筋效應(Rubber-band effect)」,導致整個網頁背景跟著被拉扯,甚至讓頁面底部的工具列錯位,嚴重破壞了應用的沉浸感。
一開始,我們試圖透過 JavaScript 來攔截 touchmove 事件,並手動計算滑動距離來控制捲動行為。我們編寫了複雜的邏輯來判斷何時應該允許區塊捲動,何時應該阻止預設行為以避免頁面拉扯。結果不僅程式碼變得異常臃腫難以維護,而且因為 JavaScript 執行緒與瀏覽器渲染執行緒的同步問題,捲動時反而出現了更嚴重的延遲與畫面撕裂(Tearing)。我們意識到,用 JavaScript 去模擬原生捲動行為是一條完全錯誤的道路。
經過深入查閱 WebKit 引擎的技術文件與開發者論壇,我們找到了問題的癥結所在。iOS Safari 預設對於非 body 元素的 overflow 捲動,並未開啟硬體加速與慣性捲動。要喚醒原生的順暢體驗,必須藉助 WebKit 專屬的 CSS 擴充屬性。我們果斷捨棄了那套複雜的 JavaScript 攔截方案,將修復重心轉回 CSS 層面。
我們在需要局部捲動的容器上,添加了 -webkit-overflow-scrolling: touch; 這個神奇的屬性。這個屬性會指示 iOS 系統為該元素建立一個獨立的硬體渲染層(Compositing Layer),並啟用原生的動量捲動(Momentum Scrolling)演算法。只要加上這一行程式碼,手指滑動離開螢幕後,列表依然會根據滑動的初速度繼續平滑捲動一段距離,完美還原了原生 App 的手感。
針對橡皮筋效應導致整個頁面被拉扯的問題,我們結合了最新的 CSS 特性,調整了外層容器的邊界行為,確保使用者在列表邊界狂滑時,只會觸發該容器內部的邊界回彈,而不會牽連到外層的整個文件視窗,徹底解決了頁面錯位的危機。
/* 舊版樣式:iOS Safari 上捲動生硬且無慣性 */
.scrollable-list {
height: 400px;
overflow-y: scroll;
/* 缺乏針對行動裝置的捲動優化 */
}
/* 之前嘗試的錯誤方向(JS 攔截) */
/* document.addEventListener('touchmove', ...); */
/* 新版樣式:啟用硬體加速慣性捲動與防止連鎖效應 */
.scrollable-list {
height: 400px;
overflow-y: auto;
/* 關鍵修復:啟用 iOS 原生慣性捲動 */
-webkit-overflow-scrolling: touch;
/* 防止捲動邊界觸發整個網頁的橡皮筋效應 */
overscroll-behavior-y: contain;
}
這次的修復為行動裝置使用者帶來了一項極為重要的體驗升級:原生級別的平滑捲動(Native-like Smooth Scrolling)。雖然這不是一個全新的業務功能,但它解決了使用者在瀏覽資訊時最頻繁互動的痛點。
現在,當使用者在手機上瀏覽長串的資料列表、歷史紀錄或聯絡人清單時,每一次的手指滑動都變得如絲綢般滑順。慣性捲動讓使用者能夠快速且不費力地瀏覽大量內容,而不再需要一次又一次地費力拖曳螢幕。此外,透過防止捲動邊界的連鎖效應,應用程式的介面變得更加穩固,不再像是一個隨時會被拉破的網頁,而是真正具備了彷彿原生應用程式般的紮實質感。這種細微但關鍵的互動回饋優化,極大地提升了使用者在行動端操作時的愉悅感與留存意願。