案例分享:阿里巴巴全球化电商核心系统架构实战,点击学习>>> 了解详情
写点什么

有赞移动消息卡片动态化方案实践

2020 年 8 月 08 日

有赞移动消息卡片动态化方案实践

概述

消息业务作为有赞移动的共享业务,在微商城、零售、美业等 B 端 App 中承担着多客服的角色,多客服是有赞为商家提供的连接商家和买家的即时消息客服工具;在精选、有赞客 C 端产品中扮演着用户联系商家的角色。在整个有赞产品中,是商家和用户沟通的桥梁,起着非常重要的作用。


痛点

我们通常来讲把出现在消息会话页面内的内容称做消息卡片,目前消息业务常见的消息卡片有文字、富文本、语音、照片、视频、通知消息,除此之外还有订单详情、推荐商品、核对订单等共计 30 余种消息卡片。目前我们消息卡片都是采用原生来开发,随着业务的日益增多,消息卡片的数量也在成倍的增长,业务方经常提出增加卡片的需求,去开发和维护这些卡片工作量比较大,并且依赖业务方的客户端发版,不够灵活。


现状

目前消息业务在 iOS 端和 Android 端均采用二方库的方式开发,供各个有赞的 App 接入,在 iOS 中采用 Cocoapods 进行二方库的依赖,Android 采用 gradle 来进行二方库的依赖;如果业务方需要增加一种消息卡片从开发到上线按照正常的周期是 1 周到 1 周半,发版周期长、开发效率低。


动态化技术指不依赖 APP 发版,就能进行动态的增加或者修改来更新页面的技术。对于消息卡片这种需要快速迭代、实时调整的业务,动态化具有非常重要的意义。主要优势体现在:


  • 提高人效

  • 缩短版本迭代试错周期

  • 解决版本长尾问题

  • 减少包大小等


整个消息的业务场景如下图所示:



消息聊天以及消息模版都是由消息卡片组成


原生消息卡片

先来说说原生消息卡片的实现方案,这里以 iOS 为例。整体架构设计我们采用 TableView 作为整个页面的容器,采用 MVVM 的架构去设计,架构分为以下模块:


  • 消息卡片数据源配置类 Configurator 负责 VC 和数据源处理类的绑定以及消息管理处理

  • 消息卡片接口管理类负责接收/发送消息数据处理,重发的操作、界面接口(增、删、改、查)

  • 数据源操作类 TableAdapter 负责 TabelView 的代理方式、数据源代理方法的实现,以及一些视图刷新等相关操作

  • 消息卡片内容视图工厂类 ContentFactory 会根据消息类型注册对应的 ContentConfig 进行一个缓存

  • 消息卡片配置类 ContentConfig 是根据消息类型从工厂类中获取的,返回当前消息卡片的宽高(size)、消息体 message、当前渲染的消息卡片视图

  • 消息模型 layout ,根据不同的消息类型生成,会保存当前的消息体以及消息卡片的宽高,为了提升性能,缓存在 TableAdapter 数据源操作类中

  • 消息卡片 cell,根据后端下发不同的卡片类型,从消息卡片配置类中获取不同的 contentView 加到 cell 中,进行消息卡片的展示

  • 消息卡片 contentView,负责消息卡片 UI 布局、数据的渲染、绑定


整个架构如下图所示:



消息原生架构图


方案

关于动态化技术栈的选择

上面介绍了 iOS 端消息卡片渲染架构设计,那么为了让消息卡片具有动态化的能力,但是不会打乱现有原生架构的情况下,我们采用了结合 weex 技术栈来做这件事。为什么用 weex 来提供动态化这样的能力?首先该技术栈已经在有赞移动中扮演者重要的角色,我们团队之前已经做了 weex 无线开发平台,我们团队主导建设了 ZanWeex ,它是一整套解决方案,从开发、构建到发布、热修、数据、监控,全生命周期的平台和工具,目前有赞业务很多模块都是以 weex 来实现,也接入了长连接功能,无须重启 App 实现实时下发的功能,对 weex 有兴趣 的,可以查阅 weex 官网。


因此我们的核心思路是利用 weex 来达到消息动态化的目的。


  • 创建 weex 容器,为了避免容器臃肿, 这里我们没有选择 ViewController 来充当 weex 的容器,而是用 View 来充当容器,里面包裹了一个 WXSDKInstance 进行 weex 的渲染。

  • 原生端创建渲染 weex 的 TableViewCell,将 weex 容器视图添加到 cell 的 contentView 中去,利用 TableView 的重用机制进行 cell 的缓存和重用。


动态化能力

