天猫精灵App首页信息流是怎样实现的

栏目: IT技术 · 发布时间: 4年前

内容简介:我们先来简单介绍下信息流的概念。从布局形式上来看也被称为“瀑布流”,如图,卡片大小错落有致,且无需用户翻页,新的内容通过懒加载自动添加到页面底端。

我们先来简单介绍下信息流的概念。

从布局形式上来看也被称为“瀑布流”,如图,卡片大小错落有致,且无需用户翻页,新的内容通过懒加载自动添加到页面底端。

天猫精灵App首页信息流是怎样实现的

从数据格式上来看也被称为“feed流”,“feed”即一种信息单元格,可以理解为某一段文字、一张图片、一段音频、一段视频等。那么App上的信息流可以简单地归结为:无限加载的交互+个性化推荐的内容。

再简单介绍下信息流的发展。自瀑布流的鼻祖Pinterest上线之后,国内各种类Pinterest交互的应用也如雨后春笋般出现,远的如今日头条、美丽说、花瓣网,近的如手淘、闲鱼、飞猪等,让你刷刷刷、买买买欲罢不能。信息流在手淘首页、购物车、商品详情页等随处可见。

天猫精灵App首页信息流是怎样实现的

回到我们天猫精灵App,老版本首页存在流量分发效率低下的问题,让人失去往下翻的欲望。随着内容商业化的进一步推进,以及语音购逐渐为大众所接受,各种三方内容和商品源源不断地接入,在诸多矛盾日趋尖锐的情况下,首页信息流呼之欲出。

尽管有现成的实现方案可以参考,因天猫精灵App和天猫精灵音箱是一对孪生兄弟,因此需要考虑 运营投放问题:我们有几十款音箱设备,不同设备的运营投放内容不同,很大一部分设备需要维持老卡片投放,因此我们既要实现信息流,也要兼容老卡片;

接下来介绍天猫精灵APP首页信息流从0到1的工程化落地。

天猫精灵App首页信息流是怎样实现的

结合上图我们来梳理下这次改动对整体框架产生影响的几个点:

      1 、滑动动效

      2 、下拉刷新位置调整(原下拉刷新统一在顶部)

      3 、老卡片兼容(个数随机)

      4 、信息流无限加载

      5 、信息流卡片渲染(需要独立的承载容器)

除了实现上述看得见的需求以外,还要解决看不见的问题:

1 如何维持内存水位?

2 、如何保障滑动流畅?

接下来的任务就是进行合理的技术选型和首页框架设计,清晰划分每个区块,然后在每个区块填充各自的元素和动效,管理各自的内存占用。

  • 渲染技术选型

App3.0 首页的框架设计已经可以支持卡片扩展、内存复用、滑动流畅等基本能力,目前可支持20多种卡片,但毕竟是native实现的,无法支持卡片样式的在线增加和动态更新。从长远来看,信息流不是简单的一种交互方式,而是各种业务的分发载体,一成不变的卡片样式势必无法满足源源不断的新业务。那么,卡片的 在线发布 动态更新 就显得不可或缺。

据了解,手淘使用了自研的DinamicX方案来实现整个首页所有卡片的渲染, 概括来说,DinamicX就是把原本在本地开发的布局文件放到了云端,因此,DinamicX卡片天然就是信息流的好搭档,既拥有native的体验,也支持在线发布和动态更新。

综上,卡片渲染的技术选型基本确定:为兼顾项目上线时间和卡片样式更新,老卡片复用原有的native方案,信息流卡片选用DinamicX方案。

  • 控件内存介绍

我们用梯子来类比App里面控件的内存占用情况,一种控件像消防梯,伸缩自如,但它的内存占用也是线性增长的,这种控件我们称之为 “线性控件”(LinearLayout) ,如下图,这类控件一般用于承载一屏以内的视图。

天猫精灵App首页信息流是怎样实现的

线性控件

另一种控件就像自动扶梯,它的高度固定,但是它的踏板可以循环往复地滚动,因此占用的内存就是可见部分所占的内存,即 “内存复用” 技术(如下图),这类控件我们称之为 “循环滚动控件”(RecyclerView) ,常用于承载列表类卡片。

天猫精灵App首页信息流是怎样实现的

循环滚动控件

  • 火车模型

初看视觉稿,我们自然会想到把各个区块一个接一个地串连起来,就像一列火车跑在轨道上,第一节是顶部区块,第二节是动效执行区块,第三节是老卡片区块,第四节是信息流区块,除了第四节使用“循环滚动控件”,其他几节使用“线性控件”,我们把这个模型称为 “火车模型”

