0到1:闲鱼高复杂度高性能社区圈子开发实录

简介: 鱼乐圈上线啦~

闲鱼会玩社区的重要阵地:会玩圈子今年年初已经上线啦~

作为一款承载着「基于兴趣聚集同好人群」的社区型产品,相较于常规导购型产品来说,在业务复杂度、交互复杂度、性能体验稳定性要求上都要高出许多,像多角色区分嵌套滚动多形态 Feeds 无限加载颜文字等特殊字符处理页面直开视频播控等场景都是导购场景很少遇到的。

本文将围绕着会玩圈子的前端设计、开发过程中遇到的典型问题进行介绍。

关键设计


如上图为会玩圈子的设计大图,可以看到整体的业务逻辑相对较为复杂。并且由于应用中存在多种角色状态,不同角色的用户展示界面和操作逻辑也有差异点存在,前端同学进行开发上手的成本较高。

为了降低前端同学在开发过程中对于全局业务理解的成本,减少沟通中信息传递容易遗漏的问题。我们在设计之初首先进行了最小模块的拆分工作。以模块维度来分配相应的工作,将模块间存在数据共享和数据通信行为进行梳理拆解,以最优方式来分配数据状态维护的最小闭环,降低组件间耦合度。

1. 模块拆分

在此处定义的模块不是前端日常开发中所讲的模块组件拆分,而是能够独立闭环自成体系的一个业务单元。这样在项目过程中除了部分组件间数据传递需要做预先约定外,前端同学仅仅只需要专注于自己所负责的交互场景即可。
  
以圈子模块主页为例,根据设计稿我们将它拆分为了三个独立的业务模块:圈子信息模块、信息流模块和浮层组件模块,他们无论从功能上还是展示上都完全不同。

  • 圈子信息模块: 偏展示型模块。交互较少,根据业务数据展示相应的信息模块内容,需要根据用户当前的身份展示不同类型的模块组件,并且可以根据当前用户的身份来进行权限校验,在未符合时进行友好Tip提示的能力。
  • 信息流模块: 偏交互型模块。需要支持多个列表在Tab下嵌套滚动的能力,模块本身需要维护用户关注状态表、黑名单筛选表和视频播放列表,方便模块中的子组件进行数据共享。并且列表具备单排流和瀑布流两种布局模式,列表内元素存在商品、帖子内容两种类型卡片。支持评论、点赞查看原图、视频播放、触发浮层等多种交互能力。
  • 浮层模块:通用型模块。允许开发者根据业务需求注册相应的模块组件,并且允许配置相应的展示位置、动画效果和图层index

2. 状态值拆分

由于在圈子中有非常多需要共享信息的场景存在,例如用户相关数据、圈子基础信息等,仅仅只是基于业务模块闭环来拆分状态在此处就不适合了。

因此在完成模块拆分之后我们对圈子主页的状态数据进行了梳理,根据组件最小渲染原则来对状态进行相应的拆分,如下图所示:

全局状态

如上图,对于有共享诉求的状态变量,我们优先将这些状态值汇总到一起以方便统一处理。

但由于是C端场景,交互复杂度不高并且考虑到资源包的大小会对用户体验有一定影响。此处的全局状态的管理方案我们选择了直接使用Rax原生的useReducer + useContext来进行处理,并将获取对应实例context 的方法Hooks化以方便开发同学使用,简单demo代码如下所示:

业务组件状态

对于非共享型的数据,则要求放到业务模块中组件渲染影响最小的容器层来进行维护,以单排流的帖子列表为例:

  • 卡片的初始数据通过props形式传入,单一帖子的交互性数据都保留在帖子元素组件一层来维护。
  • 列表容器中除了基础状态信息外,仅仅只做视频播放的控制,不额外触发容器级的重渲染。

实施调优

在多个业务模块进行组合调试的过程中,我们发现交互体验依然有许多不尽人意的问题点:

  • 展示模块过多的情况下,如果在多个Tab下进行数据加载切换过后整个页面的交互会出现明显的卡顿感:比如点击弹出浮层会有明显的等待时延,翻页切换Tab时对应的下标移动会不同步。
  • 浮层容器中注册的部分组件由于依赖共享变量,在共享变量变化时也会触发不必要的重渲染:效果为会跟着闪动一下。
  • 网络状况不稳定的情况,页面展示不够友好的;从用户点击路由跳转到首屏页面展示的等待时间过于明显,与我们要求的页面直开效果相差甚远。

    1. 减少Context.Provider重渲染


    使用Context尽管可以提升状态值传递的便捷性,但是伴随的问题也相当明显:每一次状态值更新变化都会触发整个Context.Provider和下面的子组件重新渲染。

