速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

veImageX 演进之路:iOS 高性能图片加载 SDK

字节跳动技术团队-周旋

  • 2023-04-26
    北京
  • 本文字数:5442 字

    阅读完需:约 18 分钟

veImageX 演进之路:iOS 高性能图片加载 SDK

SDK 简介


图片在业务应用场景是一个常见的元素,veImageX(简称 ImageX)为业务提供了灵活、高效的一站式图片处理解决方案,包括了服务端 SDK、上传 SDK 和客户端图片加载 SDK。本文就来介绍下 iOS 客户端图片加载 SDK(下文中简称 SDK),SDK 主要提供图片网络加载、图像解码、图片基础处理与变换以及图片服务质量监控上报等能力。


业内主流开源图片加载 SDK


在介绍 veImageX 图片加载 SDK 之前先看看业内目前有哪些主流的图片加载 SDK,veImageX 图片加载 SDK 是使用 Objective-C 语言开发的,业内使用 Objective-C 语言实现的主流开源图片加载 SDK 有 YYWebImage,SDWebImage 等。


  • YYWebImage:一个异步图片加载框架(YYKit 的一个组件)。它是作为 SDWebImage、PINRemoteImage 和 FLAnimatedImage 的改进替代品而创建的。它使用 YYCache 支持内存和磁盘缓存,使用 YYImage 支持 WebP/APNG/GIF 图片解码,但可惜的是此优秀的框架于 2017 年左右已停止更新;


  • SDWebImage:目前使用较广泛的一个图片处理框架,可以异步加载网络图片,并支持图片本地缓存等特性,也是一款优秀的图片加载框架。


veImaegX 的 SDK 优势


veImageX 图片加载 SDK 也是借鉴各家之所长,基于一些业务实际线上应用的属性自研了一套图片加载 SDK,相比于这些开源图片加载 SDK,主要有以下特性:


  • 采用分层与模块化架构设计,根据业务需要选择相应功能模块,最大程度精简包大小;

  • 支持 WebP、AVIF、HEIF 这种高压缩率图片格式,特别是在自研的高性能 HEIF 软件解码库支持下,能够高效解码 HEIF 格式,并摆脱 HEIF 原生 iOS 系统版本的限制;

  • 支持云端加密、客户端解密,保障图片隐私安全;

  • SDK 的网络库支持 HTTPDNS,可以高效防止内容劫持及域名劫持,能够有效降低图片解码失败率,提升客户端图片加载体验;

  • 支持采集各项图片相关数据并上报,配合 veImageX 控制台实时大盘数据查看,可以为业务的运营及产品的体验提升提供全面的从数据发现、数据分析、数据监控、数据诊断、数据追踪等全链路支持。


SDK 架构


随着时间的推移,SDK 的功能越来越多,各种业务对 SDK 的功能选择也开始多样化起来,特别是在 App 包体积日益增长需要降低的大背景下,SDK 也需要做包体积瘦身,面对以上种种问题,SDK 对功能的模块化/插件化能力的要求也越来越高,SDK 的架构也就随之演变成下图的样子。



SDK 主要分为三层


  • 接口层,也是最上层,这一层提供图片加载与处理的各种接口,接口设计与主流开源图片加载 SDK 保持一致,在这一层提供适配器,提供了开源图片加载 SDK(如 YYWebImage,SDWebImage 等)的适配层,方便业务快速上手与无缝切换;

  • 管理层,作为中间层负责各种模块的交互管理,也包括云控配置管理和授权管理等;

  • 模块层,这一层包含了图片加载流程的各个模块:下载模块,缓存模块,解码模块,日志上报模块等,业务可以根据自身需求来选择性依赖这些模块的各种功能,达到最小化依赖的原则。


UIImageView 如何通过 SDK 渲染出一张网络图片


业务上图片的主流应用场景就是加载网络图片,以 iOS 原生系统控件 UIImageView 为例,通过 SDK 加载一张网络图片的完整流程如下:


