iconfont

时下App越来越向重型App发展,随之带来的就是App容量剧增。

而App中五花八门,各式各样的图标图片也是容量增大的帮凶之一。

而使用iconfont代替图片可以缓解这一问题。

了解iconFont

iconFont是什么?

是一种使用字体文件取代图片文件,来展示图标/特殊字体等元素的方法.

为什么iconFont比图片占用更少的内存?

这要从计算机绘制图片的两种方式来分析。

位图(详情点击查看):亦称点阵图像或绘制图像,是由称作像素(图片元素)的单个点组成的。这些点可以进行不同的排列和染色以构成图样。当放大位图时,可以看见赖以构成整个图像的无数单个方块。扩大位图尺寸的效果是增大单个像素,从而使线条和形状显得参差不齐。然而,如果从稍远的位置观看它,位图图像的颜色和形状又显得是连续的。

矢量图(详情点击查看):也称为面向对象的图像或绘图图像,在数学上定义为一系列由线连接的点。矢量文件中的图形元素称为对象。每个对象都是一个自成一体的实体,它具有颜色、形状、轮廓、大小和屏幕位置等属性。

矢量图是根据几何特性来绘制图形,矢量可以是一个点或一条线,矢量图只能靠软件生成,文件占用内在空间较小,因为这种类型的图像文件包含独立的分离图像,可以自由无限制的重新组合。它的特点是放大后图像不会失真,和分辨率无关,适用于图形设计、文字设计和一些标志设计、版式设计等。

iconFont的优缺点

优点

1、图片统一管理,避免png分散管理带来的不便

2、占用内存小、占用存储空间小

缺点

1、只支持纯色图片

2、开发过程,所见即所得方面,对于研发不够友好,需要借助映射表

使用方法

通过阿里巴巴矢量图标库制作自己的iconFont字体

1、打开阿里巴巴矢量图标库,添加自己的项目

2、搜索或自制矢量图标上传

3、将图标添加到购物车

4、将购物车中的图标添加到自己的项目中

5、选择打包方式为Font class 并下载

6、将 .ttf 后缀字体文件拖入工程中,并在demo_unicode中查询到字体对应的Unicode码 将ttf文件拖入iOS工程

iOS代码实现

1、注册字体文件

+ (void)registerFontWithURL:(NSURL *)url {
    NSAssert([[NSFileManager defaultManager] fileExistsAtPath:[url path]], @"Font file doesn't exist");
    CGDataProviderRef fontDataProvider = CGDataProviderCreateWithURL((__bridge CFURLRef)url);
    CGFontRef newFont = CGFontCreateWithDataProvider(fontDataProvider);
    CGDataProviderRelease(fontDataProvider);
    CTFontManagerRegisterGraphicsFont(newFont, nil);
    CGFontRelease(newFont);
}

2、生成image对象

+ (UIImage*)imageWithIcon:(NSString*)iconCode inFont:(NSString*)fontName size:(NSUInteger)size color:(UIColor*)color

{

 CGSize imageSize = CGSizeMake(size, size);

 UIGraphicsBeginImageContextWithOptions(imageSize, NO, [[UIScreen mainScreen] scale]);

 UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, size, size)];

 label.font = [UIFont fontWithName:fontName size:size];

 label.text = iconCode;

 if(color)

 {

 label.textColor = color;

 }

 [label.layer renderInContext:UIGraphicsGetCurrentContext()];

 UIImage *retImage = UIGraphicsGetImageFromCurrentImageContext();

 return retImage;

}

iOS性能测试结果统计

滚动视图绘制1000个图片,分别使用png和iconfont做性能对比。

截图时:

1、iconfont均是第一次完成注册、出图。

2、均是相应case的第一次上屏。

iconfont未做缓存

图片尺寸 PNG iconfont
32 * 32 Simulator Screen Shot - iPhone 11 - 2020-07-21 at 17.43.17-w414 Simulator Screen Shot - iPhone 11 - 2020-07-21 at 17.42.29-w414
64 * 64 Simulator Screen Shot - iPhone 11 - 2020-07-21 at 17.43.27-w414 Simulator Screen Shot - iPhone 11 - 2020-07-21 at 17.42.49-w414
200 * 200 Simulator Screen Shot - iPhone 11 - 2020-07-21 at 17.43.34-w414 Simulator Screen Shot - iPhone 11 - 2020-07-21 at 17.43.06-w414
     

iconfont做了缓存

图片尺寸 PNG iconfont
32 * 32 Simulator Screen Shot - iPhone 11 - 2020-07-21 at 19.14.48-w414 Simulator Screen Shot - iPhone 11 - 2020-07-21 at 19.13.50-w414
     
64 * 64 Simulator Screen Shot - iPhone 11 - 2020-07-21 at 19.14.42-w414 Simulator Screen Shot - iPhone 11 - 2020-07-21 at 19.14.04-w414
200 * 200 Simulator Screen Shot - iPhone 11 - 2020-07-21 at 19.14.33-w414 Simulator Screen Shot - iPhone 11 - 2020-07-21 at 19.14.14-w414

Android性能测试结果统计

数据基于同一个设备HUAWWEI NOVA4和同样的图标(常规大小)测试。

对比项 加载TTF 渲染iconfont图标 渲染jpg图片 结论
耗时 3ms icon1:3ms icon100:5ms JPG1:4ms JPG100:40ms 1、通过iconfont加载多个图标本质上还是通过TextView渲染多个字符串,对耗时影响大; 2、加载JPG图片的过程需要重复解析渲染相对比较耗时。
内存(包含控件加载) 所消耗内存依赖TTF字体包大小 icon1:峰值0.4M icon100:峰值0.8M JPG1:0.8M JPG100:2M 1、控件初始化设置TextView typeFace字体对内存影响不大; 2、多个icon和图片同时渲染对内存消耗影响不大,过程中有个峰值,完成后随即内存会得到释放; 3、通过TextView设置typeFace可以同时加载多个icon,通过ImageView加载图片只能是一对一加载;

image2020-7-31_14-53-6.png

小结:

1、iconfont第一次完成注册、出图时,内存消耗较多。

2、iconfont不做缓存,耗时较长。

3、iconfont做了缓存,和png完成1000张图绘制时耗时相近。

4、ttf文件不大的情况下可以考虑缓存,用空间换时间。