设为首页 加入收藏

TOP

京喜APP - 图片库优化(一)
2023-07-23 13:25:24 】 浏览:79
Tags:京喜 APP

作者:京东零售 何骁

介绍

京喜APP早期开发主要是快速原生化迭代替代原有H5,提高用户体验,在这期间也积累了不少性能问题。之后我们开始进行一些性能优化相关的工作,本文主要是介绍京喜图片库相关优化策略以及关于图片相关的一些关联知识。

图片性能问题

作为电商APP,图片在各个业务场景被大量使用。我们需要做到尽可能降低网络消耗/内存消耗/硬盘消耗,同时不降低图片质量,提高图片加载速度,给用户带来更好的使用体验。基于这些性能目标,我们也通过初步性能评估梳理出了一些性能问题:

图片加载慢/流量消耗高

图片链接主要由后台接口下发,下发图片格式尺寸由每个业务后台指定。部分业务没有使用更小的图片格式比如WebP,或图片尺寸过大,都会使图片过大导致网络消耗高。特别是网络状况不佳的场景,图片加载过慢给用户带来不好的体验。同时也会导致更多的I/O读写解码耗时,造成更多的电量消耗。

图片内存占用高

经过初步的APP内存使用评估,图片内存消耗占APP总内存消耗的比例最高,特别是大尺寸图片会占用很多内存。一方面APP占用太高内存退到后台容易被系统杀死,导致下次打开重新启动影响体验。另一方面APP大量使用内存,容易被系统杀死产生OOM。特别是我们目前有大量的低端设备用户,设备内存相对比较低。

优化方向

基于上面分析出的一些性能问题,我们对图片框架进行了整体重构优化。一方面是降低图片网络传输,提高图片加载速度。另一方面是减少图片内存消耗。

图片优化.png

最小化网络传输

京东图片服务器提供了多种处理功能,例如图片格式转换,图片降质,图片缩放,图片圆角等功能。这些功能通过在图片URL中添加特定参数实现,图片服务器会根据参数设置提前将图片处理完成并保存到CDN服务器。我们可以通过添加图片处理参数,减少图片传输大小。

虽然后台可以提前进行URL预处理,下发已添加过图片参数的图片URL。但是由于对接后台业务很多,每个业务图片参数设置差异很大无法统一,而且可能会造成性能影响,例如没有使用webP图片格式,下发太大的图片尺寸。同时考虑到推动各业务后台修改成本也很高,并且前端机型多,不同机型需要使用不同的图片尺寸。另外也不方便灰度降级功能,后续功能修改也不方便。所以在客户端进行图片URL预处理是更好的方式,可以统一控制,也方便之后功能更新。

图片URL预处理

URL预处理

图片库在网络图片加载前,检测是否是京东域名的图片URL。如果域名匹配,图片框架先对图片URL进行预处理,预处理包括域名统一添加缩放参数添加webP参数添加降质参数的方式减少图片网络传输大小。

提示:因为后台返回的图片URL可能会带有一部分图片处理参数,例如https://img11.360buyimg.com/img/pingou-head/25.jpg!webp,直接追加图片参数可能会导致图片处理参数不生效,或格式错误导致加载失败。所以转换时会先将所有图片参数提前计算出来,之后一起处理,避免添加重复参数。

域名统一

目前图片服务器提供了多个图片域名可使用,例如m.360buyimg.comimg10.360buyimg.com等多个域名。m.360buyimg.com主要提供给移动端使用。但是由于对接了各种业务后台,导致接口会下发不同的域名图片。图片使用不同域名可能会导致以下问题:

  • 不利于缓存复用- 图片框架通常默认以URL字符串生成图片缓存key,不同域名导致生成不同的缓存key硬盘缓存无法复用会导致图片重复下载,内存缓存无法复用导致同样的图片占用多份内存。
  • 不利于HTTP/2连接复用- 大部分界面图片比较多,很多场景都会同时加载多张图片,特别是首屏通常会加载几十张图片。当加载多个图片时,每个域名都需要重新建立HTTPS连接,经历DNS解析/TCP连接/TLS握手过程(目前一次HTTPS请求创建过程大概耗时50-150ms)。如果利用HTTP/2链接复用就只需要创建一次HTTPS请求,之后的图片请求可以减少这部分的耗时。

所以在预处理时,如果是京东域名的图片,将图片URL域名统一替换为m.360buyimg.com

追加图片参数

图片缩放

很多业务后台返回的原始图片URLsize都比客户端实际显示的size要大。一方面导致使用更多的网络流量造成浪费。另一方面会导致占用更多内存。同时因为图片size和实际显示size不一致导致像素不对齐GPU需要做额外的插值处理,也会一定的影响渲染性能。所以我们通过添加缩放参数的方式,指定图片服务器下发更小和更匹配实际显示size的图片尺寸。

动态scale计算尺寸

因为iOS设备主要使用2x/3x的分辨率,所以业务方使用API时需要传入对应的ptsize大小,图片库内部根据设备的scale进行动态计算出真实的像素宽高。

提示:android设备因为屏幕差异比较大,更适合使用固定的scale。太多的图片尺寸不利于CDN缓存,无缓存的时候需要对图片进行相关参数处理,图片处理本身是耗时操作。

Scale降级

  • 低端机降级- 对于部分3xscale的低端设备,因为机器本身内存比较低,使用3x分辨率计算出来的图片像素宽高比较大,会造成更多的内存消耗以及解码/渲染更多的性能消耗。所以对于宽高超过一定要求的图片,降级到使用2x分辨率来计算像素宽高,减少设备性能消耗。
  • iPad降级- 因为目前APP并没有针对iPad做特定优化,所以iPad设备下默认是放大显示。这会导致在iPad下图片尺寸计算出来特别大。所以也是针对iPad图片尺寸做了特定限制,防止下发图片尺寸过大。
  • 大图片降级- 正常情况下图片宽/高不应该超过屏幕宽/高。为了防止部分业务使用过大的图片size,所以添加了一个限制,最终生成的图片像素尺寸不能超过屏幕宽/高

降质

图片服务器支持0-100的图片质量参数设置,通过降低图片质量可以减少图片大小,但是质量降低太多也会影响图片的观看体验。我们将图片质量参数设置为q70,指定图片服务器下发70%质量的图片。对于大部分业务,一方面可以大幅减少图片下载大小,同时也可以保证观看体验。通过添加图片降质参数至少可以减少30-40%的图片大小。

使用WebP

按照Google官方的数据,与PNG相比,WebP无损图像的字节数要少26%WebP有损图像比同类JPG图像字节数少25-34%。图片服务器支持转换webP格式,可以减少图片大小。针对png/jpg图片格式,添加webP参数,指定图片服务器下发webp格式。虽然webP相比png/jpg图片解码需要更长时间,但相对网络传输速度提升还是很大。

提示:由于目前图片服务器并不支持GIFwebP,GIF并没有做处理。

URL预处理缓存

添加轻量缓存,提高URL转换性能。因为URL转换本身有一定的耗时,而且单个图片URL可能会多次加载/多次转换。转换后的URL会直接保存到缓存中,下次使用可以直接返回。缓存keyURL+相关图片转换参数拼接组成。

图片API设计

图片处理参数通过options设置,默认使用q70图片质量以及webP格式。业务方在调用加载图片方法时传入,下面是iOS端的API:

imageView6.jx.setImage(url: URL(string: "https:
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇IOS使用AutoLayout让UIScrollView.. 下一篇uniapp ios app离线打包

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目