发起图片请求 -> 查询内存缓存 -> 查询磁盘缓存 -> 加入下载队列 -> 开始下载 -> 获取到服务端图片未解码数据 -> 从图片未解码数据中解码后得到可以渲染的图片 -> 将解码后的图片和图片未解码数据分别缓存进内存和磁盘 -> UIImageView 渲染解码后的图片,至此,一张网络图片被成功加载并展示给用户。



 SDK 模块介绍


在了解完 SDK 的主流场景中网络图片的完整加载流程后,下面分别介绍一下 SDK 加载流程中的下载、缓存、解码、日志上报与图片后处理这五大主要模块。


下载模块


下载模块的主要任务是通过网络库把网络图片从服务端下载到客户端,这个过程对图片加载来讲是非常重要的一环,下载的成功与否直接决定了图片能否正确展示,而网络库的性能也决定了图片下载的快慢,最终反映到用户的感受体验上。所以,下载模块中的下载任务除了支持苹果原生系统的网络库实现外,也支持字节内部强大的自研网络库 TTNetwork 实现,该库不仅做了一些网络相关优化,例如 HTTPDNS,HTTP2+HTTPS 连接复用优化、链路选择、动态策略等,支持最新的网络协议 QUIC,也提供了更为细粒度的网络监控,为 SDK 的图片下载提供了高效的支持。SDK 默认支持原生网络库与自研网络库,如果业务有自己的网络库,也可以通过插件化的形式集成进来。



业务上一般会并发下载多张图片,在 Feed 流场景中如果用户来回滑动图片,同样的图片会发生多次请求,如果相同图片的多个请求都去反复下载图片,这样显然会浪费用户流量,也会增加带宽成本。SDK 会管理这些并发的下载任务,并标记相同的图片请求,避免这种问题的发生。下载任务的管理与调度通过 iOS 系统原生的 NSOperation 与 NSOperationQueue 实现,同时会根据请求参数生成一个 Identifier,用来唯一标识一个下载任务,交由下载管理器去管理,这样就能避免在同一个时间段内重复多次下载相同的图片。



缓存模块


缓存模块由内存和磁盘共同组成一个二级缓存结构,当一张图片被下载到客户端上时,会被缓存进内存和磁盘缓存,如果 App 生命周期内再请求这张图片,则可以从内存缓存中查到,如果冷启动 App 后再请求这张图片,则可以从磁盘缓存中查到。这样不仅可以加快图片的加载速度,提升用户体验,也可以降低用户流量,节省带宽成本。再对缓存加上过期时间限制,就可以解决图片的时效性问题。


内存缓存方面除了支持 iOS 原生的 NSCache 外,还支持 Strong-Weak 的弱引用缓存,当缓存对象无人持有时会被及时释放掉,降低内存占用,同时也支持 LRU 缓存。在收到内存不足的通知时会主动释放内存,缓解内存压力,同时保证线程安全。磁盘缓存方面除了支持最基本的 iOS 系统文件管理 NSFileManager,还支持 LRU 缓存,同时保证线程安全。


整体看,如果 App 内只使用同一种固定的缓存算法的话,由于图片使用场景各不相同,同一种缓存算法无法满足所有场景,缓存命中率就会偏低。除了 SDK 默认支持的缓存算法外,由于内存和磁盘缓存都是由协议定义的,业务也可以根据需求去自定义缓存,在不同场景下使用不同的缓存算法,这样可以极大的提高缓存命中率。在一些业务特定场景上 SDK 的缓存命中率能够达到 80% 左右,随着缓存命中率的提升,带来的带宽成本节省收益也越大。



解码模块


图片下载到客户端上后都是未经过解码前的数据,想要把图片正确展示给用户,就必须对它进行解码。图片解码上支持通过 iOS 原生系统的解码框架 ImageIO 进行解码,即苹果原生能支持的格式,SDK 也能支持。除此之外,像 WebP、AVIF、VVIC(字节基于 BVC 算法自研的图片格式)等原生不支持的图片格式,SDK 通过自研解码器或者开源解码器的支持,也都能解码这些格式的图片。当有新格式的图片要支持时,只需实现对应格式的动静图协议就能以插件化的形式集成进 SDK,达到支持新格式图片的目的。


