Tencent / LKImageKit

A high-performance image framework, including a series of capabilities such as image views, image downloader, memory caches, disk caches, image decoders and image processors.
Other
2.08k stars 287 forks source link

相对于SDWebImage的优势在哪里 #5

Closed glary closed 6 years ago

XavierLost commented 6 years ago

我也想知道......

jiaqiu-09 commented 6 years ago

同问

SimonHolmeslm commented 6 years ago

优势在于是腾讯开源的.有任务需求吧

kelingjie1 commented 6 years ago

其实优势不是没有,而且蛮多的,我先简单列一下后面会单独输出一篇文章。 1、架构设计上 额外增加了对缓存、处理、加载、解码的控制模块 开发者可以定义自己的缓存算法、加载数据源、解码器等。 2、缓存 2.1 UIImage引用缓存 通过对UIImage生命周期的监视,实现对内存无额外占用的高效缓存,使用这个缓存之后,可以将LRU缓存的总大小,调整为原来的一半甚至更少的情况下,保持较高的缓存命中率 2.2自定义缓存 自定义缓存可以根据业务需求,定义符合场景的缓存优化策略 比如在微云中,为了实现最高速度的缩略图加载,缩略图都以未解码的二进制形式存储在内存中,在查找缓存的过程中应优先查找解码内存缓存,再查找未解码内存缓存(新),然后文件缓存,最后下载 3、加载 使用职责链模式设计的插件化方式,使得加载更加的灵活和丰富 可以从文件、网络、相册、bundle等多个地方加载,还能定制化加载需求 比如在微云中,有的图片请求是需要先拿fileid换URL再用URL下载图片,这部分逻辑都可以做在组件的加载器层 4、解码 支持第三方的解码器,在实际项目中,我们一般额外接入了webP和sharpP的解码 5、多级加载 比如可以先设置一个默认图,在设置一个小图URL和一个大图URL 并将小图加载优先级调为高 那么在列表快速滑动中,总是先显示小图,可以保证列表滑动尽量少的空白体验

7、绘制为显示区域大小 开启预绘制后,图片在显示之前会缩放为显示区域的大小,由于APP当中,大部分情况显示区域都是不会改变的。所以绘制为显示区域的大小,并缓存,能显著的降低图片占用的内存,以及显示所使用的运算资源占用,达到提高流畅性的目的。

6、二级请求合并 组件会对数据源一致且图片处理逻辑一致的请求进行合并,防止重复的图片处理运算 之后,会对数据源一致的再进行一次合并,防止重复加载

8、优先级动态调整 在实际使用过程中,图片预下载是一个很好的提升体验的策略,但是往往预下载和图片本身的下载互相占用网速,优先级不明确。 在组件中,通过对优先级的设置实现了对正常图片显示毫无影响的高效预下载。

考虑一个优化的场景: 你可以一口气将10000张图片加入预下载队列中,优先级为veryLow 将图片的封面小图,优先级设为veryHigh 将下一屏图片的封面小图,优先级设为high 将图片的封面大图,优先级设为normal 遇到图片加载和图片预下载为同个URL的时候,请求会自动合并,并且优先级调整为较高的那个。 滑出屏幕cancel的时候,又会将优先级调回原来的级别。 因此,配合优先级动态调整和请求合并,使得快速滑动场景的图片响应速度比其他开源组件快很多 而且由于本质上预下载和普通加载对于组件内部是一视同仁的,只通过优先级控制, 使得完全不会对正常加载产生影响。

9、处理模块 图片处理模块提供了图片在显示之前在后台线程对图片进行操作的机会。 使得开发者可以将图片特效、滤镜等效果集成到该组件当中。

10、极致化API性能 SDWebImage通过CGContext进行绘制,促使系统对图片进行解码,这是比较低效的方式 使用ImageIO对图片进行解码能比CGContext绘制提升40%的性能 具体的性能对比可以看我在知乎发的文章https://zhuanlan.zhihu.com/p/26955368 这个组件实现的优化点已经比文章里说的多出不少了,后续我会再输出一篇文章。

而且专门针对不同场景的图片使用不同的解码API 对于没有图片处理任务的使用ImageIO,实现最高效率的解码 对于有图片处理任务的,因为反正需要使用CGContext,则关闭ImageIO的解码,节约资源

11、更高级的缩放模式 支持的缩放模式超过系统定义的那些,可以定义anchorPoint和focusPoint 在开启预绘制的情况下,使用内置图片处理模块对图片进行处理(高效,不支持无极缩放) 在关闭预绘制的情况下,通过对内置UIImageView的移动和缩放进行处理(支持无极缩放)

12、精细的多线并发控制 组件可以分别对IO密集的加载模块,CPU密集的解码模块,GPU密集的处理模块分别定制并发数,更充分的利用硬件的性能。

Hoikiiz commented 6 years ago

SDWebImage都是上古框架了,有AFN就不需要SD了。至于腾信爸爸的这个框架简单看了一下,还是用的自定义缓存,这一点跟SD区别不大,要说优势应该是对于优先级和支持gif等解码之类的吧

kelingjie1 commented 6 years ago

刚刚写了很多,你可以细看一下,如果你需要开发数千上万的图片墙场景,SD和AFN应该是无法满足需求的。加载、取消等等的反应速度在这种场景下是很关键的指标。 另外SD和AFN对自定义功能都不太友好,不容易对一些需求做定制。

dadpp commented 6 years ago

发现滚动快一点的话,是奔溃哦。 image

kelingjie1 commented 6 years ago

这个问题我看下。 这个组件在项目当中,使用的公司的另外一个下载组件。 因为公司开源比较严格,所以不能一起开源,所以暂时先写了一个替代。

kelingjie1 commented 6 years ago

问题找到了,是容器访问的线程安全问题,我加锁保护了,麻烦再试试看看还会不会遇到

wangxu123 commented 6 years ago

SD现在好多使用者都会去修改它的源码,确实是上古框架了。特别是对gif图片的支持很不友好

helinyu commented 6 years ago

不是有个YYWebImage么? 两者相比如何?

kelingjie1 commented 6 years ago

YYImage额外提供了对Web解码的内置支持。我们的webP解码的插件在项目内已经在使用,后续也会继续开源出来。 YYImage只提供了很少的接口来解决图片加载的问题,在功能上、性能优化上并没有深入下去。具体的优势和上面对比SDWebImage的差不多。

关于性能的对比,我建议可以构造一个和DEMO里面完全一致的图片墙场景对比,试试快速滑动的反应和加载速度。应该可以得到你想要的结论。