滑屏的交互方式在运营类 H5 中已趋于普遍,五月份在做 QQ 时光机时曾写过《分屏滑动 H5 移动页面 UI 开发小结》,转眼半年已如白驹过隙,最近在做会员 15 周年主会场,对滑屏有了更多的心得与经验教训,一言以蔽之:需求与场景是多变的,而对性能和速度的要求却是永恒的。 陈皓(左耳朵耗子)曾经在微博里说过: 如今 iOS 和 Android 系统两家独大,前者在性能与特性支持度上一直走在前沿,而后者的开放性导致了如今良莠不齐的局面,同时近几年不断增强的硬件配置并未让人觉得性能上有颠覆性的突破(至少从 Webview 的表现上看)。作为大多数「麻烦」的始作俑者,Android 总让人爱恨交加。但为了 iOS 与 Android 上一致的体验,我们不得不寻求最佳的平衡点。 回归到「滑屏」这一出发点,不禁自问,如何尽可能得保证页面在安卓上的性能最佳? 第一问:拖拽翻屏,还是自动翻屏?页面随手势拖拽: touchend 后页面才翻屏: 如上面两个 Gif 图所示,两种方式的差异在于:
看似差别不大的两种交互,实现复杂度差别巨大,在 Android 中的体验更是不一样。前者需要在每个 touchmove 的时候进行计算与定位,计算量庞大,而后者只需要在松开手指后再进行计算与翻页,性能提升不是一两点。 更重要的是,从第一种方案切换到第二种时,几乎没有人发现了这微妙的改变。显然这两种交互方式并不能明显区分开来,所以自动翻屏自然是最佳的选择。 第二问:滑屏技术的最佳实现方式是什么?控制 wrapper 滑动 控制每一屏滑动 如上 Gif 图所示,滑屏可以在 wrapper 上操作,也可以将每一屏作为独立的滑动元素。简单的活动可能两者并无太大差异,但假如把多样的需求和场景考虑到,可以发现在滑屏上也会细化出很多功能点:
在上述要求下,前者已显得分身乏术,而后者由于其元素间的自由性,可以满足上述的需求,且效果更佳,虽然实现复杂度会提高。 然而我把最关键的给落下了,最最最关键的是:前者的实现方式在部分安卓上经常会出现卡在上一屏与下一屏中间的情况,一开始遇到时做了很多补救都无果,最终才无奈替换了整个滑动方案,采用第二种控制内部元素的方式,可谓血的教训。 什么是卡在上一屏与下一屏中间呢,类似这样: 简单分析下原因,整个页面都通过在 body 上监测 touchmove 时增加 event.preventDefault 来阻止自然的页面滑动,但唯独安卓有时候在有动画的元素上移动时,body 会捕捉不到 touchmove 事件,所以页面可以滚动了,便出现上述可以滑动 wrapper 的情况,而方案二控制每一屏滑动,每屏最宽最高就只是屏幕的宽高,所以也不会出现正常的页面滚动了。 第三问:首屏需要 Loading 吗?需要吗?需要。不需要吗?不需要。 需不需要看需求对 H5 的定位,若是类似微信朋友圈广告的这种品牌运营 H5,有大量素材作为支撑的页面,是需要进入时 loading 的,这一点希望提前跟产品达成共识;但假如是系列活动中比较重要的入口,需要多次进入的(如会员15周年的主会场),则不要有 loading,力求一进入就能直接看到。 针对有 loading 的情况,还需要考虑: 是否一次性将所有资源 load 完? no no no,即使有专门的 loading 页,都请分屏加载,否则这里将会流失大量用户。 那资源的体积跟时间之间应该形成一个怎样的认知呢? 看表(根据 Chrome 开发者工具 Network 换算数据):
上述是理想数值,实际上根据腾讯云统计到的 2G/3G 的下载速率,远未达到理想的速度: (但4G 会高于 Network 里换算的值) 根据《工信部及三大运营商发布11月用户发展情况》可得知:中国移动用户 2G 用户占 41.4%,3G 用户占 31.3%,4G 用户占 27.3%。远远没有长期处于 WiFi 环境下的我们想象的那么美好。虽然这些用户并非长期使用 2/3G,但是我们的页面必须确保在 2/3G 环境下有一个顺畅的体验。建议首屏资源在 300KB 左右,并设置缓存。 针对无 loading 的情况,还需要考虑: 1、假如页面有比较丰富的动画,需要先加载资源才能被正常播放呢? 要么去掉动画,要么用 CSS 或 JS 来实现动画,必须要做出取舍。 2、既然是无 loading 的页面,自然对速度有要求,还能提高加载速度吗? 可以,请分屏加载。若希望做到体验无缝,请在前一屏加载后一屏的资源。 第四问:内部滚动怎么办?如果这一屏不涉及复杂的 DOM 跟很重的效果,我还是觉得可以使用 iScroll,虽然它在安卓上的性能一直被诟病,但经过非常多安卓机的检验,效果还是在可接收范围内的,但别忘了前提:DOM 不复杂(如活动规则页)。 那是否有更好的解决方案呢?有! 我们再回看之前滑屏的最佳实现方式: 可以看到,在每一屏上进行操作,当上一屏或下一屏滑动到当前屏时,之前的那一屏会去掉 translate 属性,回归到最初的状态(被当前屏盖在下面,即 position:absolute; left:0; top:0),这个时候,将当前屏的 position:absolute; height:100% 去掉,使其回归文档流,那么 body 将会被撑开,页面可以被正常滑动,连 iScroll 都省了。 结语相信对于大部分 UI 开发来说,写出一个安卓下不卡顿,没有兼容性问题的页面是最美好的愿望,有时候甚至可以针对 iOS 跟 Android 专门写一套代码,看似工作量大,其实可以规避掉很多不必要的麻烦。同时也需要跟产品、设计师们在安卓上的体验退化上达成一致,以免页面做出来后带来预期上的落差。 这次在会员15周年中尝试了很多种技术,比如通过 Canvas 播放视频、视频在移动页面的应用以及 HTML5 音频探索 等,后续也将输出文章。来体验下会员15周年的活动吧:http://vip.qq.com/clubact/2015/clubbirthday15/index.html |
|
来自: richard_168 > 《待分类》