SDK 特色能力:iOS 全系统支持 HEIF


HEIF 这种高压缩率格式的图片在字节跳动公司内部的应用已经比较成熟了。带宽节省方面,相比 WebP,在同质量下还能再节约 30% 的带宽成本,为公司节省了大量的带宽成本。加载优化方面,HEIF 支持渐进式加载,可以先加载 HEIF 缩略图,再加载 HEIF 原图,在网络质量不好的场景下也能有不错的图片加载体验。SDK 有了公司内部自研的高性能 HEIF 软件解码库的支持,让 HEIF 格式图片的解码支持摆脱了 iOS 系统的限制,不再局限在 iOS 11 及以上才能使用 HEIF 静图,iOS 13 及以上才能使用 HEIF 动图,在低版本 iOS 上也能支持 HEIF 动静图,极大的提升了 HEIF 的应用范围,收获了大量的带宽成本节省收益。



图片后处理模块


在图片加载完后,业务也可以根据需要再次对图片进行各种实时转换,比如说加圆角、超分等,这些都是通过图片后处理来完成。下面介绍下 SDK 的一个特色能力:超分。


SDK 特色能力:超分


超分,即超分辨率,指的是基于机器学习/深度学习方法,从给定的低分辨率图片中恢复高分辨率的图片,借助图片后处理,可以在移动端上做到图片实时超分。


一般可以用于两种场景,一是用于提升用户体验,当原图片分辨率低、清晰度低时,对其进行超分后,可以用来提升清晰度,以达到提升用户观看体验的目的;二是用于降档超分,用户在请求高分辨率的图片时,可以在传输过程中降低图片的分辨率,然后在客户端上进行超分,提升到原请求的分辨率,以达到节省带宽成本的目的。



日志上报模块


SDK 包含了三大日志模块,图片性能日志、用户感知日志,大图监控日志,为业务的运营及产品的体验提升提供了全面的数据支持。配合火山引擎 veImageX 的控制台,可以实时查看各项可视化大盘数据,全方位的监控图片的各项指标。


其中,图片性能日志包括了图片 URL、下载耗时、解码耗时、错误码、图片来源等数据,用来监控图片各项性能指标;用户感知日志包括了图片 URL、ImageView 的 Size、ImageView 展示图片耗时等数据,用来监控用户体验各项指标;大图监控日志则包含了大图 URL、内存占用大小、图片文件体积、图片分辨率大小等数据,可以全面的监控异常大图情况。



演进:性能优化


SDK 致力于极致的图片加载用户体验,为此,SDK 做了很多相关性能优化,下面主要介绍下 SDK 如何提升图片加载体验、降低内存占用、优化动图播放。


提升图片加载体验


图片加载的快慢直接影响到用户的使用体验,高效的图片加载是 SDK 不可或缺的能力。


  • 渐进式加载

加载静图大图,或者加载多帧数动图,亦或者在弱网场景下,都可以开启图片渐进式加载来提升图片的加载体验。


SDK 支持传统的 PNG、JPEG 静图渐进式加载,也支持 HEIF 静图渐进式加载,先加载 HEIF 缩略图,再加载 HEIF 原图。SDK 同时也支持动图的渐进式加载,动图可以边下载边播放,在正常网络下,可以提高首帧的加载速度,在弱网下,类似于视频播放的缓冲机制,也可以提升动图的播放体验。


  • Force Decode

在图片解码方面,SDK 支持 Force Decode,能够提前把 Bitmap Buffer 转移到渲染进程,减少了未来渲染时再去拷贝的耗时,如果原始解码出来的 Bitmap Buffer,iOS 硬件屏幕不直接支持,会提前转换好,避免渲染时在主线程的转换开销,提高图片的加载帧率。


优雅的内存控制


