京东五星门店小程序性能优化实践
一、背景介绍
1.1 业务介绍
五星门店小程序主要服务于五星线下门店交易场景,目前已有 79 个城市 267 家门店(包括超级体验店、城旗店、京东 Mall 等)在使用,用户可以通过小程序便捷地查看和购买门店的商品。五星门店小程序已实现基于 Taro 跨端解决方案的一码多端能力,一套代码可以在京东 App 以及微信小程序中运行,大幅提升了研发效率,可以更快更好地支持门店业务快速发展。
1.2 现状分析
随着业务高速发展,目前线下门店的数量仍然在不断扩张,未来会有更多的用户使用五星门店小程序。作为线下门店核心交易工具,为了能够更好得服务更多的门店和用户,快速了解一线的使用情况,给用户更好的体验,我们建立了以下机制:
(1)日常沟通群与门店导购和运营人员保持密切联系,及时获取用户反馈,为产研团队提供有价值的一线参考。
(2)我们还通过团队内部的日常体验走查机制,主动发现问题,并由产研侧推动优化小程序的体验性能。
无论是一线反馈还是内部走查,都为我们提供最真实、最有价值的问题参考,让我们能够从真实用户角度出发去优化小程序。
二、具体行动
2.1 结果概览
本次小程序优化主要集中在以下三方面:js 报错率、页面渲染速度和包体积,整体优化结果如下所示:
(1)针对 js 报错率,优化前平均一周 js 错误数 1374 次,错误人数 694 人,优化后平均一周 js 错误数 260 次,错误人数 129 人,优化前后平均一周 js 错误人数和错误次数降低约 81%。
(2)针对小程序黄金流程的页面渲染优化,不同机型在渲染速度上均有不同程度的提升,我们以 iPhone14Pro、iphone14、onePlus9、华为 Nova8 以及红米手机五种测试机型作为参考:
▪商详页优化前后渲染速度平均提升 28%;
▪购物车优化前后渲染速度平均提升 20%;
▪结算页优化前后渲染速度平均提升 25.4%;
(3)针对包体积优化,抽离主包中冗余的代码和页面,并且因商详页面访问人数和访问次数排在 Top1,将商详页面从子包中移到主包,提升商详页面的访问速度,从而使得小程序日均切换耗时对比优化前下降 17.95%,总包由 5.92MB 降低到 5.32MB,缩小将近 10.14%,主包由 1.53MB 缩小 1.26MB,缩小将近 17.65%。
2.2 实践分析
2.2.1 日常体验走查机制
▪制定走查原则和评估标准:首先,依据行业大厂内优秀实践和《尼尔森十大可用性原则》,结合五星门店的业务场景进行提炼和细化标准,根据页面影响范围和与核心指标的相关性,划分核心页面和非核心页面制定具体的检查项,形成针对性的走查。以无阻碍浏览、可顺畅操作为目标,将问题严重程度分为 4 个评估标准:致命、严重、一般、轻微,研发组负责收集、定义问题,并给出严重程度评估,然后与负责的主产品一起协定解决优先级,最终由项目组决定最终负责人及解决排期。
▪确定走查的时间和频率: 在产品开发的不同阶段进行走查,如设计初稿完成后、开发中期和最终阶段,同时确认走查业务场景,整理好走查的物料。
▪制定走查的参与人员:可包括前端开发工程师、设计师、产品经理等相关角色,以确保多角度考虑产品的使用。
▪记录并整理问题: 通过实际操作产品,检查各个方面的问题,以文档、截图或录屏等方式记录问题,同时对问题进行严重程度分析和优先级整理,确保准确描述和分类。
▪提出改进建议: 针对每个问题,研发定义问题严重程度,与产品协定解决优先级,提出具体的修复方案、优化建议等。
▪问题追踪和验证: 将问题和改进建议记录在项目管理工具中,跟踪问题解决进度,并进行验证,确保解决问题。
通过以上的原则、标准和流程,可以有效地进行产品体验走查,提升产品的用户体验质量。自 2023 年以来,我们已完成:小程序整体流程场景、日常扫码进场体验场景、黄金流程体验场景、武汉扫码场景、首页升级体验场景、商详升级体验场景等 6 场体验走查,提出的数十个优化建议已经在优化迭代中落地。
2.2.2 日常优化迭代机制
针对大促备战紧张、日常需求复杂、量大、迭代快速的情况,我们与产品、测试等项目组成员商议后共同制定了日常优化迭代机制。自 2022 年以来,我们已完成 48 个版本体验优化。我们是如何与需求并行推动落地的呢?
(1)优化项来源收集:
1)前期主要通过用户动线梳理和业务说明,前端小组成员进行周会或日常走查并记录表格
2)后续扩大范围至项目组全体成员内部体验走查
3)大促期间与客服、用户、导购建立的线上和线下等体验沟通提升群组。
(2)确定走查范围: 优先优化黄流页面,其次是其他访问人数较多、业务较重要的页面。
(3)确定走查方式: 以视觉浏览、交互操作维度,多场景体验业务逻辑,来捕获问题。
(4)统计走查内容: 根据错误严重程度排序,并组会同步产品、测试及其他相关人员,优先解决线上紧急重要优化项,其次进行日常版本迭代。
(5)严格按照日常项目流程开发和上线: 利用项目外时间与业务、产品、测试等相关人员针对走查修复内容达成一致,最终共同进行排期、开发、测试、checkList 和上线。
2.2.3 性能/质量优化
2.2.3.1 js 异常报错解决
(1)统计报错信息,减少数据干扰因素,确定样本范围、报错范围、报错优先级
▪数据整理筛选:筛选报错信息,排除干扰数据,确立样本与报错范围,划分优先级。
▪统计分析结果:12 月 11 日对 JS 数据进行梳理,发现报错随访问量和新需求增加。由于 12.1-12.11 期间数据稳定,我们进行了专项统计。
▪优化重点排序:按报错频率和页面重要性,优先处理启动页、首页、商详、购物车、结算页、订单页、分类搜索、门店预约及活动等关键页面。
▪错误分类及排序:错误主要分为:业务代码错误、插件错误、基础库错误等。优先解决业务代码错误,因为直接影响用户体验,可能导致程序中断、功能异常、数据丢失、兼容性问题。再处理插件和基础库错误,以提升用户体验。其次是插件错误和基础库错误较少,因为很难排查错误来源和信息,需要外部依赖方(京东小程序、微信小程序)官方解决和迭代
▪确定版本迭代优先级:优先优化线上版本,逐步扩展至体验版和开发版。
(2) 确定项目中 JS 报错的类型,进行迭代方式优化上线,并制定后续避免措施
▪报错类型:聚焦 TypeError、ReferenceError 和 AsyncError,主要涉及变量操作和使用、函数的声明和定义、异步错误处理和捕获。
▪原因分析:业务迭代快,日常关注不足。
▪优化行动:12 月 14 日优化后,报错率降至千分之五。
▪后续策略:持续迭代优化,加强内部审核、互相的 checkList,预防同类问题。
2.2.3.2 缩包实践
(1)使用打包工具(webpackChain)来分析包体积的构成。
(2)优化大模块 common(公共逻辑)及 vendors(第三方库公共依赖)的步骤如下:
1)删除历史遗留无用模块。
2)整合和提炼组件及公共方法代码,删除重复代码。
3)按需引入第三方库,并在保证业务正常运转的前提下将第三方库替换为原生方法,若无法替代则使用体积最小版本。
4)静态资源优化:媒体资源较多的在本地存储或以 Base64 形式储存,本次调整为 CDN 引入。
(3)后续措施:
1)使用 EOS 平台检测代码重复率,及时整合和提炼代码。
2)独立引用第三方库,并使用最小体积版本。
3)优先统一使用 CDN 引入静态资源,尽量缩减存储在本地或使用 Base64 形式。
2.2.3.3 页面渲染速度优化
(1) 商详页面,经过优化后平均渲染速度提升约 28%,左侧图均为优化后,右侧图均为优化前。
iPhone14:
对于商详切出小程序再切入小程序的情况,在优化之前,商详会重新刷新接口,导致页面会出现短暂抖动。在优化之后,商详保持原有数据不重新刷新接口,使得页面能够保持稳定
One9Plus:
红米:
分析商详现状: 页面滑动卡顿、首次进入商详白屏时间长、每次进入商详(无论是首次进入还是由上一级页面返回)都会请求商详接口,导致即使页面有数据也会有 loading 出现,并且在弹窗弹出的情况下,由上一级页面返回商详时弹窗会闪现一下等。
根据现状,从以下几个方面进行优化:
1)整体布局
优化前:商详页面最外层是 ScrollView 标签,借助 ScrollY 属性的设置实现页面滚动。经调研发现 ScrollView 更适合局部滚动,如果采用 ScrollView 实现页面级滚动,滚动性能会比较差,页面上下快速频繁滚动会卡顿。
优化后:去掉最外层的 ScrollView 标签,给最外层的 View 标签设置 100%屏幕高度,内层元素高度由内容撑开,利用内容超出一屏高度产生的系统默认滚动特性实现页面滚动。滚动到某一指定位置由 scrollIntoView 更改为 Taro.pageScrollTo 实现(比如商详的返回顶部功能,切换顶部 tab 滚动到相应区域)。
2)组件优化
优化前:子组件直接在父组件中引用,并且组件中没有使用 memo,useMemo,useCallBack 等能提升性能的钩子函数。
优化后:合理使用 React.memo, 商详页面比较复杂,子组件较多,父组件的渲染会导致子组件跟着一起渲染,React.memo 可以做浅层比较,防止出现不必要的重复渲染。子组件使用 CustomWrapper 标签包裹,它可以将包裹的组件与页面隔离,子组件渲染时不会更新整个页面,由 page.setData 变为 component.setData。
3)图片预加载
优化前:商详 banner 图片是进入页面之后从服务端请求回来的,有一定的延迟。
优化后:在小程序中,从调用 Taro.navigateTo 等路由跳转 API 到小程序页面触发 onLoad,中间会有一定延时(约 300ms 左右),此时利用 Taro.preload 在跳转前做一些预处理的逻辑,比如提前加载 banner 图片等,无需等待接口返回数据,提升商详页的 banner 渲染速度。
4)数据请求时机优化
优化前: 商详的数据请求逻辑在 useDidShow 中执行,每次进入商详(无论是首次进入还是上一级页面返回)都会调用接口,导致出现频繁的 loading 效果,并且弹窗弹出的时候会闪一下。
优化后:商详数据请求逻辑放在 useEffect 中,只有新进入商详会执行,由上一级页面返回商详时无需调用接口,减少了频繁的 loading,大大提升了用户进入商详页的体验。
(2) 购物车页面,优化前后渲染速度平均提升约 20%,左侧图均为优化后,右侧图均为优化前。
iPhone14:
One9Plus:
红米:
购物车现状分析显示,购物车查车接口一次性返回全量数据,导致页面在商品数量超过 30 条时出现渲染慢和长时间白屏的问题,同时在操作购物车时也会出现卡顿等现象。为了解决上述问题,购物车优化主要集中在以下两点:
1)数据切割处理
优化前:全量数据直接传递给组件进行渲染,导致数据量大时渲染速度极慢。
优化后:原始数据切割成两部分,首先渲染前四条数据(大概能占满首屏),剩余数据利用 setTimeout 的特性进行异步处理,不会阻塞前四条数据的渲染,从而提升首屏的渲染速度。
2)调整父子组件之间数据传递的时机
优化前:父组件拿到原始数据之后直接传入子组件,在子组件内按照需要的数据结构进行处理。
优化后:根据父组件优先子组件渲染的原则,将原始数据处理的部分移至父组件,将处理后的数据传递给子组件。自此,子组件在接收到数据后可以直接进行渲染,节省了原本用于子组件数据处理的时间,从而在一定程度上提升页面的渲染速度。
(3)结算页面,优化后渲染速度平均提升约 25.4%。左侧图均为优化后,右侧图均为优化前。
iPhone14Pro:
One9Plus:
华为 Nova8:
分析结算现状: 进入页面时,由于接口之间存在依赖关系,需要请求多个接口,导致页面渲染时间较长,并且在渲染完成后会出现页面抖动现象。根据现状,结算页的优化主要包括以下三点:
1)优化网络请求:
优化前:存在多个接口依赖,导致多次请求。
优化后:整合服务层接口,将多个接口合并为一个主接口,减少网络通信次数。
2)优化数据结构,减少 setData 使用频率:
优化前:接口过于分散,相互依赖,导致频繁的 setData 调用,降低性能。
优化后:接口整合后数据体量较大,采用递归方式将主体数据拆解,减少遍历过程,减少 setData 的使用频率,避免 setData 数据量变大,从而缩短页面的渲染耗时。
3)组件更新优化:
优化前:子组件直接在父组件中引用,且未使用 CustomWrapper。
优化后:合理使用 CustomWrapper,通过将子组件使用 CustomWrapper 标签包裹,实现子组件渲染时局部更新,由 page.setData 变为 component.setData,减少全局更新,提高性能。
三、未来展望
以上是我们近一年来对五星门店小程序性能体验优化所做的一个阶段性成果的总结,整体性能得到显著提升。对于研发人员来说,提升用户体验是一项需要长期坚持的工作,作为技术同学,我们需要具备工匠精神,在接下来的一年中,我们将继续在小程序性能体验优化方面努力,给用户近乎原生应用的操做体验,主要会从以下几个方面入手:
(1)用户体验
▪持续跟进门店导购的反馈,结合现有的走查和迭代机制,不断优化小程序体验问题。
▪继续执行日常体验走查和日常优化迭代机制,主动发现并解决问题。
(2)性能提升
▪项目框架升级:第一波框架升级预计在 2024 年 3 月份完成,完成升级之后能够进一步提升编译速度,提升开发效率。
▪继续缩小包体积:随着后续需求的增加,包体积势必会增大,为满足小程序限制的包体积大小,我们需要进一步缩小优化包体积。
(3)质量保障
▪维持低 js 报错率:在日常开发中注重代码的可读性以及健壮性,注意临界点的逻辑判断等,关注监控平台的信息反馈并及时响应,将 js 异常扼杀在摇篮里。
▪打开率:持续提升小程序打开率,降低对用户和业务的影响。
作者:前端研发 李佳
来源:京东零售技术 转载请注明来源
版权声明: 本文为 InfoQ 作者【京东零售技术】的原创文章。
原文链接:【http://xie.infoq.cn/article/f8e5c7bab63571de87d59e18d】。文章转载请联系作者。
评论