前言
总所周知,主流应用都有瀑布流下拉图片的页面,为了使页面更丝滑,通常需要对图片进行缓存。这种通用需求,对标竞品往往使用三方库来实现,比如安卓有Glide 、Picasso、ImageLoader。IOS有SDWebImage,Kingfisher,PINRemoteImage。当前鸿蒙应用开发,主要推荐使用@ohos/imageknife.
然而@ohos/imageknife 2.x版本主要网络下载图片和解析的逻辑虽然是使用异步promise的方式,原则上不阻塞主线程。但是,当在页面快速下滑时,由于有很多的图片同时请求和加载,还是会造成主线程整体执行时间过长,导致页面出现丢帧卡顿。
为了解决这个问题,我逐步开始分析@ohos/imageknife和glide的源码,决定对@ohos/imageknife做一次彻底的重构,也就是当前的3.x版本。根据目前从仿抖音应用测试快速下拉图片的页面测试数据来看,丢帧率已经从原来6%+,下降几乎为0%。于是乎,总结了下从3.x–>2.x主要的优化手段,相信这些方式不仅对三方库法,对应用开发也会有很大的借鉴意义。
1.把主要的逻辑移植到子线程里。
自API11以后,鸿蒙应用提供了TaskPool的能力(https://docs.openharmony.cn/page … ool-introduction.md),因此我把图片加载的主要逻辑:网络下载+文件缓存读写+图片解码都通过TaskPool放到了子线程里执行,也就是说每个图片的请求基本上都是在子线程里执行,主线程仅保留内存缓存读写和最终的显示,从而降低主线程的时间消耗,大大降低丢帧率。
近期,Pixelmap,Resource等类型也将支持Sendable,届时子线程返回的Pixelmap对象可以改成Sendable对象,即支持引用传递,这样将会进一步减少对象序列化的时间和内存消耗,相信对性能会有更进一步的提升。
2.减少耗时API的使用
这里主要是说在2.x版本,使用了自定义组件的OnAreaChange消息时间获取了组件的宽高,然而这个API被确认为是一个耗时API,且在页面快速下滑时的调用频率非常之高。当前,在API12版本,替换成了OS提供的性能更好的onSizeChange事件,这个事件仅在组件宽度发生变化时才被调用,也就是快速下滑过程中是不被触发的。单就这个API得替换,也对整体丢帧率有了很大的改善。
3.减少不必要的请求,优先加载当前页面的图片
因为在快速下滑的场景,以及一些打开又马上关闭页面的场景,由于OS网络接口的并发限制,往往导致有很多图片在排队请求,导致给人的感觉是当前页面的图片要等前面加载完后才能显示。针对这个问题,首先建议应用开发者使用lazyforeach+reuse的方式实现下拉列表,尽量复用当前组件。其次在3.x的实现过程中,默认控制了下发taskpool的请求数(默认8),超过默认请求数的请求在内存中先排队,超过并发数的请求会做一个简单排队,而不是一股脑子全扔到taskpool里。等到排到时会优先判断当前组件是否已经被销毁了,如果被销毁了,则该请求直接放弃,不再下发taskpool请求了。这个简单实现,可以减少不少子线程的不必要请求,能大大提升图片的加载效率。
4.使用系统Image组件,替换2.x的Canvas组件。
没办法,目前大家都公认Image组件性能强于Canvas组件,且Image自带ObjectFit属性直接支持了各种常用的图片缩放模式。当然,也有应用提出一些缩放模式Image无法支持。对此,我的建议是反馈给OS,优先让系统组件支持。其次,也可以自己封装一个自定义组件,由于Image加载完成会有回调Pixelmap和宽高的接口,可以仍然自己使用Canvas来计算和绘制。
5.优化了Iamgeknife核心调度逻辑。
主要体现在并发排队,同时下发占位图和主图,网络请求等逻辑上。减少了之前代码部分不合理之处。以下是3.x的主要实现逻辑
3.x版本除了性能的提升外,还有如下能力和2.x版本同时做了增强:
1.支持自定义网络下载
2.支持多种图片变换,如高亮,模糊等
3.支持接口预加载图片,判断图片是否有缓存,以及删除图片缓存
4.支持接口回调启动加载,完成加载或加载失败
5.支持设置缓存策略
6.heric格式图片支持
未来ImageKnife即将实现以下特性:
1.对动图的控制
2.支持对图片的降采样设置,从而减少内存缓存的占用
3.对Sendable的支持
4.支持自定义格式图片解码(当前只能修改源码)
诚然,由于应用对性能苛刻的要求,目前ImageKnife只能随着OS一起优化,已经用到了不少API12和最新HarmonyOS的镜像的特性,放弃了对AP9,AI10的支持。 待后续OS API稳定后,我们也会思考下如何更好地兼容历史版本。
写在最后
有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)文档用来跟着学习是非常有必要的。
这份鸿蒙(HarmonyOS NEXT)文档包含了鸿蒙开发必掌握的核心知识要点,内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。
希望这一份鸿蒙学习文档能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!
获取这份完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习文档
鸿蒙(HarmonyOS NEXT)5.0最新学习路线
有了路线图,怎么能没有学习文档呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,内容包含:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。
获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习文档
《鸿蒙 (OpenHarmony)开发入门教学视频》
《鸿蒙生态应用开发V3.0白皮书》
《鸿蒙 (OpenHarmony)开发基础到实战手册》
OpenHarmony北向、南向开发环境搭建
《鸿蒙开发基础》
●ArkTS语言
●安装DevEco Studio
●运用你的第一个ArkTS应用
●ArkUI声明式UI开发
.……
《鸿蒙开发进阶》
●Stage模型入门
●网络管理
●数据管理
●电话服务
●分布式应用开发
●通知与窗口管理
●多媒体技术
●安全技能
●任务管理
●WebGL
●国际化开发
●应用测试
●DFX面向未来设计
●鸿蒙系统移植和裁剪定制
……
《鸿蒙进阶实战》
●ArkTS实践
●UIAbility应用
●网络案例
……