这与我们预期的渲染流程不一致,毕竟我可能只是调整了一个CircleHeader组件所依赖的值,没必要底下CircleSlider组件及其中的列表组件都需要跟着做调整渲染,这个代价是我们无法接受的。

通过在社区中寻找相应的解决方案,我们发现还是有一定技巧来解决这个问题的:Context.Provider其实组件也保持着Rax组件的一致规则:props.children作为传入属性,它如果保持不变就不会触发值diff,进而也就不会出现重渲染的问题了。

那如何才能做到让Provider不会由于props.children的变化产生重渲染呢?通过社区提供的资料,我们发现每次执行的都是JSX转义后的createElement(xxx)。由于每次执行产生的子组件都不一致,所以会导致不必要的重渲染。

为此我们将Context.Provider单独拆分成为一个专门用于传状态值的高阶组件,将子组件以props.children的形式传入:

通过这种方式,我们将CircleApp变为了Stateless Component。只有在首次初始化组件时进行渲染,之后Provider值变化时页不会重新导致GlobalContextProvider执行createElement(CircleApp``)来重新创建组件实例了,减少不必要的js执行。

2. 调整组件结构


如上图可以看到在圈子中存在较多弹出浮层组件的场景,在初版设计过程中考虑到浮层组件由于也需要使用到全局共享变量。因此在设计组件结构之初,将浮层容器组件放到了全局共享变量的GlobalContextProvider组件之内。

但在实际体验过后发现,尽管对于内部的浮层组件获取共享变量较便利了,但反馈出来的问题也相当明显:在使用中低端机型时,如果页面加载的数据过多后会出现明显的延迟感。并且浮层组件仅仅在真实展示的时候才需要用到相应的状态值,非展示时其实不需要关系这些数据的具体内容。

 

为此我们调整了浮层容器组件和主页常驻组件的层级结构,如上图所示:将常驻组件容器和层容器由原来的嵌套结构优化为了并行结构,两组件之间的数据通信通过方法调用来触发。这样调整之后优点相对比较明显:首先浮层组件可以更加通用、复用性更强。所有所需参数都是通过传参的方式传入,不需要再强依赖全局共享状态,对于开发同学来说维护起来的成本更低。其次因为减少对共享状态值的依赖,子组件不必要的重渲染也都得到了优化。对于中低端机型也能提供相对更好的互动体验。

3. 首屏体验优化 + 容灾机制

在去年下半年的体验优化升级战役中闲鱼的前端页面体验都有了很大的提升:页面首屏等待时间大幅度降低、内容展示更加友好,各个频道页接入渐进式首屏后用户能更快的查看到内容数据。
但在圈子开发的过程中,我们发现对于个性化推荐的场景之前提出的渐进式首屏方案无法较好的支持。为此我们选择了降级方案,调整了从圈子广场页到圈子主页及相关子页面的路由跳转逻辑。

如上图,通过制定上下游页面之间的数据缓存约定来达成容灾和提高交互体验是目的。在每次页面路由跳转时都将相应的业务数据进行缓存,在下一级页面对消费相应的缓存数据。这样不仅可以在网络环境较差的情况下提升用户的体验。同时在接口报错时进行可以起到最低程度的有效兜底,避免用户体感过差。


优化前                                            优化后

在此基础上为了提升页面首屏的渲染速度,我们接入提升数据预取方案离线包缓存方案。将首屏页面渲染过程中最为耗时的资源包加载过程首屏接口请求过程做了并行化处理,从而降低了首屏展示的等待时长。

优化前后效果对比:

优化前 优化后

后续展望

会玩圈子的首个版本在遭遇各种小问题后终于顺利上线了。在这个过程中解决了部分在之前电商导购场景下未经历过的问题:例如角色权限管控,多状态值管理等问题。这些经验的沉淀对于之后闲鱼社区内复杂C端应用体系的成长可以提供一定的助力。