技术架构设计

在架构设计上面,我们在以前原生的 MVVM 的基础上,利用 JS 动态库,配合 weex 达到动态化卡片的能力,做到了 App 不发版的情况下,只需发布 weex 就可以动态添加消息卡片,也可以修改消息卡片的 UI 样式。鉴于这样的设计目标,在这个框架里,主要考虑以下方面:


  • 在不改变原有原生架构的基础上去做消息卡片动态化

  • 页面布局动态化,意思是页面的排版布局,可以通过 weex 端和 JS 端发布来达到动态更新

  • 组件的复用,为了在多种类型的卡片中保持良好的性能,需要对 weex 端容器进行缓存和复用

  • 开发、构建、发布整个流程需要拥有一个完善的平台


JS 动态库

JS 动态库是我们团队出的一个动态化方案的框架,主要功能是提供动态下发的能力;快速修复线上问题;两端特殊复杂的逻辑保持一致等。JS 动态库也是利用 ZanWeex 平台来开发、构建到发布,一整套流程都是完善的,这里我们不去过多的讨论 JS 动态库的相关内容,我们仅仅是用到动态下发的能力,核心思路是:


  • 利用 JS 动态库根据消息类型下发对应的 weex 卡片的 url

  • 利用 JS 动态库根据消息内容和消息类型来计算原生承载 weex 容器的 TableView 的 cell 宽高

  • 利用 JS 动态库下发需要加载 weex 卡片的消息类型

  • 利用 JS 动态库根据消息类型来判断当前的 cell 是否是 weex 卡片 cell


接入 JS 动态库

  • 我们在 JS 动态库中,暴露出获取 weex 卡片对应的 url 方法,入参是消息类型

  • 获取 weex 卡片所在的 cell 的宽高,入参是消息卡片内容和消息类型,JS 将卡片内容解析出来,进行高度、宽度的计算返回给原生。

  • 获取需要支持 weex 卡片的消息类型,原生根据这些类型进行容器 cell 的注册


性能

性能较好,在多个 weex 卡片消息交替出现的时候,为了避免达到性能瓶颈,因此首先考虑到利用原生 TableView / RecyclerView 的重用机制,拿 iOS 来举例,用 weex 的 url 和 TableView 的 identifier 做一个绑定,这样不必自己去维护 weex 卡片的重用和回收。第一版做出来的时候发现,这样在持续加载 weex 卡片的时候 WXSDKInstance 会不停的渲染调用 renderWithURL 方法,这样无疑是消耗比较大的性能去创建 weex 视图。因此我们在 weex 容器中做一个标记,记录上次该容器加载的 url,每次在加载 weex 卡片 cell 的时候去判断当前的 url 是否是上次记录的 url,如果是,就说明这个类型的 weex 卡片之前已经渲染过,WXSDKInstance 实例可以拿到原生传过来的数据进行 refreshInstance;否的话用 WXSDKInstance 进行 renderWithURL,这样可以节省一次 render 重新渲染,从而解决卡片太多,上下滑动的时候会出现短暂的空白现象。


整体流程

  • 消息通道连接的时候,weex 模块去拉取对应的注册的 weex 页面;初始化 JS 动态库,其实也就是拉取 JS 相关的逻辑配置

  • 后端下发消息数据,经过数据解析器将消息经过转化生成 layoutModel 缓存起来

  • 在消息卡片视图工厂类 contentFactory 中,将消息类型传到 JS 端来判断当前消息类型是否需要注册成 weex 卡片

  • 在获取卡片宽高、消息模型的卡片内容配置类 contentConfig 中,将消息类型、消息内容传到 JS 端,返回 weex 卡片宽高

  • 数据操作类去持有 LayoutModel 和 contentConfig 类,在 TableView 代理方法回调的时候,去加载对应的 weex 卡片和宽高,并且将 weex 卡片的 url 作为 identifier 重用标记

  • TableView 加载 weex 容器的 Cell 时传递消息类型到 JS 动态库,然后返回对应的 weex 卡片 url,然后根据 url 将消息卡片内容传递到 weex 容器端去进行渲染或者刷新


架构设计如下图所示:



消息动态化架构图


优化

目前整个流程已经上线,情况比较稳定,极大的提高了开发效率,增加/修改消息卡片做到完全动态化,但是目前我们的方案也有很多不足之处,比如我们期望更好的性能和更高的运行效率、更加动态化的事件处理能力、更加方便的开发体验,对此我们也做了更进一步的规划建设:


  • 组件创建、布局计算、数据绑定机制、从 JS 端获取数据做缓存的优化,提升性能

  • 规范事件点击回调处理,提供跳转商品详情、订单详情、原生特定页面 router 以及 webView 的事件处理

  • 拆分出动态化框架 SDK ,让其他需要用到的业务可以接入,比如一些活动页面


