您好!
欢迎来到京东云开发者社区
登录
首页
博文
课程
大赛
工具
用户中心
开源
首页
博文
课程
大赛
工具
开源
更多
用户中心
开发者社区
>
博文
>
Taro 鸿蒙技术内幕系列(四):JDImage 自研鸿蒙图片库
分享
打开微信扫码分享
点击前往QQ分享
点击前往微博分享
点击复制链接
Taro 鸿蒙技术内幕系列(四):JDImage 自研鸿蒙图片库
29****
2024-11-27
IP归属:北京
100浏览
> 作者:Taro技术组-何骁、Taro技术组-向俊成 ![](https://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2024-09-26-21-35NaN6T9eOyiqx9Z6.png) > 基于 Taro 打造的京东鸿蒙 APP 已跟随鸿蒙 Next 系统公测,本系列文章将深入解析 Taro 如何实现使用 React 开发高性能鸿蒙应用的技术内幕 # 背景 2024年初,京东正式启动了鸿蒙 APP 的开发工作。由于电商 APP 大量依赖图片来展示商品信息,对图片库的性能和加载体验要求极高,因此图片库被作为核心基础能力提前纳入京东鸿蒙首期基础建设计划。本文将详细介绍京东自研鸿蒙图片库的开发过程及其技术原理。 # 技术实现 ## 前期调研 经过前期的调研,我们发现`HarmonyOS`平台的网络图片加载主要依赖以下两种实现方式: ### 系统 - Image组件 仅仅提供基础的图片组件用于图片加载,但功能、图片格式支持和扩展性都较弱,无法实现更丰富的图片库能力。存在的一些问题: - 性能一般,尤其在同时加载多个图片时较慢 - 不支持 AVIF 图片格式并且无法扩展 - 无法搭建完善的质量监控体系 - 无法控制和扩展图片下载、解码、缓存流程,无法加入更多的性能优化手段和扩展定制 ### 第三方库 - ImageKnife 社区参考Android图片库`Glide`的`HarmonyOS`版本实现,使用`ArkTS`开发。虽然能力比系统`Image`组件完善,但在性能、稳定性和扩展性都无法满足诉求。存在的一些问题: - 性能一般 - 代码质量一般,存在一些 bug 和 Crash - 整体架构、扩展性设计不够,无法加入更多的性能优化手段和扩展定制 由于系统`Image`组件和`ImageKnife`开源库无法满足诉求,我们决定自主研发鸿蒙图片库。此外,随着`HarmonyOS`系统的引入,客户端在原有的`iOS`和`Android`基础设施上新增了一个平台,增加了维护成本。现有iOS/Android图片库也存在双端部分能力不一致的情况。集团内部期望未来的客户端基础设施能够支持跨端复用,以提高开发效率和一致性。 因此,团队选择基于`C++`为核心进行图片库开发,这种实现方式有以下优势: - 跨端复用:将更多的公共模块下沉到`C++`层以实现跨端复用,未来图片库可以扩展到`iOS`和`Android`平台。 - 适配 Taro:`Taro Harmony`框架基于鸿蒙`CAPI`进行开发,需要依赖`CAPI`的图片组件,可以避免`ArkTS`和`C++`之间频繁通信带来的性能损耗。 - 高性能:`C++`在运行时性能上优于`ArkTS`。 ## JDImage 能力 ![](https://img14.360buyimg.com/img/s1500x0_jfs/t1/211373/11/47107/74028/6735b559F4b6199c8/7b893857d765533c.png) ## 架构设计 由于图片库使用`C++`进行跨端开发,面临不同平台之间的兼容性挑战,部分功能需要依赖于端侧的特定实现。为了应对这些复杂性,需要提供了一定的抽象能力,使得在支持不同平台时能够灵活调整和替换模块具体实现。在设计过程中也参考了`iOS`/`Android`业界成熟的开源库,如`SDWebImage`、`Glide`和`Fresco`。 我们选择采用`模块化`和`架构分层`的思想来设计图片库的整体架构。`模块化`将图片库拆分为多个独立模块,不仅增强了系统的灵活性和可替换性,还使我们能够在不同的客户端环境和图片加载场景下进行灵活调整和扩展。`架构分层`将图片库划分为`Core`层和`客户端`层,`Core`层使用`C++`进行开发支持跨端复用,`客户端`层用于特定模块的平台差异化实现。这种设计方法有效地解决了跨端开发的复杂性问题,提高了系统的可维护性和稳定性。 ![图片库架构图](https://img12.360buyimg.com/img/s1500x0_jfs/t1/156196/18/48708/97179/6716635eF6ae28be0/f1ea426d1b369f28.png) ## 核心模块介绍 图片库主要分为`图片缓存`、`解码器`、`图片源拉取`、`性能监控`、`图片组件`这几个核心功能模块,模块之间不直接依赖可以被单独调用执行。 ### 图片缓存 - 内存缓存:用于保存已解码后的位图对象,避免每次图片加载都要进行图片解码,从而提高加载性能。我们采用`LRU`算法实现来高效利用内存,同时提供了最大内存缓存大小和设备内存紧张时回收一部分图片缓存的策略,以动态调整内存消耗。 - 磁盘缓存:用于保存下载后的网络图片在APP沙盒中,降低网络消耗并提高加载性能。提供了基础的图片读取、保存、删除、缓存大小读取等能力,同时支持多线程并行执行,实现图片磁盘缓存的高性能读写能力。 ### 图片数据源拉取 图片数据源拉取模块负责图片数据源读取能力。我们在`HarmonyOS`平台上提供了多个数据源实现,处理不同格式的图片数据源拉取任务: - HTTP:提供`HTTP`链接的网络图片下载能力。底层使用`Cornet`进行实现,实现高性能的多请求并行网络下载能力,同时方便未来实现跨端复用。 - Base64:提供`Base64`格式的图片格式读取能力。 ### 解码器 图片解码器模块负责将编码后的图片格式解码为操作系统的图片格式用于显示。我们在`HarmonyOS`平台上提供了多个解码器实现处理不同格式的图片解码任务,可以支持多线程并行执行提高解码性能。 - 系统解码器:利用`HarmonyOS`系统提供的图片解码器可以支持`PNG`、`JPG`、`GIF`、`WebP`、`SVG`等常用图片的高性能硬件解码能力。 - AVIF 解码器:由于京东APP大量使用`AVIF`图片格式,通过集成`libavif`库支持`AVIF`图片的解码能力。 ### 性能监控 - 加载性能监控:统计图片加载过程的各阶段耗时数据、缓存命中率、图片格式、资源消耗等信息,用来搭建图片加载性能数据平台和性能优化参考指标。 - 异常监控:捕获图片加载过程中的各种错误异常,用来搭建图片加载线上异常告警和根据场景进行异常重试。 ### 图片组件 图片组件基于系统`Image`组件进行封装,通过`src`属性传入解码后的`PixelMap`进行渲染。同时提供了一些额外的加载属性用于提升加载性能,例如添加`lazy`属性支持图片懒加载、`sourceSize`属性指定图片显示尺寸、` priority`属性设置加载优先级。 ## 性能优化 ### 图片加载流水线 ![图片加载流水线](https://img11.360buyimg.com/img/s1500x0_jfs/t1/164538/21/52510/82513/6735a1cbF89064750/e6349d83c4379355.png) 图片加载流水线借鉴了`Fresco`的流水线设计。采用流水线方式可以灵活调整流水线的执行流程,可以通过搭配不同的流水线子任务以满足不同类型的图片加载任务和不同客户端的差异化诉求。同时也添加了很多优化策略提升优化图片加载流水线的执行性能。`图片加载流水线`主要包含以下这些能力: - 调度执行顺序:管理图片加载的流水线子任务执行顺序,确保各个步骤按照预期的顺序进行执行。 - 调用功能模块:灵活调用不同的功能模块,如解码、缓存、网络请求等,根据具体需求动态调整,以适应不同的图片加载任务。 - 线程调度:对流水线子任务进行执行线程调度,确保非主线程任务在子线程中并行执行,主线程任务在主线程中执行。使用`HarmonyOS`提供的`FFRT`框架进行高性能线程调度。 - 重复任务聚合:识别重复的加载任务,避免非必要的重复请求,提高加载性能。 - 加载监控:统计加载过程性能数据和错误异常。同时加载数据也可以用于回溯分析异常问题。 - 取消/重试机制:实现图片加载的取消和重试逻辑。提前取消可以降低非必要的图片加载请求,重试机制可以尽可能降低线上显示异常。 ### 面向京东图片服务器设计 京东`图片服务器`提供了多种处理功能,例如图片`格式转换`、`图片降质`、`图片缩放`、`图片圆角`、`灰度图`等。这些功能通过在图片`URL`中添加特定图片处理参数实现,图片服务器会根据参数设置提前将图片处理完成并保存到`CDN`服务器。 我们可以通过在流水线预处理阶段,针对京东域名图片自动追加特定的图片处理参数降低网络流量传输消耗,例如根据视图实际显示大小添加缩放参数,添加降质参数,使用`.avif`格式图片降低网络传输大小。同时在磁盘缓存模块实现中,我们也通过实现优化策略让部分相同的图片可以进行磁盘缓存复用避免重复下载。 ![URL预处理](https://img14.360buyimg.com/img/s1500x0_jfs/t1/195443/1/49323/41899/67175036F3cad4599/0966c4efebe69ce4.png) ## 质量保障 作为一个新上线的基础组件,保证业务稳定性至关重要。为了快速发现并解决问题,图片库中实现了线上监控和异常恢复机制。 ### 线上监控 #### 异常监控 如前文所述,图片加载流水线涉及多个子任务,加载异常可能出现在任何一个环节。为了精准定位问题,图片库为每个子任务定制了不同的异常对象,每个异常对象包含独特的错误码,并会根据严重程度将其分为异常和警告两个级别。当加载流程结束时会根据上报策略进行异常上报。 #### 性能监控 除了加载成功率,加载速度也是图片库的核心指标,为了能正确还原加载流程,图片库按照配置策略记录每个子任务开始和结束时间,一方面用于统计各阶段的加载耗时,另一方面还作为异常定位时的重要辅助信息。 ### 异常恢复 除了从监控发现问题,为了将异常影响降至最低,图片库也实现了流水线失败重试、组件异常降级及线上配置降级三种异常恢复机制。 #### 流水线失败重试 在图片库任务预处理阶段,会基于配置策略对图片链接进行处理,如统一图片域名,图片格式转换等等。由于图片链接拼接规则复杂,无法保证所有链接进行转化处理后仍能正常加载,因此图片库流水线中增加了重试机制,会根据错误类型使用不同的重试策略。 #### 组件异常降级 对于经过重试仍然失败的任务,图片库组件侧会尝试直接使用系统`Image`组件进行兜底渲染,以防止出现图片库特定格式兼容性的问题。 此外,因为图片库流水线加载完成不意味着图片一定能正常渲染,图片的最终渲染成功与否取决于最终图片是否能在图片组件完成渲染上屏。因此,针对流水线成功但组件渲染失败的情况,图片库也会尝试降级到系统`Image`组件加载原始链接。 如果降级后仍然失败,则会按照业务配置顺序加载异常兜底图。 #### 线上配置降级 由于线上环境复杂,可能会出现仅发生在特定用户、系统版本、APP版本的异常,图片库也基于移动配置SDK支持了针对特定用户、机型、版本强制降级的能力。 # 加载对比 ![加载对比图](https://storage.360buyimg.com/jxfe/ppms/c/202410/22/b377d9f5-e767-4c14-97a6-ee0ba489c649.gif) ## 未来规划 我们也梳理了未来可能尝试的一些图片库优化方向: - 网络优化:弱网优化、HTTPDNS 等策略优化图片网络下载性能。 - 性能优化:提高磁盘缓存/内存缓存复用率、使用堆内存池减少堆内存分配、优化 GIF 播放、低端机优化等。 - 适配京东图片服务器能力:利用服务器图片处理能力,如使用不同的缩放尺寸参数、清晰度、图片格式、图片域名等参数提高加载性能。 - 能力完善:提供更多图片加载参数、支持更多图片类型等能力满足不同业务的加载诉求。 - 更多平台支持:扩展到`iOS`、`Android`等更多平台。 - 提升图片效果:使用不同的插值方式、超分技术、HDR 等能力提高图片显示效果。 # 总结 京东自研的鸿蒙图片库通过模块化设计和流水线调度策略,成功解决了跨端开发的复杂性问题,同时提高了系统的可维护性和稳定性。通过实现多重异常容错机制,保证了业务的稳定性。该图片库不仅满足了京东APP在鸿蒙系统上的高性能图片加载需求,还为未来的跨平台开发奠定了基础。 目前,图片库已通过`Taro`集成到`京东`鸿蒙 APP 中上线使用,在图片加载体验和稳定性上有不错的表现。未来,我们将继续优化图片库的性能,扩展功能,并探索在更多平台上的应用可能。同时,我们也会持续关注业界最新的图片处理技术,不断改进我们的解决方案,为用户提供更好的图片加载体验。 ## 系列往期精选 [京东鸿蒙上线前瞻——使用 Taro 打造高性能原生应用](http://sd.jd.com/article/36725?shareId=30665&isHideShareButton=1) [Taro 鸿蒙技术内幕系列(一):如何将 React 代码跑在 ArkUI 上](http://sd.jd.com/article/37611?shareId=2474&isHideShareButton=1) [Taro 鸿蒙技术内幕系列(二):如何让 W3C 标准的 CSS跑在鸿蒙上](http://sd.jd.com/article/38281?shareId=2474&isHideShareButton=1) [Taro 鸿蒙技术内幕系列(三) - 多语言场景下的通用事件系统设计](http://sd.jd.com/article/39187?shareId=1927&isHideShareButton=1) ## 下期预告 ![下期预告](https://img13.360buyimg.com/img/s800x0_jfs/t1/121427/40/52661/58146/6735bde4F3f037868/f6ecc76a38499abf.png)
上一篇:Elasticearch索引mapping写入、查看、修改
下一篇:InheritableThreadLocal从入门到放弃
29****
文章数
7
阅读量
2029
作者其他文章
01
基于 prefetch 的 H5 离线包方案
前言对于电商APP来讲,使用H5技术开发的页面占比很高。由于H5加载速度非常依赖网络环境,所以为了提高用户体验,针对H5加载速度的优化非常重要。离线包是最常用的优化技术,通过提前下载H5渲染需要的HTML/JS/CSS资源,加载时直接使用本地缓存资源避免额外的网络请求提高加载速度。本文主要是介绍团队在离线包技术方案上的探索,以及基于prefetch的离线包实现方案如何减少维护成本和开发成本。现有方
01
京喜APP - 图片库优化
介绍京喜APP早期开发主要是快速原生化迭代替代原有H5,提高用户体验,在这期间也积累了不少性能问题。之后我们开始进行一些性能优化相关的工作,本文主要是介绍京喜图片库相关优化策略以及关于图片相关的一些关联知识。图片性能问题作为电商APP,图片在各个业务场景被大量使用。我们需要做到尽可能降低网络消耗/内存消耗/硬盘消耗,同时不降低图片质量,提高图片加载速度,给用户带来更好的使用体验。基于这些性能目标,
01
使用Swift提高代码质量
前言京喜APP最早在2019年引入了Swift,使用Swift完成了第一个订单模块的开发。之后一年多我们持续在团队/公司内部推广和普及Swift,目前Swift已经支撑了70%+以上的业务。通过使用Swift提高了团队内同学的开发效率,同时也带来了质量的提升,目前来自Swift的Crash的占比不到1%。在这过程中不断的学习/实践,团队内的Code Review,也对如何使用Swift来提高代码质
01
移动端APP组件化架构实践
theme: smartblue前言对于中大型移动端APP开发来讲,组件化是一种常用的项目架构方式。个人最近几年在工作项目中也一直使用组件化的方式来开发,在这过程中也积累了一些经验和思考。主要是来自在日常开发中使用组件化开发遇到的问题以及和其他开发同学的交流探讨。本文通过以下问题来介绍组件化这种开发架构的思想和常见的一些问题:为什么需要组件化组件化过程中会遇到的挑战和选择如何维护一个高质量的组件化
29****
文章数
7
阅读量
2029
作者其他文章
01
基于 prefetch 的 H5 离线包方案
01
京喜APP - 图片库优化
01
使用Swift提高代码质量
01
移动端APP组件化架构实践
添加企业微信
获取1V1专业服务
扫码关注
京东云开发者公众号