但目前仍有许多的问题点待我们思考优化:

  • 目前圈子主页的首屏平均可交互时长为1000ms左右,用户从点击入口到进入主页内浏览基本无需等待。但我们相信通过根据设备类型来做区分,在进入页面之初降级部分中低端机非必须能力能够为这一类用户提供更快的交互体验。
  • 为了突出社区内不同圈子个性点,相信自定义的装修能力以及定制插件能力在之后是必不可少的。要如何能够基于现有的架构体系快速接入这些业务诉求,也是我们在现有能力上需要预先思考到的
  • 根据业务诉求的变化,如何将从业务模块中产生的组件尽量做到更通用化并且支持多种容器也是需要解决的。

作者:闲鱼技术——庞止

原文链接

本文为阿里云原创内容,未经允许不得转载

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/514332.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2018年计算机CPU纳米制程,联发科疯狂堆核计划曝光:7纳米制程,12核CPU

【PConline 资讯】联发科疯狂堆核的脚步并未停歇,在商用量产10纳米十核处理器——Helio X30之后,联发科瞄准了更先进的制程、更密集的CPU核心。据台湾电子时报(DIGITIMES)消息,联发科将首次集成12核CPU,预计第二季度由台积电的7纳…

佳能hdr_烧设备无止境不代表随时败家,佳能EOS 5D4“闲鱼”翻身取代200D

2019年最后一天马上翻篇,想过去看今朝我此起彼伏。待到明年赏花浪漫时,我希望我会笑得更开心一点。今天跟大伙说说刚从闲鱼入手的5D4。烧设备可以,烧相机要出人命,看大佬们三天两头往家里败镜头,我的荷包可撑不住。第一…

浅谈数据中台安全体系构建思路

作者:王振东来源:绿盟科技 战略规划部 摘要数据中台是大数据业务体系数据规约化建设的核心场景,数据中台既搭建大量数据归集的相关设施,又针对数据开展大量治理、运维、分析、加工、共享、开放等交互事务,数据暴露面、…

MaxCompute Tunnel 技术原理及开发实战

简介: MaxCompute(原名ODPS)是一种快速、完全托管的EB级数据仓库解决方案, 致力于批量结构化数据的存储和计算,为用户提供数据仓库的解决方案及分析建模服务。Tunnel是MaxCompute提供的数据传输服务,提供高并发的离线数…

js实现一键复制到剪切板上_js实现各种复制到剪贴板的方法

