Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
FtnApp 的缩略图实践
Search
Frank Xu
August 26, 2012
Programming
0
46
FtnApp 的缩略图实践
Frank Xu
August 26, 2012
Tweet
Share
More Decks by Frank Xu
See All by Frank Xu
Proxy Pattern
yyfrankyy
0
78
微信读书阅读器架构
yyfrankyy
2
2.1k
Watcher - EventBus Reinvented
yyfrankyy
0
150
SQLite 调优实践
yyfrankyy
0
110
JSDoc 的使用
yyfrankyy
0
130
交易平台化(前端)
yyfrankyy
0
160
淘宝搜索前端优化
yyfrankyy
0
140
淘宝排行榜 V3 项目总结
yyfrankyy
0
110
Other Decks in Programming
See All in Programming
KSPの導入・移行を前向きに検討しよう!
shxun6934
PRO
0
280
Method Swizzlingを行うライブラリにおけるマルチモジュール設計
yoshikma
0
120
状態管理ライブラリZustandの導入から運用まで
k1tikurisu
3
470
私のEbitengineの第一歩
qt_luigi
0
450
Lessons by WebAssembly app in production on CDN Edge Computing Service
tetsuharuohzeki
0
210
Hono・Prisma・AWSでGeoなAPI開発
nokonoko1203
5
680
Go1.23で入った errorsパッケージの小さなアプデ
kuro_kurorrr
2
390
オートマトン学習しろ / Do automata learning
makenowjust
3
130
Jakarta EE meets AI
ivargrimstad
1
520
LangChainの現在とv0.3にむけて
os1ma
4
920
AndroidアプリのUIバリエーションをあの手この手で確認する / Check UI variations of Android apps by various means
tkmnzm
1
180
Some more adventure of Happy Eyeballs
coe401_
2
190
Featured
See All Featured
Practical Orchestrator
shlominoach
185
10k
Optimizing for Happiness
mojombo
375
69k
WebSockets: Embracing the real-time Web
robhawkes
59
7.3k
Clear Off the Table
cherdarchuk
91
320k
No one is an island. Learnings from fostering a developers community.
thoeni
18
2.9k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
230
17k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
36
2.1k
The Cult of Friendly URLs
andyhume
76
6k
Product Roadmaps are Hard
iamctodd
PRO
48
10k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
23
1.7k
Designing for Performance
lara
604
68k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
43
2k
Transcript
FtnApp 的缩略图实践 AyangXu
列表缩略图和预览大图 图片缓存策略(磁盘,内存) 耗时操作的应对(读写、压缩) 大图滑动的逐步调优 Agenda
两种缩略图的异同
列表缩略图 文件小(15-20k) 文件多(列表) 滑动的时候频繁读 高缓存命中
预览大图 文件大(200k+) 绘制耗时长 重用率低 内存控制要求更高
共同特点 平滑性要求高 多重检查:本地 ➜ 原图(压缩) ➜ 网络 过度状态(ICON / loadingView)
small loadThumbnail big QMCache thumb.db file original file web thumbnail
小图的缓存策略(磁盘) small loadThumbnail QMCache thumb.db original file web thumbnail
小图的缓存策略(磁盘) 全部小图保存到⼀一个 DB 启动的时候子线程加载(15k*100张) 滚动停止时,只更新 visibleCells 先更新内存,显示,再在后面更新 DB 不要在 cellForRowAtIndexPath
里做太多事情
图片缓存策略
小图的缓存策略(内存) 内存更新策略 缩略图只加不减 全部小图,包括默认的 ICON 都只读⼀一次
大图的缓存策略(内存) NSCache NSDiscardableContent / NSPurgeableData 不Copy Key,释放时机不可控 QMCache NSMutableArray w/
NSMutableDictionary 自定义 Capacity,多了就删
耗时操作的应对
QMCache thumb.db file original file web thumbnail 难点: 两种 IO
操作 两个网络操作 相互嵌套 本地 ➜ 原图 ➜ 网络
GCD VS OperationQueue GCD 保留作用域,线程池 不好控制并发任务,不好取消 NSOperationQueue w/ NSBlockOperation FIFO,封装了
GCD,可配置并发数,支持取消 保留还在队列里的 URL,避免重复的操作 快速滑动时,取消未开始的任务,优先留给当前页
[queue addOperation: [NSBlockOperation blockOperationWithBlock:^{ dispatch_async( dispatch_get_main_queue(), ^{/*UI*/}); }]]; dispatch_async( dispatch_get_global_queue(0,0),
^{ dispatch_async( dispatch_get_main_queue(),^{/*UI*/}); }); VS
大图滑动的逐步调优
大图滑动的基本实现
两层UIScrollView 1 2
⼀一次性准备ContentSize { numOfImages * (width + padding), height }
[previewImage renderMultipleImages: ^(int page, downloadImageCallback callback) { asyncLoadImage(page, ^(UIImage *image)
{ callback(image); }); } ]; 将读取逻辑扩展出去
评估工具 Core Animations Allocations Instruments
大图滑动 V1 图片和 loadingView 分开两个数组 未渲染部分用 [NSNull null] 占位,提前创建 好N个
loadingView 检查是否 [NSNull class] 来判定是否需要加 载 scrollViewDidEndDecelerating 时加载 每次加载时创建 view,加载过的不会释放
大图滑动 V1 FPS 10-15 不断创建新的 view,不断释放 在 scrollViewDidEndDecelerating 才加载,太 慢
进列表时间很长,初始化东西太多
大图滑动 V1.1 动态补充 loadingView 将绘制逻辑改到 scrollViewWillBeginDragging 缓存第二层的 zoomingScrollView
大图滑动 V1.1 进列表时间有所改善 所有第⼀一次翻动都很卡 FPS: 10-15 Cache 过的 view 不需重新创建
FPS: 20-30
大图滑动 V1.2 提前加载左右 N 页 判定是否到了 N 页,再进行加载 N =
5
大图滑动 V1.2 预加载左右 5 张,进列表时间又长了⼀一点 左右 5 张之内 FPS 30-40
第 6 张⼀一次性又要加载5张 FPS 10-20
大图滑动 V1.x zoomingScrollView 基本不可重用 大图缓存的命中率很低 每⼀一次绘制都需要遍历三个N长数组 图片,loadingView,zoomingScrollView 每次翻动的时间跟列表长度相关 O(N) 创建后不移出
view,subviews 越来越多
大图滑动 V2 不采用单独的 loadingView 数组和 [NSNull null] 用 zoomingScrollView 来引用
loadingView 跟 image View的缓存和回收 NSMutableSet 无序,NSObject 不重复 visiblePages / recyclePages
大图滑动 V2 scrollViewDidScroll 判定当前可见的页(<=2) 如果需要绘制,从 recyclePages 里 dequeue ⼀一个放到 visiblePages
回收不可见的页,从 visiblePages 里挪到 recyclePages 如果不需要绘制,什么都不做
大图滑动 V2 FPS 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) 快速滑动时拉伸小图,模糊,但是快 scrollViewDidEndDecelerating 时绘制大图 view 不可见时马上清大图 image = nil;
And.. [NSURLConnection sendSynchronousRequest:returningResponse:error:] 所有网络数据都 load 到内存,并发下载三个, 内存涨了 10M (Oh my!)
对可能的大图片,异步 IO + 文件流
Thanks Q&A