作者:京东零售 何骁
基于 Taro 打造的京东鸿蒙 APP 已跟随鸿蒙 Next 系统公测,本系列文章将深入解析 Taro 如何实现使用 React 开发高性能鸿蒙应用的技术内幕
2024年初,京东正式启动了鸿蒙 APP 的开发工作。由于电商 APP 大量依赖图片来展示商品信息,对图片库的性能和加载体验要求极高,因此图片库被作为核心基础能力提前纳入京东鸿蒙首期基础建设计划。本文将详细介绍京东自研鸿蒙图片库的开发过程及其技术原理。
经过前期的调研,我们发现
HarmonyOS平台的网络图片加载主要依赖以下两种实现方式:
仅仅提供基础的图片组件用于图片加载,但功能、图片格式支持和扩展性都较弱,无法实现更丰富的图片库能力。存在的一些问题:
社区参考Android图片库
Glide的
HarmonyOS版本实现,使用
ArkTS开发。虽然能力比系统
Image组件完善,但在性能、稳定性和扩展性都无法满足诉求。存在的一些问题:
由于系统
Image组件和
ImageKnife开源库无法满足诉求,我们决定自主研发鸿蒙图片库。此外,随着
HarmonyOS系统的引入,客户端在原有的
iOS和
Android基础设施上新增了一个平台,增加了维护成本。现有iOS/Android图片库也存在双端部分能力不一致的情况。集团内部期望未来的客户端基础设施能够支持跨端复用,以提高开发效率和一致性。
因此,团队选择基于
C++为核心进行图片库开发,这种实现方式有以下优势:
C++层以实现跨端复用,未来图片库可以扩展到
iOS和
Android平台。Taro Harmony框架基于鸿蒙
CAPI进行开发,需要依赖
CAPI的图片组件,可以避免
ArkTS和
C++之间频繁通信带来的性能损耗。C++在运行时性能上优于
ArkTS。
由于图片库使用
C++进行跨端开发,面临不同平台之间的兼容性挑战,部分功能需要依赖于端侧的特定实现。为了应对这些复杂性,需要提供了一定的抽象能力,使得在支持不同平台时能够灵活调整和替换模块具体实现。在设计过程中也参考了
iOS/
Android业界成熟的开源库,如
SDWebImage、
Glide和
Fresco。
我们选择采用
模块化和
架构分层的思想来设计图片库的整体架构。
模块化将图片库拆分为多个独立模块,不仅增强了系统的灵活性和可替换性,还使我们能够在不同的客户端环境和图片加载场景下进行灵活调整和扩展。
架构分层将图片库划分为
Core层和
客户端层,
Core层使用
C++进行开发支持跨端复用,
客户端层用于特定模块的平台差异化实现。这种设计方法有效地解决了跨端开发的复杂性问题,提高了系统的可维护性和稳定性。
图片库主要分为
图片缓存、
解码器、
图片源拉取、
性能监控、
图片组件这几个核心功能模块,模块之间不直接依赖可以被单独调用执行。
LRU算法实现来高效利用内存,同时提供了最大内存缓存大小和设备内存紧张时回收一部分图片缓存的策略,以动态调整内存消耗。图片数据源拉取模块负责图片数据源读取能力。我们在
HarmonyOS平台上提供了多个数据源实现,处理不同格式的图片数据源拉取任务:
HTTP链接的网络图片下载能力。底层使用
Cornet进行实现,实现高性能的多请求并行网络下载能力,同时方便未来实现跨端复用。Base64格式的图片格式读取能力。图片解码器模块负责将编码后的图片格式解码为操作系统的图片格式用于显示。我们在
HarmonyOS平台上提供了多个解码器实现处理不同格式的图片解码任务,可以支持多线程并行执行提高解码性能。
HarmonyOS系统提供的图片解码器可以支持
PNG、
JPG、
GIF、
WebP、
SVG等常用图片的高性能硬件解码能力。AVIF图片格式,通过集成
libavif库支持
AVIF图片的解码能力。图片组件基于系统
Image组件进行封装,通过
src属性传入解码后的
PixelMap进行渲染。同时提供了一些额外的加载属性用于提升加载性能,例如添加
lazy属性支持图片懒加载、
sourceSize属性指定图片显示尺寸、
priority属性设置加载优先级。
图片加载流水线借鉴了
Fresco的流水线设计。采用流水线方式可以灵活调整流水线的执行流程,可以通过搭配不同的流水线子任务以满足不同类型的图片加载任务和不同客户端的差异化诉求。同时也添加了很多优化策略提升优化图片加载流水线的执行性能。
图片加载流水线主要包含以下这些能力:
HarmonyOS提供的
FFRT框架进行高性能线程调度。京东
图片服务器提供了多种处理功能,例如图片
格式转换、
图片降质、
图片缩放、
图片圆角、
灰度图等。这些功能通过在图片
URL中添加特定图片处理参数实现,图片服务器会根据参数设置提前将图片处理完成并保存到
CDN服务器。
我们可以通过在流水线预处理阶段,针对京东域名图片自动追加特定的图片处理参数降低网络流量传输消耗,例如根据视图实际显示大小添加缩放参数,添加降质参数,使用
.avif格式图片降低网络传输大小。同时在磁盘缓存模块实现中,我们也通过实现优化策略让部分相同的图片可以进行磁盘缓存复用避免重复下载。
作为一个新上线的基础组件,保证业务稳定性至关重要。为了快速发现并解决问题,图片库中实现了线上监控和异常恢复机制。
如前文所述,图片加载流水线涉及多个子任务,加载异常可能出现在任何一个环节。为了精准定位问题,图片库为每个子任务定制了不同的异常对象,每个异常对象包含独特的错误码,并会根据严重程度将其分为异常和警告两个级别。当加载流程结束时会根据上报策略进行异常上报。
除了加载成功率,加载速度也是图片库的核心指标,为了能正确还原加载流程,图片库按照配置策略记录每个子任务开始和结束时间,一方面用于统计各阶段的加载耗时,另一方面还作为异常定位时的重要辅助信息。
除了从监控发现问题,为了将异常影响降至最低,图片库也实现了流水线失败重试、组件异常降级及线上配置降级三种异常恢复机制。
在图片库任务预处理阶段,会基于配置策略对图片链接进行处理,如统一图片域名,图片格式转换等等。由于图片链接拼接规则复杂,无法保证所有链接进行转化处理后仍能正常加载,因此图片库流水线中增加了重试机制,会根据错误类型使用不同的重试策略。
对于经过重试仍然失败的任务,图片库组件侧会尝试直接使用系统
Image组件进行兜底渲染,以防止出现图片库特定格式兼容性的问题。
此外,因为图片库流水线加载完成不意味着图片一定能正常渲染,图片的最终渲染成功与否取决于最终图片是否能在图片组件完成渲染上屏。因此,针对流水线成功但组件渲染失败的情况,图片库也会尝试降级到系统
Image组件加载原始链接。
如果降级后仍然失败,则会按照业务配置顺序加载异常兜底图。
由于线上环境复杂,可能会出现仅发生在特定用户、系统版本、APP版本的异常,图片库也基于移动配置SDK支持了针对特定用户、机型、版本强制降级的能力。
我们也梳理了未来可能尝试的一些图片库优化方向:
iOS、
Android等更多平台。京东自研的鸿蒙图片库通过模块化设计和流水线调度策略,成功解决了跨端开发的复杂性问题,同时提高了系统的可维护性和稳定性。通过实现多重异常容错机制,保证了业务的稳定性。该图片库不仅满足了京东APP在鸿蒙系统上的高性能图片加载需求,还为未来的跨平台开发奠定了基础。
目前,图片库已通过
Taro集成到
京东鸿蒙 APP 中上线使用,在图片加载体验和稳定性上有不错的表现。未来,我们将继续优化图片库的性能,扩展功能,并探索在更多平台上的应用可能。同时,我们也会持续关注业界最新的图片处理技术,不断改进我们的解决方案,为用户提供更好的图片加载体验
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70037994/viewspace-3053658/ ,如需转载,请注明出处,否则将追究法律责任。