通常情况下,App 内图片的场景还是很多的,当加载大量图片时,图片所占的内存可能会很大,如果内存占用过高,会带来 OOM 问题,给用户的感受跟 Crash 一样,都是应用突然闪退。


SDK 有如下的几种方案来降低图片内存占用:


  • 释放内存缓存

当系统内存紧张,收到内存不足通知时,缓存模块会及时释放内存缓存,同时也提供接口,由业务在适当时机主动释放内存缓存。


  • 全局图片降采样

图片在内存中的占用大小可以简单用如下公式来估算:


memoryCost(单位:字节)= imageWidth(单位:像素)* imageHeight(单位:像素)* 4


由公式可以看出,如果想要降低内存,那么就要想办法在不影响功能和体验的前提下尽量降低图片的宽高,由此,当不能明确下载后的图片大小是否会远大于需要展示的 ImageView 的大小时,可以使用全局图片降采样功能。全局图片降采样分为以尺寸大小限制进行降采样和以内存大小限制进行降采样。


以尺寸大小限制进行降采样:


如果当前图片的长宽都大于降采样的长宽,那么把原图片长宽等比例缩放到恰好能贴到降采样尺寸的轮廓



以内存大小限制进行降采样:


如果当前图片的内存占用超过内存限制,那么把原图片长宽等比例缩放到恰好低于内存限额



  • 禁止图片渲染

每次需要渲染前,都会给业务回调当前图片的元信息,例如图片的长宽尺寸、动图的帧数、以及预估的内存消耗量,业务可以根据此信息来禁止不符合预期的超大图渲染。


  • 大图监控

实际业务场景中,待展示图片的分辨率和帧数都是未知的。在一些极端情况下(线上真实案例),某个动图分辨率是 1080p、帧数上百帧,是用户录屏生成的,是个超大的动图,解码后有超过 1 个 GB 的内存占用,在一些低端机上就直接 OOM 了。对于这类 OOM 情况,很难根据常规方法排查。那怎么有效监控这种不符合预期的线上大图呢,SDK 通过图片展示尺寸,图片解码后内存占用大小和图片文件体积这三个维度来定义一个大图,当一张图片触发这三个维度中任意一个维度的阈值限制时,就会被记录到大图监控日志内,这些数据后续会被上报。业务通过 veImageX 控制台就可以看到大图监控这个指标下的详细数据,当发现内存占用大小这个值异常大后,就可以及时查到相应的图片 URL,然后结合实际业务场景,及时下线这种不符合预期的超大图,降低线上 OOM 率。


动图播放的优化


动图在业务上也是一个常见应用场景,如果能做好动图的优化,也可以带来用户体验的提升。动图在播放时,会不断解码每一帧图片,这时会大量消耗 CPU 资源,SDK 内部会计算当前可用的内存以及渲染动图的所有帧需要的内存,如果当前可用内存满足渲染动图所有帧需要的内存时,SDK 会缓存动图的所有帧,以此来节省 CPU 资源,如果当前可用内存不满足渲染动图所有帧需要的内存时,SDK 会在每一帧图片播放结束之后舍弃前一帧,也就是不断重复渲染下一帧图片,通过消耗 CPU 资源节约内存,达到 CPU 消耗与内存节省的一个平衡。


写在最后


业内虽然已经有很多很成熟的图片加载 SDK 了,但要契合公司自己业务发展的 SDK 也很重要,图片加载 SDK 作为 veImageX 整体产品端到端不可或缺的一环,也是在这种背景下应运而生了。除了一些性能优化外,在成本节省上,HEIF 格式的应用为公司节省了大量带宽成本,收益非常可观,并且也在持续尝试新的压缩率更高的图片格式,例如 VVIC。在前沿能力应用上,随着图片超分算法的不断迭代优化,相信在未来也能带来不错的体验上的提升和成本上的节省。

2023-04-26 13:048434
用户头像
鲁冬雪 GMI Cloud China Marketing Manager

