造成tableView卡顿的原因有哪些?
-
1.提前计算并缓存cell的属性及内容。
当我们创建cell的数据源方法时,编译器并不是先创建cell再定cell的高度,而
是先根据内容依次确定每一个cell的高度,高度确定后,再创建要显示的cell,
滚动时,每当cell进入屏幕都会计算高度,提前估算高度告诉编译器,编译器
知道高度后,紧接着就会创建cell,这时再调用高度的具体计算方法,这样可
以防止浪费时间去计算显示以外的cell。 -
2.最常用的就是cell的重用, 注册重用标识符。
如果不重用cell时,每当一个cell显示到屏幕上时,就会重新创建一个新的cell
如果有很多数据的时候,就会堆积很多cell。
如果重用cell,为cell创建一个ID,每当需要显示cell 的时候,都会先去缓冲池
中寻找可循环利用的cell,如果没有再重新创建cell。 -
3.避免cell的重新布局。
cell的布局填充等操作 比较耗时,一般创建时就布局好,如可以将cell单独放
到一个自定义类,初始化时就布局好。 -
4.减少cell中控件的数量。
尽量使cell得布局大致相同,不同风格的cell可以使用不用的重用标识符,初始
化时添加控件,不适用的可以先隐藏。 -
5.如果cell内显示得内容来自
web
,使用异步加载,缓存结果请求。当cell中的部分View是非常独立的,并且不便于重用的,而且“体积”非常小,在内存可控的前提下,我们完全可以将这些view缓存起来。当然也是缓存在模型中。 -
6.不要使用
ClearColor
,无背景色,透明度也不要设置为0,渲染耗时比较长。 -
7.使用局部更新。
如果只是更新某组的话,使用reloadSection
进行局部更。 -
8.加载网络数据,下载图片,使用异步加载,并缓存。
-
9.少使用
addView
给cell动态添加view
。 -
10.按需加载cell,cell滚动很快时,只加载范围内的cell。
-
11.不要实现无用的代理方法,
tableView
只遵守两个协议。 -
12.缓存行高。
estimatedHeightForRow
不能和HeightForRow
里面的layoutIfNeed
同时存在,这两者同时存在才会出现“窜动”的bug。所以我的建议是:只要是固定行高就写预估行高来减少行高调用次数提升性能。如果是动态行高就不要写预估方法了,用一个行高的缓存字典来减少代码的调用次数即可。 -
13.不要做多余的绘制工作。
在实现drawRect
:的时候,它的rect
参数就是需要绘制的区域,这个区域之外的不需要进行绘制。例如,可以以用CGRectIntersectsRect
、CGRectIntersection
或CGRectContainsRec
t判断是否需要绘制image
和text
,然后再调用绘制方法。 -
14.预渲染图像。
当新的图像出现时,仍然会有短暂的停顿现象。解决的办法就是在bitmap contex
t里先将其画一遍,导出成UIImage
对象,然后再绘制到屏幕。 -
14.使用正确的数据结构来存储数据。
如何提升 tableview 的流畅度?
-
降低
CPU
、GPU
的工作,从这两个大的方面去提升性能。
CPU
:对象的创建和销毁、对象属性的调整、布局计算、文本的计算和排版、图片的格式转换和解码、图像的绘制。
GPU
:纹理的渲染。 -
卡顿优化在
CPU
层面
尽量用轻量级的对象,比如用不到事件处理的地方,可以考虑使用CALayer
取代UIView
。
不要频繁地调用UIView
的相关属性,比如frame
、bounds
、transform
等属性,尽量减少不必要的修改。尽量提前计算好布局,在有需要时一次性调整对应的属性,不要多次修改属性。
Autolayout
会比直接设置frame
消耗更多的CPU
资源。图片的
size
最好刚好跟UIImageView
的size
保持一致。控制一下线程的最大并发数量。
尽量把耗时的操作放到子线程。
文本处理(尺寸计算、绘制)。
图片处理(解码、绘制)。
-
卡顿优化在
GPU
层面尽量避免短时间内大量图片的显示,尽可能将多张图片合成一张进行显示。
GPU
能处理的最大纹理尺寸是4096x4096
,一旦超过这个尺寸,就会占用CPU
资源进行处理,所以纹理尽量不要超过这个尺寸。尽量减少视图数量和层次。
减少透明的视图(
alpha<1
),不透明的就设置opaque
为YES
。尽量避免出现离屏渲染。
-
iOS 保持界面流畅的技巧
1.预排版,提前计算
在接收到服务端返回的数据后,尽量将CoreText
排版的结果、单个控件的高度、cell 整体的高度提前计算好,将其存储在模型的属性中。需要使用时,直接从模型中往外取,避免了计算的过程。
尽量少用UILabel
,可以使用CALayer
。避免使用AutoLayout
的自动布局技术,采取纯代码的方式。2.预渲染,提前绘制
例如圆形的图标可以提前在,在接收到网络返回数据时,在后台线程进行处理,直接存储在模型数据里,回到主线程后直接调用就可以了
避免使用 CALayer 的 Border、corner、shadow、mask 等技术,这些都会触发离屏渲染。3.异步绘制
4.全局并发线程
5.高效的图片异步加载
网友评论