总结

以上是我们整个消息卡片动态化的整体方案,总结来讲就是在原生架构基础上配合 weex 技术栈、JS 动态下发,达到整个动态化的目的,可以算作一个轻量化的动态化方案,算是在动态化方面做一些尝试,也希望可以和广大开发同学一起交流。


参考链接:



本文转载自公众号有赞 coder(ID:youzan_coder)。


原文链接


https://mp.weixin.qq.com/s?__biz=MzAxOTY5MDMxNA==&mid=2455761163&idx=1&sn=32e318bdf0c847021abc5e621193172c&chksm=8c68772ebb1ffe38768f187645f73848879ed6bd7baf8f50a4b6e81556dc8b7ab56868d22579&scene=27#wechat_redirect


2020 年 8 月 08 日 14:051890

评论

发布
暂无评论
发现更多内容

openGauss X ShardingSphere,分布式方案的另一种最佳实践

SphereEx

数据库 开源

MySQL日志15连问

云流

Java MySQL 数据库 面试 后端

使用Java故意消耗Cpu和内存的代码

不想秃头

Java 程序员

“京东商城”亿级高并发秒杀系统到底是怎么设计的?自己做该如何下手?

Java架构师迁哥

阿里P8手抄本惨遭泄露,并出现病毒式传播,致28人斩获大厂offer

Java架构师迁哥

32岁的我裸辞了,八年Java老鸟,只因薪水被应届生倒挂,在闭关三个月后拿到阿里Offer,定级P7!

Java架构师迁哥

炸了!阿里又一力作上传GitHub,Spring Cloud Alibaba差距不止一点

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

开源即巅峰!阿里首次分享:Java架构师全栈“成长笔记”

Java架构师迁哥

GitHub榜首的阿里“绝巅版”Java工程师手册,看完才知道差距多大

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

鲲鹏BoostKit虚拟化使能套件,让数据加密更安全

华为云开发者社区

鲲鹏

包头市企业如何申请等保测评?去哪里申请?联系电话是多少?

行云管家

网络安全 等级保护 等保测评 等保评测 包头

由于太全被各大厂要求Github连夜下架

Java架构师迁哥

音视频编解码流程与如何使用 FFMPEG 命令进行音视频处理

声网Agora

音视频 ffmpeg

垃圾弹窗广告,如何清除互联网世界的牛皮癣

石头IT视角

互动赠新书|当云原生遇到混合云:如何实现“求变”与“求稳”的平衡

阿里巴巴云原生

云计算 云原生 混合云

发布60分钟!霸榜Github的阿里面试参考指南,啃透涨薪10k

Java架构师迁哥

足足541页!费了大力气才从GitHub上扒下的阿里Java优化“圣经”

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

GitHub星标70K阿里大佬手写的Spring Boot实战手册

Java架构师迁哥

The Data Way Vol.4|开源是创造软件诸多方法中最好的一种形式

SphereEx

数据库 开源

主机监控用什么软件好?监控机制是怎样的?

行云管家

运维 IT运维 主机监控

某宝付费的Redis核心原理深度实践PDF,竟在GitHub标星86k+霸榜

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

真香!霸榜掘金首页第一,阿里内部Java性能调优笔记终于开源了

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

不愧是阿里内部“千亿级并发系统架构设计笔记”面面俱到,太全了

胧月

Java 架构 面试 后端 高并发

求职季,我是这样拿到百度AI Offer的!

百度开发者中心

百度 AI 求职

软件真的可以定义汽车么?

软件定义汽车

软件 物联网 汽车

你见过最具有代表性面试是什么样?大三4面上岸腾讯(Java岗)

Java架构师迁哥

一位年薪 180 万的字节大佬扔给我的四份学习笔记

Java架构师迁哥

诧异!GitHub上竟有阿里专家用800页笔记,只讲MySQL调优而且火了

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

Fish-Lottie:纯Dart如何实现一个高性能动画框架?

阿里巴巴移动技术

flutter 开源 dart 客户端

没想到我也可以入职阿里!二本毕业、两年crud经验,侥幸通过面试定级P6

Java架构师迁哥

牛客网论坛最具争议的Java面试成神笔记,看过的人都已经成功进入大厂

Java 白

Java 编程 程序员 架构 面试

数据库运维技术发展与展望

数据库运维技术发展与展望

有赞移动消息卡片动态化方案实践-InfoQ