作为一款承载着「基于兴趣聚集同好人群」的社区型产品,相较于常规导购型产品来说,在业务复杂度、交互复杂度、性能体验稳定性要求上都要高出许多,像多角色区分、嵌套滚动、多形态 Feeds 无限加载、颜文字等特殊字符处理、页面直开、视频播控等场景都是导购场景很少遇到的。
本文将围绕着会玩圈子的前端设计、开发过程中遇到的典型问题进行介绍。
如上图为会玩圈子的设计大图,可以看到整体的业务逻辑相对较为复杂。并且由于应用中存在多种角色状态,不同角色的用户展示界面和操作逻辑也有差异点存在,前端同学进行开发上手的成本较高。
为了降低前端同学在开发过程中对于全局业务理解的成本,减少沟通中信息传递容易遗漏的问题。我们在设计之初首先进行了最小模块的拆分工作。以模块维度来分配相应的工作,将模块间存在数据共享和数据通信行为进行梳理拆解,以最优方式来分配数据状态维护的最小闭环,降低组件间耦合度。
在此处定义的模块不是前端日常开发中所讲的模块组件拆分,而是能够独立闭环自成体系的一个业务单元。这样在项目过程中除了部分组件间数据传递需要做预先约定外,前端同学仅仅只需要专注于自己所负责的交互场景即可。
圈子信息模块: 偏展示型模块。交互较少,根据业务数据展示相应的信息模块内容,需要根据用户当前的身份展示不同类型的模块组件,并且可以根据当前用户的身份来进行权限校验,在未符合时进行友好Tip提示的能力。
信息流模块:偏交互型模块。需要支持多个列表在Tab下嵌套滚动的能力,模块本身需要维护用户关注状态表、黑名单筛选表和视频播放列表,方便模块中的子组件进行数据共享。并且列表具备单排流和瀑布流两种布局模式,列表内元素存在商品、帖子内容两种类型卡片。支持评论、点赞查看原图、视频播放、触发浮层等多种交互能力。
浮层模块:通用型模块。允许开发者根据业务需求注册相应的模块组件,并且允许配置相应的展示位置、动画效果和图层index
useReducer + useContext
来进行处理,并将获取对应实例context
的方法Hooks化以方便开发同学使用,简单demo代码如下所示:卡片的初始数据通过props形式传入,单一帖子的交互性数据都保留在帖子元素组件一层来维护。
列表容器中除了基础状态信息外,仅仅只做视频播放的控制,不额外触发容器级的重渲染。
展示模块过多的情况下,如果在多个Tab下进行数据加载切换过后整个页面的交互会出现明显的卡顿感:比如点击弹出浮层会有明显的等待时延,翻页切换Tab时对应的下标移动会不同步。
浮层容器中注册的部分组件由于依赖共享变量,在共享变量变化时也会触发不必要的重渲染:效果为会跟着闪动一下。
网络状况不稳定的情况,页面展示不够友好的;从用户点击路由跳转到首屏页面展示的等待时间过于明显,与我们要求的页面直开效果相差甚远。
CircleHeader
组件所依赖的值,没必要底下CircleSlider
组件及其中的列表组件都需要跟着做调整渲染,这个代价是我们无法接受的。Context.Provider
其实组件也保持着Rax
组件的一致规则:props.children
作为传入属性,它如果保持不变就不会触发值diff,进而也就不会出现重渲染的问题了。Provider
不会由于props.children
的变化产生重渲染呢?通过社区提供的资料,我们发现每次执行的都是JSX转义后的createElement(xxx)
。由于每次执行产生的子组件都不一致,所以会导致不必要的重渲染。Context.Provider
单独拆分成为一个专门用于传状态值的高阶组件,将子组件以props.children
的形式传入:目前圈子主页的首屏平均可交互时长为1000ms左右,用户从点击入口到进入主页内浏览基本无需等待。但我们相信通过根据设备类型来做区分,在进入页面之初降级部分中低端机非必须能力能够为这一类用户提供更快的交互体验。
为了突出社区内不同圈子个性点,相信自定义的装修能力以及定制插件能力在之后是必不可少的。要如何能够基于现有的架构体系快速接入这些业务诉求,也是我们在现有能力上需要预先思考到的
根据业务诉求的变化,如何将从业务模块中产生的组件尽量做到更通用化并且支持多种容器也是需要解决的。
PICK ME
闲鱼技术团队通过创新追寻更多价值,不断驱动业务变革。
从闲置生意的老本行,到打造“无忧购”“会玩社区““新线下”,
从出版书籍、峰会发声,到开源专利、海外传播,
闲不住,上闲鱼——技术团队对极致的探索与深耕是我们的底气。
立即加入
1、招客户端/服务端/前端/架构/质量工程师
2、发简历给guicai.gxy@alibaba-inc.com
3、您还可以在头条、知乎、掘金、facebook、twitter找到我们