三代终端容器 KUN 的首次大考【架构演进】
闲鱼号在闲鱼业务中一直承担着非常重要的角色,它既是卖家组织商品的货架,又是达人自我表达的载体,既是大 V 私域运营的阵地,又是小铺开店经营的门面。它是闲鱼各产品线的交汇点,号店浑然一体,一定要类比的话,它更像是抖音/小红书个人主页 + 淘宝店的综合体。
闲鱼号是个用户高频访问的场景,产品 Feature 快速迭代,体验上备受关注,当下面临的问题:
• 古董级高度耦合的业务代码、多业务线并行的日常需求时常让前端成为交付瓶颈
• 基于 Weex 1.0 渲染附带着大量的双端不一致问题和体验顽疾,也限制了交互创新
最近我们对闲鱼号做了架构升级,相信很快就会和大家见面,这里做个小结,概括下来这次升级直接带来的收益:
体验
中高端机上维持秒开,同时:
• 新增微信朋友圈式的下拉封面交互,手势体感更加连贯,个人表达更加充分
• 新增贴近原生体验的下拉刷新交互,提升 APP 体验一致性
• 优化嵌套滚动的交互体验,纵划横划更加自然顺滑,逛起来更高效
(iPhone12/iOS16 录制,Gif 压缩掉帧严重,实际无明显卡顿感)
可维护性
可维护性的提升是「产品->设计->实现」综合优化的结果,具体:
• 产品侧重新梳理所有 Features,抽象并制订同类功能的表达原则,确定各业务的表达方式、优先级
• 设计侧综合考虑模块权重、所属角色、用户比例、扩展方式等因素确定设计框架
• 技术侧通过组件化拆分+全局状态的方式解耦业务逻辑,提高需求并行效率
为什么要升级
闲鱼号项目已有超过5年历史,目前业务较难向前迭代,原因主要归结为端容器能力受限和架构腐化两方面。
端容器能力受限
闲鱼号目前是前端页面,容器使用 Weex 1.0(后文统称 Weex)。Weex 两年前就少有维护,其既有问题使得承载当下业务有以下问题:
1. 难维护。闲鱼号存在较多的舆情顽疾,究其原因,Weex 不是标准前端容器,在布局、组件、动画、事件等方面与预期不一致。一部分绕道解决,一部分只能保持现状依托升级容器解决
2. 难做好体验。业务定位使闲鱼号在体验上有较高要求,但“这个交互是 Native 实现的,Weex 做不了”不时会出现在业务迭代的技术评估中。
项目架构腐化
闲鱼号有较高的业务复杂度和较厚重的历史上下文。承载了人设、电商、内容、信任等领域的业务,同时存在多维度视图(主/客态、B/C态、内容/电商态),多年下来已发展到 5.x 版本,技术架构仍未进行过本质升级,相关问题已严重影响项目日常维护和迭代,主要体现在:
1. ViewModel 过于复杂。ViewModel 是大管家,统一格式化、将数据派发到模块。在平铺了15+模块数据的场景,ViewModel 改动不时“牵一发而动全身”
2. 缺乏统一的状态共享方案,数据流混乱。组件间通信存在 Vue 事件体系、自建事件体系、全局 controller 、自建状态共享体系多种方式
升级目标
对应上述问题,闲鱼号迎来了技术架构升级。升级核心目标是,未来1-2年技术架构不成为项目迭代、维护的吞吐瓶颈,支撑业务快速、平稳、创新的发展,能持续保持高标准体验。其中:
• 容器能力:升级渲染容器,提升容器能力边界。明显减少存量体验顽疾,多场景协助业务、设计完成理想的交互、视觉体验
• 项目架构:模块解耦,打造清晰的数据流。明显提升迭代效率,减少影响面回归成本和压力,降低不同模块协作冲突次数
其中针对项目架构部分非本文重点,主要通过模块化前端后数据协议、统一状态管理方案进行了解决。后文继续介绍容器能力部分的思考和实践
为什么用 KUN 渲染?
闲鱼号端侧主要问题
为对症下药,对闲鱼号端容器(Weex)侧进行了全面的诊断。问题集中在性能、渲染质量、扩展能力、终端体验一致性四个方面
1. 性能:闲鱼号首屏(700ms)和交互性能不错,性能问题主要在内存上,Weex 页面重度访问是闲鱼客户端 OOM 的主要场景之一。启动 Weex 容器会产生较大的增量内存,部分控件无回收机制也会导致内存增加,如
waterfall
组件: 加载 5 页带来了 3000 个未释放内存节点、40M 内存增量
2. 渲染质量:在基础样式、布局、事件体系等方面和前端预期不一致,如:
• 不支持
overflow: visible
• 不支持
z-index
,层叠只能通过节点位置先后实现• 不支持
display: inline
, 替代方案rich-text
标签不支持line-height
等基础样式控制
3. 终端体验一致性:闲鱼号工程中充斥着大量形如
if(isIOS){xxxx} else if(isAndroid){xxx}
的代码,主要作用之一按端处理,以规避渲染差异。尽管如此,目前两端仍存在不小差异。3. 扩展能力:前端标准和生态起源于 PC,无线设备相对于 PC 存在不少特性,无线端原生能力相对于纯前端也更加丰富。受容器扩展能力(成本)限制,前端无法(标准)实现部分业务认为理所当然的体验:
• 无法在元素上屏前获取元素布局信息(宽、高、位置)。大多折叠场景需要
• 高频动画性能不佳。绑定滚动的动画如 曝光、导航透明度渐变等场景
• 基础控件能力缺失。如:输入框无法自动聚焦、控制聚焦时距离键盘空间;增强控件定制困难,如在嵌套滚动容器上添加回到顶部
为从根本解决上述问题,我们进行了新容器调研。
渲染容器选型
在无线前端容器演进过程中,前端侧比较固定,框架(React、Rax等)驱动业务代码生成 Virtual DOM 以抽象视图结构, 特定 Driver/容器内置 JS Module 将 Virtual DOM 翻译为容器对应的渲染指令;容器侧主要历经 Webview 容器渲染 -> 客户端渲染衍生 -> 自绘渲染(衍生)三个阶段。其中:
1. Webview 渲染容器。为解决 Native 页面 双端研发成本、双端渲染不一致、无动态化、页面与客户端耦合的问题,Webview 容器开始承载无线业务
2. 客户端渲染衍生容器(React Native 、Weex 1.0)。 Webview 解决问题的同时引入了新的问题,渲染性能和能力边界明显逊色,故在 2.0 时代诞生了客户端渲染衍生容器,对接起了前端、客户端生态,用前端生态写,用客户端能力渲染。
3. 自绘渲染衍生(基于 Flutter/完全自绘)。客户端渲染一定程度了解决 Webview 渲染性能、能力边界的问题,但将前端标准/生态 “翻译” 为 Android/IOS 标准/生态的过程,存在明显的失真,实际渲染与预期不一致,Android 与 IOS 不一致。由此,更彻底的方法是重写渲染能力以进行统一。
自绘渲染方案一方面性能优于 Webview,一方面渲染一致性优于 Weex,闲鱼号新容器往自绘(衍生)类选型便是自然的方向。 在自绘容器中,基于 Kraken,闲鱼技术团队自研了 KUN 容器,整体思路是对接前端和 Flutter 生态,用前端写,在Flutter 渲染。对于上文提到闲鱼号端侧的 4 个问题, KUN 对应的解决原理如下:
1. 性能(内存)
• 对于已接入 Flutter 的客户端,打开 KUN 页面的增量内存只有 KUN 引擎本身,没有 Flutter 负担,KUN 引擎较为轻量,内存增量相对于 Webview、客户端衍生方案较少
• Flutter 自身提供了良好的回收能力(sliver),在无限流(瀑布流)场景,内存占用不会随内容加载无限上涨
2. 渲染质量:借助 Flutter 像素级渲染能力,上述
overflow: visible、z-index、rich-text
等问题均能解决3. 终端体验一致性。前端对接的生态从两套变成了一套,以 React Native 和 KUN 中 Text 组件渲染为例:下图中,Text 业务组件在 React Native 下被转为了 JS 元素,在 UIManager.js 中转为 RN Element RCTVirtualText。接下来就是客户端部分,RCTVirtualText 在 C++ 层通过 Bridge 将指令传递给 Native UIManager,UIManager 根据所处不同的系统环境进行组件映射,IOS 映射到 UITextView,Android 映射到 TextView。相对之下 KUN 则是一套映射,呈现 Flutter 基础组件,便能有更好的终端一致性
4. 扩展能力:经过一层 KUN Element 抽象,自定义 Flutter 组件也可视为基础组件同等公民开放给 KUN 前端。如此,通过低成本对接前端、Flutter 生态等方式,KUN 有了灵活强大的扩展能力,以嵌套滚动容器为例:
以上从理论层面推导了 KUN能解决上述问题,我们便开始了闲鱼号升级到 KUN 容器的实践。 现阶段已完成升级,经过了一轮技术灰度。回顾升级过程,也像新生事物一样充斥着标准对齐、性能等诸多细节问题,但最终都悉数解决,整体体验符合预期。
体验变化效果
性能
首屏性能上,KUN 与 Weex 1.0 勉强持平,中高端机器上维持秒开。内存水位上初步测试较 Weex、WebView 有所降低,待补充准确数据(上图为 KUN,下图为 Weex)
渲染质量
基础样式、布局、事件体系等方面已基本对齐前端标准,
overflow: visible、z-index、rich-text
等均已正常渲染扩展能力
Kun 使得前端享有了闲鱼客户端 Flutter 生态。闲鱼号升级中,快速扩展了前端无法(标准)实现组件10余个,包括:
• 流畅嵌套滚动
• 富交互下拉封面
• 滚动视频播控
• 图片加载控制(裁剪、渐显等能力)
• 带高斯模糊背景的弹幕
(Gif 压缩掉帧严重,实际无明显卡顿感)
• 借助 Flutter 能力取背景图主色的蒙层
• 借助 Flutter 在上屏之前能获取布局信息,标准化实现了纯前端难以模拟的行数过多动态折叠功能
终端体验一致性
渲染引擎较少与 OS 渲染能力耦合,解决了双端组件、交互(bounce 效果)、布局等方面不一致问题。 除了文字排版和字体外,基本做到双端一致。研发过程中,渲染层面也几乎不出现
if(isAndroid){renderAndroid()} if(isIOS){renderIOS()}
的代码。
后续思考
如果从闲鱼号端侧诉求的视角出发,我们可以这样看待 KUN 的演进:
KUN 在基础规范上会持续扩充,并且与 W3C 规范持续对齐;在扩展能力上通过 CSS 扩展、JSAPI 扩展、混合组件扩展等方式持续增强容器能力、拓展容器边界、提升用户体验。
闲鱼号架构在持续演进中。有了 KUN 的加持,我们对此充满信心。
三代终端容器 KUN 的首次大考【架构演进】相关推荐
- 美团外卖终端容器无关化研发框架
2019年9月,美团外卖技术团队联合多个研发部门正式推出了React2X,面向所有的前端研发人员,特别是按业务领域划分的团队,为大家提供一个完整的.开放的多终端容器无关化(Containerless) ...
- 容器编排技术 -- Kubernetes设计架构
容器编排技术 -- Kubernetes设计架构 Kubernetes集群包含有节点代理kubelet和Master组件(APIs, scheduler, etc),一切都基于分布式的存储系统.下面这 ...
- 【云原生】第二篇--容器管理工具 Docker生态架构及部署
容器管理工具 Docker生态架构及部署 一.Docker生态架构 1.1 Docker Containers Are Everywhere 1.2 生态架构 1.2.1 Docker Host 1. ...
- Arista教你如何讨容器、白盒基础架构数据中心玩家的欢心
Arista网络推出旗下的网络操作系统容器版本,目标是争取白盒数据中心用户群,此举得到博通.惠普企业及微软Azure网络的支持. Arista教你如何讨容器.白盒基础架构数据中心玩家的欢心 网络公司A ...
- 拉勾网《32个Java面试必考点》学习笔记之十二------架构演进与容器技术
本文为拉勾网<32个Java面试必考点>学习笔记.只是对视频内容进行简单整理,详细内容还请自行观看视频<32个Java面试必考点>.若本文侵犯了相关所有者的权益,请联系:txz ...
- 从0到1000万:哔哩哔哩直播架构演进史
本期作者 赵海林 B端技术中心资深开发工程师 01 前言 哔哩哔哩直播成立于 2014 年,经过 8 年时间的发展已经从最初的业务试水成长为公司重要的业务板块之一.技术架构也从一个单体服务演进为由数百 ...
- 汽车电子电气架构演进驱动主机厂多重变化
已剪辑自: https://mp.weixin.qq.com/s/P56MaFODVc_eZ4JEOVJvfA 汽车电子电气架构(EEA,Electrical/Electronic Architect ...
- 架构师必看 京东咚咚架构演进
原文地址:http://developer.51cto.com/art/201512/500645.htm 咚咚是什么?咚咚之于京东相当于旺旺之于淘宝,它们都是服务于买家和卖家的沟通. 自从京东开始为 ...
- 融合、协同系统的边缘云原生架构演进和实践
简介:云原生和边缘计算是近两年都非常火的技术话题了,在第十届云计算标准和应用大会上,阿里云高级技术专家熊鹰分享了<基于融合.协同系统的边缘云原生架构演进和实践>,希望通过介绍现在阿里云在边 ...
最新文章
- 粗暴的手动更新方式等效git更新
- mysql5.2 软件园_MySQL Server V5.5 官方安装版
- Python中的向量、矩阵(numpy)
- python用什么系统好_10分钟用python搭建一个超好用的CMDB系统
- java大神请出来_求java大神,请分析以下代码,写出执行结果,并解释每行结果输出的原因。...
- mysql5.6 pt-query-digest_pt-query-digest安装及分析
- ubuntu下定时执行工具cron开启关闭重启
- win10安装mysql出现请键入 NET HELPMSG 3534 以获得更多的帮助。
- QML学习【一】Basic Types
- springboot和ssm的区别
- 怎样安装php5_如何安装php5.3
- linux date 得到指定 datemonth 月的 开始一天 结束一天
- web app 开发
- ati hd4570 linux amd 64 安装命令,ATI 显卡的驱动在Linux下的安装方法
- Training_model(2)
- 9260ac网卡linux驱动,intel wireless-ac 9260 driver
- 南京信息工程大学计算机博士点,南京信息工程大学2021年招收攻读博士学位研究生专业及考试科目...
- 数据泄露,数据防泄密该怎么做?
- 阿里云403(Forbidden)Access to XMLHttpRequest at ‘‘ fromorigin ‘‘ has been blocked by CORS policy:Respon
- 联通4G业务或沿用沃品牌 不推无限量套餐
热门文章
- 「GoTeam 招聘时间」梦映动漫 Golang 开发工程师/高级经理(广州)
- 用ajax做级联操作,学习笔记之MVC级联及Ajax操作
- 关于苹果开发者账号应用的那些事
- 嘉曼服饰上市破发,大跌16%:公司市值37亿 刘溦家族色彩浓厚
- 五邑大学计算机学院院长,五邑大学计算机学院研究生导师介绍曹彩凤
- 哪款蓝牙耳机性价比最高?2023性价比高的蓝牙耳机推荐
- Android开发xposed,用Android Studio开发Xposed插件项目步骤
- 【JAVA】Java学习方法
- C语言提取字符对应的ASCAl,ascall码对照表(ASCII码表)
- python的文件操作、模块操作、os模块、time、datatime模块以及模块的制作