自如首创iOS图片资源极致优化方案(一)

5,238

背景

iOS开发过程中对资源的管理业界没有给出一个优质方案,于是大项目通过不断迭代都会遇到包体过大的情况。包体瘦身便有了百家争鸣的局面,瘦身的矛头都指向了导致包体暴增的大boss:资源!但是没有一个方案是可以解决病根的,自如另辟蹊径,开创了资源管理系统新途径,并成功拿到3项相关技术专利

资源管理通常遇到的问题

这里的前提是工程已经组件化,不同组件通过路由管理,组件间0耦合,组件管理使用cocoapod

问题的产生原因

在日常开发中,我们接到需求之后如果有图片就会导入到工程,如果这个图片经过迭代废弃了,很多人是不会主动去删除的,因为开发人员是不知道这个图片是不是在其他地方有人在用,删了可能引起严重丢图bug!所有,业界很少有人主动删图,因此大量废弃图片导致包体日益增加

业界通常遇到的问题

问题:组件A里面有图片 x、y、z,组件B里面有q、r、x,这时候图片怎么管理? 方案1:把图片和组件放在一起做成pod组件来使用,无论是通过bundle还是通过xcasset,都会出现图片x重复。很多第三方都是这么做,比如阿里的: 16244379346304.jpg 这里面有俩问题 1,图片可能和其他组件重复 2,图片如果包含2x和3x,在出包的时候slicing就不会使用,xcasset本身在安装到具体手机的时候会自动选择使用2x还是3x,使用bundle或者指定asset目录的形式会使苹果的这一优化失效;另外,苹果会对xcasset里的png图片进行最优压缩,这一特性也会失效,从而导致包体无法缩减到最优状态

方案2:使用一个独立图片组件,这个组件包括工程中所有的图片 许多工程优化过程中经常会经过这个阶段,所有图片都放到一个pod组件库里面,作为一个基础组件使用,这样就可以解决图片重复问题,而且图片可以统一管理和统一压缩,基本趋于完美的状态。例如:组件A用到图片 x、y、z,组件B用到q、r、x,图片组件M包含 x、y、z、q、r,这样只需要A依赖M,B依赖M,最终打包的时候仅包含这5张图片就可以实现需求,图片也没有重复 这里存在一个问题 1,如果公司还有另一个项目P1,P1需要用到B组件,这时候P1就会引入5张图片!如果按需索取的话,应该仅仅引入q、r、x即可,这样直接打破了组件跨app使用的通用性,资源完全耦合到这一个app里了!

16244390071539.jpg 如果把所有图片都放主工程xcasset里,结果和方案2是一样的

自如资源管理无敌方案

简单来说,资源资源管理无敌方案就是云端管理图片和组件之间的关系,统计图片使用次数,云控3个月没有使用记录的图片

16244397063915.jpg

以上是整体架构图,里面涉及到许多技术后面会慢慢讲,先说下这里如何解决的问题以及本方案的优势

1,一般方案中图片重复的问题,本方案图片和组件建立一对一关系,通过云端统一管理,不会出现重复问题 2,一般方案中的xcasset特性和slicing问题,本方案在打包期间实时从云端拉取图片,生成xcasset之后导入到工程,这些优质特性都会生效 3,一般方案中跨app使用问题,本方案图片和组件一对一对应,可以随意迁移到其他app,而不会缺少图片或图片重复

由此可见,云端管理系统可以解决市面上一般方案引起的一系列问题,除了解决这些问题之外,还可以统计图片使用次数,根据使用次数来评估废弃图片;另外,云端管理图片可以延伸为管理资源,plist、音视频、webp等资源

自如资源管理系统研发历程

图片管理一期

图片一期属于头脑风暴的开始,奠定了资源管理的基础

我们要解决的难点一共俩:

  1. iOS图片一般使用UIImage imageNamed 同步方式读取图片,云端管理之后如何不改变使用方式的情况下异步下载图片来使用
  2. 如何找出每个组件对应哪些图片

第一个问题是主要问题,如果实现不了异步下载图片和不改变原有使用方式,图片管理这个事情就无法推动,图片管理方案也就失去了意义。好在最终我们找到了方案!这个功能我们放到了图片二期的时候来做,图片一期主要解决问题2

找出工程中所有使用的图片,包括图片名称是拼接的、图片名是服务端控制的、图片名是个变量等

找工程中的图片几种方法:

  1. 根据查找使用API的方式定位,比如:UIImage imageNamed
  2. 导出工程中所有的图片资源作为工程中使用的图片

我们使用的组件化方案是采用pod管理各个组件的,组件的图片资源有的是放组件里的、有的是通过图片组件统一管理的、也有直接放主工程xcasset里的,因此,我们面临如何统计图片资源的问题。

统计工程中的所有图片方法:

  1. 导出工程使用的所有图片到一个文件夹下(使用脚本批量处理)
  2. 每条业务线负责的组件都创建一个image_manager.txt文件,存放本组件使用到的图片。(这步有丢失图片的可能,因为有些图片可能是变量拼接的,由于人工疏忽而没有写入到image_manager.txt,但是测试阶段很容易发现问题)
  3. 我们要管理的资源定位是自研组件,因此无需考虑第三方图片的情况

主工程作为特殊的组件处理,给主工程起一个工程ID名称,比如ios_ziroom,主工程组件的名称就是工程ID名称。这样主工程就可以跟组件一样的处理和图片之间的关系,每个组件收集完image_manager.txt之后,用脚本在打包的时候汇总所有的image_manager.txt文件内容,并且除重,得到的结果和工程中搜索到的资源进行对比,没差异之后说明统计的图片名称和资源都能对上号了,这些工作是为了资源云管理做的准备。

后期我们会对资源管理系统进行继续详细分享

自如大前端研发中心招募新同学! FE/IOS/Android工程师看过来

公司福利有: 全额五险一金,并额外购买商业保险 免费健身房+年度体检 公司附近租房9折优惠 每年2次晋升机会

办公地点:北京酒仙桥普天实业科技园 欢迎对技术有执着热爱的你加入我们!简历请投递 lich7@ziroom.com