天猫精灵App首页信息流是怎样实现的

这种模型的优点是实现简单,基本没有什么衍生的副作用。如果不需要兼容老卡片,那么这个模型基本上就够用了,为什么这么说呢?上文我们介绍过背景,不同的设备投放的卡片不一样,我们就必须考虑极端情况下,运营同学配置了几十个甚至更多的老卡片,这时就存在内存溢出的风险了。

  • 自拍杆模型

于是我们思考另一种模型—— “自拍杆模型” ,自拍杆的特点是一截套一截,每一截都可以伸缩滑动。

天猫精灵App首页信息流是怎样实现的

如下图,我们用动画容器套下拉刷新组件,下拉刷新组件套一个循环滚动控件,这个循环滚动控件我们称之为 “父容器” (如红色虚线框),用于承载老卡片和一个循环滚动控件,里面这个循环滚动控件我们称之为 “子容器” (如绿色虚线框),用于承载信息流卡片。

天猫精灵App首页信息流是怎样实现的

嵌套方案

上文提到,“循环滚动控件”占用的内存仅屏幕可见区域所占的内存,那么“自拍杆模型”中的“父容器”就解决了老卡片带来的内存溢出风险。但是, 有利必有弊 ,从“火车模型”转为“自拍杆模型”,牵一发而动全身,如果我们对“自拍杆模型”不做任何优化,就会发生信息流无法滑动或者只有信息流能够滑动的现象,这就是App开发中令人头疼的 “嵌套滑动冲突” 问题,它存在于每一层嵌套之中,就好比自拍杆从顶上往外拉,当你去拉第一截时,第一截没拉出来,反而把第二截或者第三截拉出来了,或者只有第一截能拉动,其他几截怎么都拉不动,这个场景想必大家可以脑补一下,体现在App上如下:

如果“嵌套滑动冲突”处理不好的话,更为严重的副作用是“父容器”和“子容器”将无法发挥内存复用的能力,首页内存会随着老卡片或信息流卡片的加载而暴增。

  • 解决嵌套滑动冲突

解决该问题的核心就在于对用户滑动事件的合理消费,以“父容器”和“子容器”之间的嵌套为例:

1 、随着父容器的滑动,当子容器出现在屏幕可见区域时,抢夺用户滑动事件。如图红色标注,子容器在滑动过程中,将用户手指滑动的距离 x 通知给父容器,然后由父容器根据自身当前情况决定是否消费滑动距离,如果父容器消费了滑动距离 y ,那么子容器就会消费剩余的滑动距离 (x-y) ,惯性滑动事件也是如此,流程如下左图。

2 、当子容器滑动到临界位置时就释放滑动事件交由父容器处理。结合自拍杆脑补,当往外拉时,里面的一截先往外拉,当它拉到底时套着它的那一截再开始往外拉;当往里缩时,套着它的那一截先往里缩,当这一截缩到底时里面的一截再开始往里缩,App上效果如下右图(示意图来自网络)。

天猫精灵App首页信息流是怎样实现的

嵌套滑动时序图

天猫精灵App首页信息流是怎样实现的

嵌套滑动 demo

解决思路理清楚了,那么任何一层的嵌套滑动问题都随之迎刃而解,剩下的细节填充只是时间问题了,最终的实现效果如下视频:

  • 首页性能

首先来看下首页连续滑动时的内存水位:

天猫精灵App首页信息流是怎样实现的

可以看出,首页内存占用基本维持在390M上下,远低于OOM 崩溃安全线,再来看下信息流加载过程中的滑动流畅性:

视频中的柱状图中每一根的高度即代表每一帧的渲染耗时,滑动优化的细节在此不做展开,总体来看,天猫精灵App首页滑动性能不低于业界头部App

  • 总结

本篇主要介绍了天猫精灵App首页框架设计,为兼顾不同设备的运营投放,因此选择了“自拍杆模型”,并解决了该模型引起的“嵌套滑动冲突”问题,首页的整体内存水位因此也得到了有效控制。

(全文完)

其它精选文章:

扫码或长按关注微信公众号: 天猫精灵技术。

天猫精灵App首页信息流是怎样实现的 讲述天猫精灵背后的技术


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

遗传算法原理及应用

遗传算法原理及应用

周明、孙树栋 / 国防工业出版社 / 1999-6 / 18.0

一起来看看 《遗传算法原理及应用》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具