iOS 如何优化项目

最近公司需要优化项目,但一时间无从下手,于是查阅了资料,对优化点进行了总结:
iOS 如何优化项目
  • 结构与架构
    • 文件目录分类
      • 以一个基础的电商项目来解释,4个tabbarItem对应着四大模块,首页、分类、购物车、个人中心,往下每个还可以细分为MVC+Session层
      • 按项目架构来分: 最外层为Model、View、Controller、Session层,内部才是业务模块
    • 第三方库管理
      • 手动管理
        手动维护各种第三方库,适合于已经趋于稳定、极少Bug的三方库
      • CocoaPods
      • Carthage
        这里更推荐使用Carthage,因为它对项目的侵入性最小,而且是去中心化管理,不需要等待漫长的pod update / install过程.不过各有各的好处,使用CocoaPods简单粗暴,基本不需要额外设置什么,看自己需求吧
    • 项目架构
      • MVC
      • MVVM
      • MVP
      • 响应式编程框架(如 ReactiveCocoa或者RxSwift)
  • 崩溃&性能调优
    1. 代码规范,定期code review了吗
    2. 复杂列表的滚动时FPS可以保持在60帧左右吗?
    3. 页面加载渲染的耗时能不能进一步减小?
    4. 网络缓存有做吗,UIWebView / WKWebView的常用静态资源做缓存了吗
    5. App的启动时间可以在保持最小业务逻辑的同时再减小一点吗
    • UITest & UnitTest
      当开发完新需求的时候,在提测之前我们最好编写下UITest和UnitTest,覆盖主业务流程即可,可以提高我们的提测质量,减小一些可见的Bug,再加上冒烟用例,最大程度上提高我们提测的质量(成为KPI之王),而且上线之后这些单元测试和UITest组件的脚本可以配合自动化测试定期进行回归测试,提高App的质量,减少崩溃率
    • NullSafe
      @implementation NSMutableDictionary (NullSafe)
      - (void)swizzleMethod:(SEL)origSelector withMethod:(SEL)newSelector
      {
      Class class = [self class];
      Method originalMethod = class_getInstanceMethod(class, origSelector);
      Method swizzledMethod = class_getInstanceMethod(class, newSelector);
      BOOL didAddMethod = class_addMethod(class,
      origSelector,
      method_getImplementation(swizzledMethod),
      method_getTypeEncoding(swizzledMethod));
      if (didAddMethod) {
      class_replaceMethod(class,
      newSelector,
      method_getImplementation(originalMethod),
      method_getTypeEncoding(originalMethod));
      } else {
      method_exchangeImplementations(originalMethod, swizzledMethod);
      }
      }
      + (void)load {
      static dispatch_once_t onceToken;
      dispatch_once(&onceToken, ^{
      id obj = [[self alloc] init];
      [obj swizzleMethod:@selector(setObject:forKey:) withMethod:@selector(safe_setObject:forKey:)];
      });
      }
      - (void)safe_setObject:(id)value forKey:(NSString *)key {
      if (value) {
      [self safe_setObject:value forKey:key];
      }else {
      NullSafeLogFormatter(@"[NSMutableDictionary setObject: forKey:], Object cannot be nil")
      }
      }
      这种解决方法可以避免诸如数组取值越界、字典传空值、removeObjectAtIndex等错误
      ​​
    • 监控系统
      目前大多数App都集成了第三方统计库,常见的比如腾讯的Bugly、友盟的U-App等等
      • CPU、内存、FPS记录及保存
        `CPU`、`FPS`、`Memory占用`网上都有现成的方法获取到这三个参数,这三个属于性能监控,可以定时记录,比如10S记录一次到本地文件中,每次打开App上传昨天的日志。这就要自己制定日志上传的策略了
      • 卡顿日志收集
      • 从容崩溃,上传崩溃日志
      • 性能调优&App体验优化
        • 懒加载的利与弊
          懒加载适用于一些可能不会加载的页面,比如弹框、空数据页面之类的,使用得当可以避免内存暴涨,使用不好,比如在必定会弹出的页面中使用懒加载可能会在增加页面响应时间,所以使用懒加载一定要注意使用场景,避免产生副作用
        • 避免使用重绘
          重写 drawRect 或者 drawReact:inContext方法会默认创建一个图层上下文,图形上下文所需要的内存为图层宽 * 图层高 * 4字节,图层每次进行重绘时都需要抹掉内存重新分配,会产生巨大的性能开销
        • App体验优化
          • UITableViewCell 使用不当造成滑动卡顿
          • 大量cornerRadius和maskToBounds一起使用造成的离屏渲染造成的性能问题
          • 网络请求操作没有任何状态展示,比如加载框、按钮置灰等
          • 网络请求没有进行缓存
  • 网络请求优化
    • 请求压缩
      DNS查询之后是TCP握手建立连接,并发送请求数据。对于TCP来说,单个IP包大小受限于MSS值,大部分用户所处网络环境下每个包的大小约在1.5KB,新建立的HTTP连接由于TCP的slow start特性,会导致本地的部分IP包本临时缓存,从而增加了整体request的延迟。所以我们应该尽可能尝试去压缩我们的网络请求业务数据,减少一个Request的IP包数量,或许可以让用户少经历一个RTT,降低请求延迟的用户感知
    • 请求合并
      对于非关键性的业务数据,或者对实时性要求不高的请求来说,通过合并请求的方式可以减少和服务器交互的次数,一则降低服务器压力,二则合并之后再压缩能节约客户端的流量。这类请求一般见于打点SDK,crash日志收集等非业务型请求
    • 合理的并发数
      有些业务场景会出现多个Request集中产生的情况,此时我们需要设置一个合理的并发数。并发数如果太小,会导致“劣质”的请求block住“优质”的请求。如果并发数太大,带宽有限的场景下,会增加请求的整体延迟
    • 请求成功率监控
    • 网络请求缓存优化
      适用场景:一些更新频率较低的场景:比如个人中心
      关于网络请求缓存,App端的网络请求对面到后端更多的是增删改查,这个方面需要和后端配合,是否资源改变即后端是否需要重新检索或修改数据,这个时候我们就需要一个value比如时间戳Last-Modified或者标识ETag来告知服务器自己当前的资源标记,目前常用的策略为:
      以时间戳Last-Modified为例
      App端第一次请求接口,服务端返回成功,HTTP Status为200,并且在返回的Header中用Last-Modified表明服务器中该资源最后被修改的时间
      App端第二次请求该接口,Header中传递本地缓存的Header中的Last-Modified,如果服务器端的资源并未发生变化,则会返回HTTP Status为304,我们直接可以使用本地的缓存,传输流量更少,相对而言,用户的等待时间会更短
  • #来自 http://www.jianshu.com/p/71f90b4bf6d9 http://mrpeak.cn/blog/ios-network/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值