滑屏的互動形式自從在 H5 中流行起來,便廣泛應用在產品宣傳、廣告、招聘和活動運營等場景中,作為微信朋友圈廣告慣用的形式,其影響力更是得到了強化與放大。如今滑屏H5可謂玲琅滿目,數不盡數。
作為一個 UI工程師,接過很多類似的專案,也曾寫過滑屏的外掛,在經歷了不同的需求的“洗禮”並踩過若干個坑之後,不禁反問自己:應該如何面對每一次類似的需求,在已有的經驗下如何做到體驗更好?如何節省工作量提高效率?面對效能優秀的 iOS 與效能良莠不齊的 Android 平臺,又如何做到體驗統一與效能最優?
第一問:拖拽翻屏,還是滑動翻屏?
頁面隨手勢拖拽後翻屏
滑動後(touchend)後翻屏
如上面兩個 Gif 圖所示,兩種方式的差異在於:
- 拖拽翻屏:頁面隨手指拖動而移動,手指鬆開(touchend)後翻頁
- 滑動翻屏:頁面不隨手指拖動而移動,手指鬆開(touchend)後翻頁
看似差別不大的兩種互動,實現複雜度差別巨大,在 Android 中的體驗更是不一樣。前者需要在每個 touchmove 的時候進行計算與定位,計算量龐大(關注數字變化):
而後者只需要在鬆開手指後再進行計算與翻頁,效能大幅提升:
而且從第一種方案切換到第二種時,互動上的微妙改變並沒有帶來直觀的影響。所以從效能角度上,滑動翻屏自然是最佳的選擇。
第二問:滑屏技術的最佳實現方式是什麼?
控制 wrapper 滑動
控制每一屏滑動
如上 Gif 圖所示,滑屏可以在 wrapper 上操作,也可以將每一屏作為獨立的滑動元素。簡單的滑動可能兩者並無太大差異,但假如把多樣的需求和場景考慮到,可以發現在滑屏上也會細化出很多功能點:
- 迴圈滑動
- 滑動禁用與開啟
- 預載入 / 延時載入
- 初始化時顯示某一頁
- 滾動到某一頁、跳過某一頁
- 提供滑動前、滑動中、滑動後的介面
- 滑動時間、速度、緩動效果自定義
- 考慮動態增刪頁數而無差錯
- 考慮頁面縮放、橫豎屏切換
在上述要求下,前者已顯得分身乏術,而後者由於其元素間的自由性,可以滿足上述的需求,且效果更佳,雖然實現複雜度會提高。
最關鍵的是,前者的實現方式在部分安卓上偶爾會出現卡在上一屏與下一屏中間的情況,一開始遇到時做了很多補救都無果,最終才無奈替換了整個滑動方案,採用第二種控制內部元素的方式,可謂血的教訓。
簡單分析下原因,整個頁面都通過在 body 上監測 touchmove 時增加 event.preventDefault() 來阻止自然的頁面滑動,但唯獨安卓有時候在有動畫的元素上移動時,body 會捕捉不到 touchmove 事件,頁面可以滾動了,便出現上述可以滑動 wrapper 的情況,而方案二控制每一屏滑動,每屏最寬最高就只是螢幕的寬高,也就不會出現頁面滑動了。
第三問:首屏需要 Loading 頁嗎?
需要嗎?需要。不需要嗎?不需要。
需不需要看需求對 H5 的定位,若是類似微信朋友圈廣告的這種品牌運營 H5,有大量素材作為支撐的頁面,是需要進入時 loading 頁的,這一點希望提前跟產品經理達成共識;但假如頁面是系列活動中比較重要的入口,需要多次進入,則不要有 loading 頁,力求一進入就能直接看到。
針對有 loading 的情況,還需要考慮:
是否一次性將所有資源 load 完? no no no,即使有專門的 loading 頁,都請分屏載入,否則這裡將會流失大量使用者。
那資源的體積跟時間之間應該形成一個怎樣的認知呢? 看錶(根據 Chrome 開發者工具 Network 換算資料):
上述是理想數值,實際上根據騰訊雲統計到的 2G/3G 的下載速率,遠未達到理想的速度:
根據《工信部及三大運營商釋出11月使用者發展情況》可得知:中國移動使用者 2G 使用者佔 41.4%,3G 使用者佔 31.3%,4G 使用者佔 27.3%。現狀遠遠沒有長期處於 WiFi 環境下的我們想象的那麼美好,雖然這些使用者並非長期使用 2G/3G,但是頁面必須確保在 2/3G 環境下有一個順暢的瀏覽體驗,避免使用者流失。建議首屏資源在 300KB 左右(大概載入時間為 2~3s 左右),並設定快取。
針對無 loading 的情況,還需要考慮:
假如頁面有比較豐富的動畫,需要先載入資源才能被正常播放呢? 要麼去掉動畫,要麼用 CSS 或 JS 來實現動畫,必須要做出取捨。
既然是無 loading 的頁面,自然對速度有要求,還能提高載入速度嗎? 可以,請分屏載入。若希望做到體驗無縫,請在前一屏載入後一屏的資源。
第四問:內部滾動怎麼辦?
內部滾動即某屏內部還有滾動(但實際上系統的滾動跟滑屏的滾動是衝突對立的),如果這一屏不涉及複雜的 DOM,我還是覺得可以使用 iScroll,雖然它在安卓上的效能一直被詬病,但經過非常多安卓機的檢驗,效果還是在可接收範圍內的,但別忘了前提:DOM 不復雜(如活動規則頁)。
那是否有更好的解決方案呢?不妨回看之前滑屏的最佳實現方式:
可以看到,在每一屏上進行操作,當上一屏或下一屏滑動到當前屏時,之前的那一屏會去掉 translate 屬性,迴歸到最初的狀態(被當前屏蓋在下面,即 position:absolute; left:0; top:0),這個時候,將當前屏的 position:absolute; height:100% 去掉,使其迴歸文件流,那麼 body 將會被撐開,頁面可以被正常滑動,是不是連 iScroll 都省了?
正如你體驗到的那樣,理想很豐滿,現實很骨感,在 PC 上的體驗這個Demo是沒有問題的(請在 Chrome 下模擬手機滑動),然而因為 iOS 和 Android 中很多瀏覽器都自帶 bounce 回彈效果,而 iOS 和 Android 的大部分瀏覽器中,頁面滾動時是會阻止頁面重繪的(JS 的執行也無法立刻生效在頁面中),所以Demo 裡看到的效果就是回彈後才翻屏。所以目前這個方案頁僅限於某些場景使用。
第五問:背景音樂是預設開啟或是關閉?
之前在做一個宣傳活動 H5 的時候,預設開啟過音樂,發現 28w 曝光只有 800 個人主動關閉音樂。所以預設開啟還是最優的,在製作音訊的時候注意體積最好在 100~200k 範圍,並且預設音量不應該太高,收尾漸入漸出,還得注意版權。
然而目前不管是手 Q 或是微信,都存在一個偶現的 bug:在手機中切換頁面或者回到主螢幕,H5 的背景音樂依舊在播放,除非殺掉程式。初步猜測為 Webview 未正確得到釋放。
第六問:H5 頁面需要兼顧 PC 平臺嗎?
很多 H5 頁面都只針對移動裝置展示,但如果分享的連結被人在 PC 中開啟呢?比如分享到微博或QQ 空間的連結,被正在電腦上瀏覽的人開啟,看到的是一個顯示不正常的頁面,這樣的體驗是非常不好的。所以最好的做法就是準備一個 PC 的掃碼頁面或將內容搬到 PC,打通迴路,為 H5 頁面引流。
正如之前做過的 QQ 時光機專案:
第七問:動畫如何做低版本退化?
移動端對 CSS3、Canvas、SVG 動畫的支援已經不錯了,目前相容性較差的系統主要有 Android 2.3,它不支援 animtion-fill-mode 屬性,這會導致動畫播放完後無法保持在最後狀態;不支援 before/after 偽元素的動畫;不支援 animation-timing-function: steps,所以也無法玩轉圖片序列幀;所以可以特別針對這個版本進行差異化處理,通過判斷 UA 對其展示靜態頁面。
然而最佳的退化方式不應該是版本檢測,而是能力檢測,可以通過 Modernizr 這個元件判斷裝置具備的能力。
第八問:如何做好適配?
適配的核心就是確保內容在不同的螢幕解析度下顯示正常,經常採用的方式有 REM、Media Query 和 JS+CSS,沒有一套永恆不變的適配方案,往往需要多種結合。如果是比較簡單的展示類H5,可以參考如下的程式碼:
當然,少不了橫豎屏的提示:
不過在 iPhone4/4s 這種小螢幕下,也可以嘗試取消分屏滑動,直接用瀏覽器原生的滾動。
第九問:…
- 分享到各個社交平臺(準備分享引導浮層)
- 使用自定義字型(font spider、fontmin)
- 圖片資源自動合併成雪碧圖(Compass)
相信對於大部分 UI 開發來說,寫出一個安卓下不卡頓,沒有相容性問題的頁面是最美好的願望,有時候甚至可以針對 iOS 跟 Android 專門寫一套程式碼,看似工作量大,其實可以規避掉很多不必要的麻煩。同時也需要跟產品、設計師們在安卓上的體驗退化上達成一致,以免頁面做出來後帶來預期上的落差。
在追求最佳實踐的路上,永遠少不了層出不窮的問題。不一而足,無法窮舉,滑屏只是一種形式,內容才是 H5 的精華所在,切勿捨本逐末。如今可以看到越來越多的創意融入 H5 中(視訊、Canvas、SVG 等),前端世界變得越來越豐富多彩,這對開發者來說是機遇也是挑戰,你我共勉!