可能存在的问题场景
- 直播项目中多个GIF图播放不及时释放会占用内存
- 直播项目中多个GIF读取有可能导致短时间CPU占用率高
加载GIF的方式主要有两种:
- 原生加载
// 一帧一帧的图片组成数组去加载
self.redImgView.animationImages = [self imgDataList];
self.redImgView.animationDuration = 1;
self.redImgView.animationRepeatCount = 1;
[self.redImgView startAnimating];
- 第三方FLAnimatedImage加载
// 把多张图片组成GIF,加载GIF
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:_imgNameList];
FLAnimatedImage *image = [[FLAnimatedImage alloc] initWithAnimatedGIFData:data];
self.redImgView.animatedImage = image;
建议选用FLAnimatedImage加载GIF,具体原因可参考源码或者网上其它解释,这里暂时只讨论缓存方式
一、100张图片通过沙盒读取,imageWithContentsOfFile转成UIImage:
-(void)bundleLoadMuch {
NSLog(@"第一种方案:开始读取");
for (int index = 0; index != 101; index++) {
@autoreleasepool {
NSString *imageName = [NSString stringWithFormat:@"live_level_star_%02d", index];
NSString *imagePath = [[NSBundle mainBundle] pathForResource:imageName ofType:@"png"];
NSData *data = [NSData dataWithContentsOfFile:imagePath];
[_imgDataList addObject:data];
}
}
NSLog(@"第一种方案:完成读取");
}
二、把多张图片合并成GIF,再读取:
-(void)bundleLoadOneGif {
NSLog(@"第二种方案:开始读取");
if (1) {
_imgDataList = [[NSMutableArray alloc] init];
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"gifhome_200x200" ofType:@"gif"];
NSData *data = [NSData dataWithContentsOfFile:imagePath];
[_imgDataList addObject:data];
}
NSLog(@"第二种方案:完成读取");
}
三、把多张图片合并成Webp,再读取:
-(void)bundleLoadOneWebp {
NSLog(@"第三种方案:开始读取");
if (1) {
_imgDataList = [[NSMutableArray alloc] init];
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"start" ofType:@"webp"];
NSData *data = [NSData dataWithContentsOfFile:imagePath];
[_imgDataList addObject:data];
}
NSLog(@"第三种方案:完成读取");
}
三种方案测试数据:
第一种方案执行时间为30ms,CPU占用率为48%
第二种方案执行时间为2ms,CPU占用率为25%
第三种方案执行时间为1ms,CPU占用率为7%
结论:
优先使用读取一个文件(GIF或者WebP)的方式,第二种方案和第三种方案的区别,我理解应该为文件大小的区别,同样的一个动图,WebP图是要比GIF图小
WebP:WebP是Google近几年推出的新型网络图片格式,有静态和动态两种类型,其中静态webp比jpg和png的压缩率都要大,而且失真率接近于png,远胜于jpg,因为他支持8位的透明通道。在无损压缩的情况下,比png要小28%左右。而动态webp比gif好了不止一两点,gif只支持2位的透明通道,而且图片锯齿严重。