发布了 362 篇内容, 共 264.9 次阅读, 收获喜欢 294 次。

关注

评论

发布
暂无评论
发现更多内容

智源未来选择 TDengine Cloud,解锁高效能源管理

TDengine

某个国外的真实XSS漏洞利用探寻

我再BUG界嘎嘎乱杀

黑客 网络安全 信息安全 XSS 漏洞

畅捷通基于Flink的实时数仓落地实践

Apache Flink

大数据 flink 实时数仓

Qwen2-Math 开源 AI 模型发布;阿里云推出首个域名 AI 大模型应用丨 RTE 开发者日报

声网

远程访问内网设备:对比IPsec VPN,SD-WAN异地组网更具优势

贝锐

运维 SD-WAN 远程运维 组网

全文彩印!人民邮电出版的“24小时学会黑客攻防”,讲的太好了!

我再BUG界嘎嘎乱杀

黑客 网络安全 安全 信息安全 网安

就一次!带你彻底搞懂CSRF攻击与防御

我再BUG界嘎嘎乱杀

黑客 网络安全 信息安全 CSRF 网安

Java智能之Spring AI:5分钟打造智能聊天模型的利器

快乐非自愿限量之名

Java 人工智能 spring AI

相聚中国香港,共赢智能未来!华为云邀您共赴 KubeCon China 2024

华为云原生团队

云计算 云原生 KubeCON AI 人工智能

JNPF快速开发平台助力企业实现工作流自动化

EquatorCoco

工作流 低代码 自动化运维

Pinterest:从 Druid 到 StarRocks,实现 6 倍成本效益比提升

StarRocks

Druid Pinterest

邀请函 I 松下信息和望繁信科技邀您参加「数智时代下大数据应用的“道”与“术”」闭门会议

望繁信科技

大数据 数字化转型 解决方案 流程挖掘 流程智能

解锁企业成功密码—商品计划的神奇力量

第七在线

实用指南|在多云环境中部署向量数据库

Zilliz

大数据 向量数据库 LLM 大语言模型 AICG

京东面试:说说CMS工作原理?

王磊

JNPF快速开发平台赋能数字办公方式转变

不在线第一只蜗牛

低代码 数字化转型 数字化办公

观测云突变告警,精准预测云原生的系统异常

观测云

云原生 监控告警

Kubernetes 监控:观测云与 Prometheus CRD 的集成

可观测技术

Kubernetes

XIAOJUSURVEY重磅升级,推出图形化逻辑编排能力

XIAOJUSURVEY

开源 规则引擎 可视化编排 图形化编排 问卷逻辑

扎克伯格说AI会让推荐系统变得更强大?一文读懂什么是智能推荐系统

爱AI的猫猫头

人工智能 音视频 推荐系统 办公效率 搜索系统

API可观察性对于现代应用程序的最大好处

幂简集成

API API 接口

vue前端自适应布局,一步到位所有自适应

不在线第一只蜗牛

Vue 前端

易点天下KreadoAI爆款视频生成功能上新 解锁出海营销新路径

新消费日报

亚信安慧AntDB-T:使用Brin索引提升OLAP查询性能以及节省磁盘空间

亚信AntDB数据库

AntDB

JNPF快速开发平台让业务活起来

快乐非自愿限量之名

数据分析与决策支持:京东商品详情API的商业价值

技术冰糖葫芦

API Explorer api 货币化 API 接口 API 测试

IoTDB 单机/双活/集群部署的区别和适用场景

Apache IoTDB

阿里巴巴拍立淘API返回值:商品关联推荐与交叉销售

技术冰糖葫芦

API Explorer api 货币化 API 接口 API 测试

【活动预告】研讨会+开源集市,IoTDB “登录” GOTC 2024!

Apache IoTDB

14点自动化经验

FunTester

现成源码开发游戏直播软件:应对快速变化的技术和用户需求

软件开发-梦幻运营部

veImageX 演进之路:iOS 高性能图片加载 SDK_AI&大模型_InfoQ精选文章