FtnApp 的缩略图实践     AyangXu
Agenda列表缩略图和预览大图图片缓存策略(磁盘,内存)耗时操作的应对(读写、压缩)大图滑动的逐步调优
两种缩略图的异同
列表缩略图文件小(15-20k)文件多(列表)滑动的时候频繁读高缓存命中
预览大图文件大(200k+)绘制耗时长重用率低内存控制要求更高
共同特点平滑性要求高多重检查:本地 ➜ 原图(压缩) ➜ 网络过度状态(ICON / loadingView)
loadThumbnail small                   big            QMCachethumb.db                 file           original             f...
小图的缓存策略(磁盘)            loadThumbnail    small               QMCache   thumb.db              original                file  ...
小图的缓存策略(磁盘)全部小图保存到⼀一个 DB启动的时候子线程加载(15k*100张)滚动停止时,只更新 visibleCells先更新内存,显示,再在后面更新 DB不要在 cellForRowAtIndexPath 里做太多事情
图片缓存策略
小图的缓存策略(内存)内存更新策略 缩略图只加不减 全部小图,包括默认的 ICON 都只读⼀一次
大图的缓存策略(内存)NSCache  NSDiscardableContent / NSPurgeableData  不Copy Key,释放时机不可控QMCache  NSMutableArray w/ NSMutableDictionar...
耗时操作的应对
本地 ➜ 原图 ➜ 网络                        QMCache难点:            thumb.db               file 两种 IO 操作                       origi...
GCD VS      OperationQueueGCD  保留作用域,线程池  不好控制并发任务,不好取消NSOperationQueue w/ NSBlockOperation  FIFO,封装了 GCD,可配置并发数,支持取消  保留还...
dispatch_async(   dispatch_get_global_queue(0,0), ^{     dispatch_async(      dispatch_get_main_queue(),^{/*UI*/});  });  ...
大图滑动的逐步调优
大图滑动的基本实现
两层UIScrollView    1        2
⼀一次性准备ContentSize{ numOfImages * (width + padding), height }
将读取逻辑扩展出去[previewImage renderMultipleImages: ^(int page, downloadImageCallback callback) {   asyncLoadImage(page, ^(UIImag...
评估工具           InstrumentsCore Animations      Allocations
大图滑动 V1图片和 loadingView 分开两个数组  未渲染部分用 [NSNull null] 占位,提前创建  好N个 loadingView  检查是否 [NSNull class] 来判定是否需要加  载scrollViewDid...
大图滑动 V1FPS 10-15不断创建新的 view,不断释放在 scrollViewDidEndDecelerating 才加载,太慢进列表时间很长,初始化东西太多
大图滑动 V1.1动态补充 loadingView将绘制逻辑改到 scrollViewWillBeginDragging缓存第二层的 zoomingScrollView
大图滑动 V1.1进列表时间有所改善所有第⼀一次翻动都很卡 FPS: 10-15Cache 过的 view 不需重新创建 FPS: 20-30
大图滑动 V1.2提前加载左右 N 页判定是否到了 N 页,再进行加载N=5
大图滑动 V1.2预加载左右 5 张,进列表时间又长了⼀一点左右 5 张之内 FPS 30-40第 6 张⼀一次性又要加载5张 FPS 10-20
大图滑动 V1.xzoomingScrollView 基本不可重用 大图缓存的命中率很低每⼀一次绘制都需要遍历三个N长数组 图片,loadingView,zoomingScrollView 每次翻动的时间跟列表长度相关 O(N)创建后不移出 v...
大图滑动 V2不采用单独的 loadingView 数组和 [NSNull null]  用 zoomingScrollView 来引用 loadingView 跟  imageView的缓存和回收  NSMutableSet    无序,NS...
大图滑动 V2scrollViewDidScroll判定当前可见的页(<=2)如果需要绘制,从 recyclePages 里 dequeue⼀一个放到 visiblePages回收不可见的页,从 visiblePages 里挪到recycleP...
大图滑动 V2FPS 40-50保持外层 UIScrollView 的 subviews,最多只有两个减少不断创建新 view 的开销减少 scrollViewDidScroll 时的遍历开销 O(1)
进化路线滑动时的 FPS 15 => 45滑动时的遍历:O(n) => O(1)内存增长:  view 的创建和回收: N => 2
Next?大图内存没有尽快释放  [obj release] 只是引用-1,并没有马上释放采用小图策略,DB 保存等比小图⼀一次加载到内存,内存只缓存小图 (20k * 100)快速滑动时拉伸小图,模糊,但是快scrollViewDidEndD...
And..[NSURLConnection sendSynchronousRequest:returningResponse:error:]所有网络数据都 load 到内存,并发下载三个,内存涨了 10M (Oh my!)对可能的大图片,异步 ...
Thanks Q&A
Upcoming SlideShare
Loading in …5
×

FtnApp 的缩略图实践

936 views

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
936
On SlideShare
0
From Embeds
0
Number of Embeds
8
Actions
Shares
0
Downloads
8
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

FtnApp 的缩略图实践

  1. 1. FtnApp 的缩略图实践 AyangXu
  2. 2. Agenda列表缩略图和预览大图图片缓存策略(磁盘,内存)耗时操作的应对(读写、压缩)大图滑动的逐步调优
  3. 3. 两种缩略图的异同
  4. 4. 列表缩略图文件小(15-20k)文件多(列表)滑动的时候频繁读高缓存命中
  5. 5. 预览大图文件大(200k+)绘制耗时长重用率低内存控制要求更高
  6. 6. 共同特点平滑性要求高多重检查:本地 ➜ 原图(压缩) ➜ 网络过度状态(ICON / loadingView)
  7. 7. loadThumbnail small big QMCachethumb.db file original file web thumbnail
  8. 8. 小图的缓存策略(磁盘) loadThumbnail small QMCache thumb.db original file web thumbnail
  9. 9. 小图的缓存策略(磁盘)全部小图保存到⼀一个 DB启动的时候子线程加载(15k*100张)滚动停止时,只更新 visibleCells先更新内存,显示,再在后面更新 DB不要在 cellForRowAtIndexPath 里做太多事情
  10. 10. 图片缓存策略
  11. 11. 小图的缓存策略(内存)内存更新策略 缩略图只加不减 全部小图,包括默认的 ICON 都只读⼀一次
  12. 12. 大图的缓存策略(内存)NSCache NSDiscardableContent / NSPurgeableData 不Copy Key,释放时机不可控QMCache NSMutableArray w/ NSMutableDictionary 自定义 Capacity,多了就删
  13. 13. 耗时操作的应对
  14. 14. 本地 ➜ 原图 ➜ 网络 QMCache难点: thumb.db file 两种 IO 操作 original 两个网络操作 file 相互嵌套 web thumbnail
  15. 15. GCD VS OperationQueueGCD 保留作用域,线程池 不好控制并发任务,不好取消NSOperationQueue w/ NSBlockOperation FIFO,封装了 GCD,可配置并发数,支持取消 保留还在队列里的 URL,避免重复的操作 快速滑动时,取消未开始的任务,优先留给当前页
  16. 16. dispatch_async( dispatch_get_global_queue(0,0), ^{ dispatch_async( dispatch_get_main_queue(),^{/*UI*/}); }); VS[queue addOperation: [NSBlockOperation blockOperationWithBlock:^{ dispatch_async( dispatch_get_main_queue(), ^{/*UI*/});}]];
  17. 17. 大图滑动的逐步调优
  18. 18. 大图滑动的基本实现
  19. 19. 两层UIScrollView 1 2
  20. 20. ⼀一次性准备ContentSize{ numOfImages * (width + padding), height }
  21. 21. 将读取逻辑扩展出去[previewImage renderMultipleImages: ^(int page, downloadImageCallback callback) { asyncLoadImage(page, ^(UIImage *image) { callback(image); }); }];
  22. 22. 评估工具 InstrumentsCore Animations Allocations
  23. 23. 大图滑动 V1图片和 loadingView 分开两个数组 未渲染部分用 [NSNull null] 占位,提前创建 好N个 loadingView 检查是否 [NSNull class] 来判定是否需要加 载scrollViewDidEndDecelerating 时加载每次加载时创建 view,加载过的不会释放
  24. 24. 大图滑动 V1FPS 10-15不断创建新的 view,不断释放在 scrollViewDidEndDecelerating 才加载,太慢进列表时间很长,初始化东西太多
  25. 25. 大图滑动 V1.1动态补充 loadingView将绘制逻辑改到 scrollViewWillBeginDragging缓存第二层的 zoomingScrollView
  26. 26. 大图滑动 V1.1进列表时间有所改善所有第⼀一次翻动都很卡 FPS: 10-15Cache 过的 view 不需重新创建 FPS: 20-30
  27. 27. 大图滑动 V1.2提前加载左右 N 页判定是否到了 N 页,再进行加载N=5
  28. 28. 大图滑动 V1.2预加载左右 5 张,进列表时间又长了⼀一点左右 5 张之内 FPS 30-40第 6 张⼀一次性又要加载5张 FPS 10-20
  29. 29. 大图滑动 V1.xzoomingScrollView 基本不可重用 大图缓存的命中率很低每⼀一次绘制都需要遍历三个N长数组 图片,loadingView,zoomingScrollView 每次翻动的时间跟列表长度相关 O(N)创建后不移出 view,subviews 越来越多
  30. 30. 大图滑动 V2不采用单独的 loadingView 数组和 [NSNull null] 用 zoomingScrollView 来引用 loadingView 跟 imageView的缓存和回收 NSMutableSet 无序,NSObject 不重复 visiblePages / recyclePages
  31. 31. 大图滑动 V2scrollViewDidScroll判定当前可见的页(<=2)如果需要绘制,从 recyclePages 里 dequeue⼀一个放到 visiblePages回收不可见的页,从 visiblePages 里挪到recyclePages如果不需要绘制,什么都不做
  32. 32. 大图滑动 V2FPS 40-50保持外层 UIScrollView 的 subviews,最多只有两个减少不断创建新 view 的开销减少 scrollViewDidScroll 时的遍历开销 O(1)
  33. 33. 进化路线滑动时的 FPS 15 => 45滑动时的遍历:O(n) => O(1)内存增长: view 的创建和回收: N => 2
  34. 34. Next?大图内存没有尽快释放 [obj release] 只是引用-1,并没有马上释放采用小图策略,DB 保存等比小图⼀一次加载到内存,内存只缓存小图 (20k * 100)快速滑动时拉伸小图,模糊,但是快scrollViewDidEndDecelerating 时绘制大图view 不可见时马上清大图 image = nil;
  35. 35. And..[NSURLConnection sendSynchronousRequest:returningResponse:error:]所有网络数据都 load 到内存,并发下载三个,内存涨了 10M (Oh my!)对可能的大图片,异步 IO + 文件流
  36. 36. Thanks Q&A

×