iOS 性能优化:包大小优化

背景

所开发的 App 包大小达到了 230M+,下载缓慢,而且使用数据下载较麻烦。

为什么要优化包大小?

首先是 Apple Store 数据下载的限制;

另外无非就是包大了,用户不愿意下载了,空间不足的时候要删除 App 第一个想到的就是删除大的 App。

怎么优化?

1. 删除无用类、无用图片

因为项目经过两次重构、多次 UI 替换,导致很多无用类和无用图片未清除。

  1. 删除无用图片资源,可以使用 LSUnusedResources

  2. 分析无用类,可以通过 AppCode 里的 Code->Inspect Code 进行静态分析;或者是找一些脚本

需要注意的是:工具可能会误判,一定要经过二次确认再去删除,防止清除后影响正常业务。

2. 重复代码抽离

举例:消息 encode、decode 重构

原先消息基类 messageContent 的公有属性,都需要在子类中 encode 和 decode 处理一遍,书写麻烦,而且代码冗余。

encode 和 decode 进行重构优化,子类只需要在 encode 的时候调用 super,然后将子类特有的值塞到 dict 中返回即可,在 decode 的时候从 dict 中取出特有的值使用即可。

优化结果

App 层 + SDK 层总计近 100 种消息,每个基于 MessageContent 的子类重复代码减少约 40 行,每个基于 MediaMessageContent 的子类重复代码再减少 11 行,大约减少 4000+ 行冗余代码,极大程度地减少新建消息子类的代码以及时间。

修改前子类代码:

objc 复制代码
///将消息内容编码成json
- (NSData *)encode {
    NSMutableDictionary *dataDict = [NSMutableDictionary dictionary];
    [dataDict setObject:self.content forKey:@"content"];
    
    if (self.extra) {
        [dataDict setObject:self.extra forKey:@"extra"];
    }

    if (self.senderUserInfo) {
        [dataDict setObject:[self encodeUserInfo:self.senderUserInfo] forKey:@"user"];
    }

    if (self.mentionedInfo) {
        [dataDict setObject:[self encodeMentionedInfo:self.mentionedInfo] forKey:@"mentionedInfo"];
    }

    NSData *data = [NSJSONSerialization dataWithJSONObject:dataDict options:kNilOptions error:**nil**];
    return data;
}

///将json解码生成消息内容
- (void)decodeWithData:(NSData *)data {
    if (data) {
        __autoreleasing NSError *error = nil;
        NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];

        if (dictionary) {
            self.content = dictionary[@"content"];
            self.extra = dictionary[@"extra"];

            NSDictionary *userinfoDic = dictionary[@"user"];
            [self decodeUserInfo:userinfoDic];

            NSDictionary *mentionedInfoDic = dictionary[@"mentionedInfo"];
            [self decodeMentionedInfo:mentionedInfoDic];
        }
    }
}

修改后子类代码:

objc 复制代码
- (NSMutableDictionary *)encodeDict {
    NSMutableDictionary *dataDict = [super encodeDict];
    [dataDict setObject:self.content forKey:@"content"];
    return dataDict;
}

- (NSDictionary *)decodeWithData:(NSData *)data {
    NSDictionary *dictionary = [super decodeWithData:data];
    self.content = dictionary[@"content"];
    return dictionary;
}

3. 图片资源压缩

图片资源使用 WebP,压缩率高,而且肉眼看不出差异,同时支持有损和无损两种压缩模式。压缩后大小分别减小 64%、19%。

图片大小超过 100KB,考虑使用 WebP,小于 100KB 时,可以对图片进行无损压缩。

需要注意的是:虽然 WebP 的图片格式更小,但是系统 API 只支持 iOS14 以上使用,低版本还需要用 sd/其他方法 解析,否则会导致显示不出来。

4. 删除合并动态库

删除合并无用的动态库

位置消息合并至主库,删除公众号、客服、客服、讨论组、翻译、位置等动态库。

5. Xcode 编译设置优化

此模块处理参考 百度APP iOS端包体积50M优化实践(一)总览

相关推荐
web1350858863518 分钟前
全面指南:使用JMeter进行性能压测与性能优化(中间件压测、数据库压测、分布式集群压测、调优)
jmeter·中间件·性能优化
早起的年轻人5 小时前
Flutter CupertinoNavigationBar iOS 风格导航栏的组件
flutter·ios
貂蝉空大7 小时前
uni-app开发安卓和ios app 真机调试
android·ios·uni-app
胖虎18 小时前
iOS 中的圆角与平滑圆角:从新特性到老项目适配
ios·圆角·平滑圆角·cornercurve
志飞8 小时前
ios UICollectionView使用自定义UICollectionViewCell
ios·collectionview·自定义cell
程序员远仔14 小时前
【Vue.js 和 React.js 的主要区别是什么?】
前端·javascript·css·vue.js·react.js·性能优化·html5
Neo Evolution14 小时前
Flutter与移动开发的未来:谷歌的技术愿景与实现路径
android·人工智能·学习·ios·前端框架·webview·着色器
敢嗣先锋1 天前
鸿蒙5.0实战案例:基于ArkUI启动冷启动过程最大连续丢帧数问题分析思路&案例
性能优化·移动开发·多线程·harmonyos·arkui·鸿蒙开发
没头脑的ht1 天前
ios App的启动过程和启动优化
ios
敲代码的鱼哇1 天前
设备唯一ID获取,支持安卓/iOS/鸿蒙Next(uni-device-id)UTS插件
android·ios·uniapp·harmonyos