一、实现点击按钮,复制文本框中的的内容function copyUrl2(){var Url2document.getElementById("biao1");Url2.select(); // 选择对象document.execCommand("Copy"); // 执行浏览器复制命令alert("已复制好,可贴粘。");}用…

滴滴 Flink-1.10 升级之路

简介: 滴滴实时计算引擎从 Flink-1.4 无缝升级到 Flink-1.10 版本,做到了完全对用户透明。并且在新版本的指标、调度、SQL 引擎等进行了一些优化,在性能和易用性上相较旧版本都有很大提升。 一、 背景 在本次升级之前,我们使用的…

戴尔服务器一直显示配置内存,dell服务器内存故障解决及排查

如果系统可以运行,请运行相应的诊断检测程序。有关可用的诊断测试,请参阅使用系统诊断程序。如果诊断程序指示出现故障,请按照诊断程序提供的更正措施进行操作。如果系统无法运行,请关闭系统和连接的外围设备,并断开系…

苹果新算法已混进 iOS 14.3!CSAM 检测技术再遭网友争议

整理 | 禾木木出品 | CSDN云计算(ID:CSDNcloud)苹果宣布即将推出 CSAM 检测系统时,遭到了 4000 多个组织及个人的公开反对,他们质疑苹果会破坏用户隐私和端到端加密机制。一位 Reddit 用户发现 CSAM 算法竟已被悄悄地隐…

数字化时代,阿里云云效如何构建下一代研发协作工具平台?

简介: 本次分享主要由四部分组成: 1、企业在成长过程中遇到的研发效能困境; 2、研发管理从信息化走向数字化的路径,以及背后的逻辑; 3、云原生和 AI 两项新技术在研发平台上的落地; 4、结合阿里巴巴自身案例…

axiosa安装_axios安装及使用

axios 安装npm install axios --saveaxios 使用1. axios 的引入在main.js文件中引入(在main.js引入即为全局引入)// axios需要使用prototype将axios挂载到原型上 ,$后面是自己另起的名称,以后就可以使用该名称Vue.prototype.$axios Axios2.在组件中直接…

珠海小学计算机比赛,欢聚一堂 共叙佳话 —— 参加珠海市中小学信息技术工作年会纪要...

欢聚一堂 共叙佳话——参加珠海市中小学信息技术工作年会纪要2012年12月22日,香洲区中小学信息技术工作室一行8人赴金湾一小,参加了珠海市教育学会中小学信息技术教学专业委员会组织的第三届年会,会议分为四项议程。一、近两年工作总结上午&a…

安谋科技发布新业务品牌“核芯动力”,先手布局智能计算产业

安谋科技(中国)有限公司(“安谋科技”)举行“创芯生,赋未来” 新业务品牌战略发布会,重磅发布“双轮驱动”战略以及新业务品牌“核芯动力”。新业务品牌的发布代表安谋科技引领智能计算产业发展趋势、推动计…

技术方案设计的方法论及案例分享

简介: 怎么去体现技术方案设计的深度是大家普遍关心的一个问题,这个问题不是个例问题,因此本文主要分享下作者个人的一些观点和看法。 怎么去体现技术方案设计的深度是大家普遍关心的一个问题,这个问题不是个例问题,因…

hp服务器硬盘ultra320,惠普/hp 300GB 1.5万转 3.5寸 SAS服务器硬盘 P/N:431944-B21

IBM 90P1307 90P1311 26K5260 71P7485 300G 10K U320 SCSI 硬盘sun 四口千兆网卡 X444** 501-6738SUN N240,N440硬盘XRA-SC1NB-146G15K/540-6607SUN网卡 X4447A-Z 501-7606 PCI-esun v480 电源 300-1486 3001486sun 501-0409 光纤卡Sun 硬盘 XRB-SS2CF-146G10K 540-7868 146GB …

qtextedit 默认文案_QTextEdit的paste

背景QTextEdit中粘贴一大段文字时,EasyDraft中粘贴进去的文字们的格式就乱了,处于无格式。还有在EasyDraft中选中一些文字进行拖放动作时,格式也会混乱。解决这两种都牵涉到QTextEdit粘贴行为,我们可以截获剪切板(clipboard)的内容…

第四范式:现代存储架构下的系统优化实践

8月21日,白玉兰开源联合示说网主办的“开源大数据技术线上meetup”特邀约大数据领域的前沿技术专家,就大数据存储的关键技术、挑战和当前应用展开交流讨论,阵容强大、内容全面。第四范式体系架构科学家,高性能计算Team leader卢冕…

穿越疫情,阿里云3000万补贴助力中小企业寒冬突围

简介: 2021年,活下去,是所有中小企业的一致心愿。冬将尽,春将来。我们也都在迫切等待着百花齐放的春天到来,阿里云愿和广大中小企业一起守望相助,共待山河无恙,春暖花开! 简介&#…

KubeVela:标准化的云原生平台构建引擎

简介: 本文由“GO 开源说”第三期 KubeVela 直播内容修改整理而成,视频内容较长,本文内容有所删减和重构。 KubeVela 的背景 KubeVela 是一个基于 Go 语言开发的云原生平台级开源项目,这个项目是去年 11 月中旬正式发布的。虽然发…

axis2 默认端口_基于 AXIS2/C 的 C 语言库实现对提供 REST API 的系统进行数据访问...

基于 AXIS2/C 的 C 语言库实现对提供 REST API 的系统进行数据访问宋 东平 和 赵 健2013 年 3 月 07 日发布AXIS2/C 简介和 REST 及 REST API 相关内容的简介AXIS2/C 简介Axis2/c 是基于 C 语言实现的 Web Service 引擎,基于 Axis2 架构,用于提供 Web 服…

漫画:什么是自动驾驶?

作者:小灰来源:程序员小灰什么是自动驾驶自动驾驶,也被称为无人驾驶,顾名思义,是指交通工具在没有人类操作的情况下,也能够完成环境的感知与导航,顺利到达目的地。从传统的手动驾驶到智能的自动…