iOS 图片加载方式对比

作者: 果哥爸 | 来源:发表于2022-10-11 10:36 被阅读0次

    一. 引言

    我们做启动优化和卡顿优化的时候,发现图片通过不同的加载方式,加载时长相差巨大,尤其在低端机型(iPhone6iPhone7iPhone8系列)上,不同方式的图片加载,加载时间可以相差10几倍-几十倍不等,相差至少一个数量级。

    试想一下,如果你做某个需求,添加了一些图片的加载,而这个图片加载耗时比较大,直接影响了启动时长和卡顿率,导致稳定性数据有大的下降,到时领导对你的印象和后期绩效评估,估计都会有影响。

    因此充分了解图片加载的不同方式之间优缺点,加载的过程是非常有必要,有利于我们针对不同场景采用不同加载方式来提升项目稳定性。

    我们都知道图片加载主要有三种方式:

    • 放在Assets.xcassets里面管理,然后通过imageNamed方法进行加载
    • 放在bundle里面通过imageNamed方法进行加载
    • 放在bundle里面通过imageWithContentsOfFile方式进行加载

    这里我们对三种图片的加载速度进行一个对比,并分析下原因:

    二. 实验

    这里分别选了两组图片:

    • 一组是图片都是大图,大小在1.5M-4M之间,分辨率都是在1920*1080及以上。

      image.png
    • 另一组是小图,大小在1k-4k之间,分辨率在60*60左右。

    然后分别将两组图片,放在Assets.xcassetsmain bundle里面。

    image.png

    放在main bundle的所有图片,加上前缀local

    image.png

    然后在FJFImageLocalLoadVC里面创建三个按钮分别是:

    • 放在Assets.xcassets管理通过 imageNamed来加载图片的Asset imageName按钮
    • 放在bundle管理通过 imageNamed来加载图片的文件夹 imageName按钮
    • 放在bundle管理通过 imageWithContentsOfFile来加载图片的文件夹 contentOfFile按钮

    每次启动,点击一个按钮,循环去加载对应的图片,并输出每张图片的加载耗时:

    1. 大图实验数据

    A. 用Assets.xcassets管理通过 imageNamed加载

    2022-09-03 16:18:11.412898+0800 FJFBlogProjectDemo[15202:794425] --------Asset catalog加载图片 函数耗时:7.09605 ms
    2022-09-03 16:18:11.414388+0800 FJFBlogProjectDemo[15202:794425] --------Asset catalog加载图片 函数耗时:0.95403 ms
    2022-09-03 16:18:11.415612+0800 FJFBlogProjectDemo[15202:794425] --------Asset catalog加载图片 函数耗时:0.86498 ms
    2022-09-03 16:18:11.416765+0800 FJFBlogProjectDemo[15202:794425] --------Asset catalog加载图片 函数耗时:0.79906 ms
    2022-09-03 16:18:11.417784+0800 FJFBlogProjectDemo[15202:794425] --------Asset catalog加载图片 函数耗时:0.71502 ms
    2022-09-03 16:18:11.418706+0800 FJFBlogProjectDemo[15202:794425] --------Asset catalog加载图片 函数耗时:0.64099 ms
    2022-09-03 16:18:11.419683+0800 FJFBlogProjectDemo[15202:794425] --------Asset catalog加载图片 函数耗时:0.72193 ms
    2022-09-03 16:18:11.420537+0800 FJFBlogProjectDemo[15202:794425] --------Asset catalog加载图片 函数耗时:0.59795 ms
    2022-09-03 16:18:11.421399+0800 FJFBlogProjectDemo[15202:794425] --------Asset catalog加载图片 函数耗时:0.60701 ms
    2022-09-03 16:18:11.422386+0800 FJFBlogProjectDemo[15202:794425] --------Asset catalog加载图片 函数耗时:0.73600 ms
    2022-09-03 16:18:11.422987+0800 FJFBlogProjectDemo[15202:794425] --------Asset catalog加载图片 函数耗时:0.30601 ms
    2022-09-03 16:18:11.424036+0800 FJFBlogProjectDemo[15202:794425] --------Asset catalog加载图片 函数耗时:0.81706 ms
    
    

    B. 用bundle管理通过 imageNamed加载

    2022-09-03 16:19:55.879618+0800 FJFBlogProjectDemo[15217:795488] --------文件 imageName加载图片 函数耗时:141.64495 ms
    2022-09-03 16:19:55.886850+0800 FJFBlogProjectDemo[15217:795488] --------文件 imageName加载图片 函数耗时:6.81698 ms
    2022-09-03 16:19:55.892923+0800 FJFBlogProjectDemo[15217:795488] --------文件 imageName加载图片 函数耗时:5.73993 ms
    2022-09-03 16:19:55.897756+0800 FJFBlogProjectDemo[15217:795488] --------文件 imageName加载图片 函数耗时:4.54497 ms
    2022-09-03 16:19:55.900638+0800 FJFBlogProjectDemo[15217:795488] --------文件 imageName加载图片 函数耗时:2.71297 ms
    2022-09-03 16:19:55.902903+0800 FJFBlogProjectDemo[15217:795488] --------文件 imageName加载图片 函数耗时:2.18391 ms
    2022-09-03 16:19:55.905131+0800 FJFBlogProjectDemo[15217:795488] --------文件 imageName加载图片 函数耗时:2.14791 ms
    2022-09-03 16:19:55.907324+0800 FJFBlogProjectDemo[15217:795488] --------文件 imageName加载图片 函数耗时:2.11704 ms
    2022-09-03 16:19:55.909492+0800 FJFBlogProjectDemo[15217:795488] --------文件 imageName加载图片 函数耗时:2.09796 ms
    2022-09-03 16:19:55.911705+0800 FJFBlogProjectDemo[15217:795488] --------文件 imageName加载图片 函数耗时:2.13397 ms
    2022-09-03 16:19:55.913859+0800 FJFBlogProjectDemo[15217:795488] --------文件 imageName加载图片 函数耗时:2.08092 ms
    2022-09-03 16:19:55.916220+0800 FJFBlogProjectDemo[15217:795488] --------文件 imageName加载图片 函数耗时:2.28393 ms
    
    

    C. 用bundle管理通过 imageWithContentsOfFile加载

    2022-09-03 21:39:53.313360+0800 FJFBlogProjectDemo[18445:937441] --------文件 imageWithContentsOfFile加载图片 函数耗时:122.10906 ms
    2022-09-03 21:39:53.317499+0800 FJFBlogProjectDemo[18445:937441] --------文件 imageWithContentsOfFile加载图片 函数耗时:3.84998 ms
    2022-09-03 21:39:53.321495+0800 FJFBlogProjectDemo[18445:937441] --------文件 imageWithContentsOfFile加载图片 函数耗时:3.74699 ms
    2022-09-03 21:39:53.325367+0800 FJFBlogProjectDemo[18445:937441] --------文件 imageWithContentsOfFile加载图片 函数耗时:3.62003 ms
    2022-09-03 21:39:53.329069+0800 FJFBlogProjectDemo[18445:937441] --------文件 imageWithContentsOfFile加载图片 函数耗时:3.44801 ms
    2022-09-03 21:39:53.332854+0800 FJFBlogProjectDemo[18445:937441] --------文件 imageWithContentsOfFile加载图片 函数耗时:3.51596 ms
    2022-09-03 21:39:53.336646+0800 FJFBlogProjectDemo[18445:937441] --------文件 imageWithContentsOfFile加载图片 函数耗时:3.54803 ms
    2022-09-03 21:39:53.340615+0800 FJFBlogProjectDemo[18445:937441] --------文件 imageWithContentsOfFile加载图片 函数耗时:3.70693 ms
    2022-09-03 21:39:53.344022+0800 FJFBlogProjectDemo[18445:937441] --------文件 imageWithContentsOfFile加载图片 函数耗时:3.15106 ms
    2022-09-03 21:39:53.346476+0800 FJFBlogProjectDemo[18445:937441] --------文件 imageWithContentsOfFile加载图片 函数耗时:2.30098 ms
    2022-09-03 21:39:53.348315+0800 FJFBlogProjectDemo[18445:937441] --------文件 imageWithContentsOfFile加载图片 函数耗时:1.73199 ms
    2022-09-03 21:39:53.349933+0800 FJFBlogProjectDemo[18445:937441] --------文件 imageWithContentsOfFile加载图片 函数耗时:1.54901 ms
    
    

    2. 小图实验数据

    A. 用Assets.xcassets管理通过 imageNamed加载

    2022-09-03 16:25:07.374076+0800 FJFBlogProjectDemo[15271:798689] --------Asset catalog加载图片 函数耗时:4.29296 ms
    2022-09-03 16:25:07.375350+0800 FJFBlogProjectDemo[15271:798689] --------Asset catalog加载图片 函数耗时:0.88501 ms
    2022-09-03 16:25:07.375836+0800 FJFBlogProjectDemo[15271:798689] --------Asset catalog加载图片 函数耗时:0.23699 ms
    2022-09-03 16:25:07.376785+0800 FJFBlogProjectDemo[15271:798689] --------Asset catalog加载图片 函数耗时:0.75495 ms
    2022-09-03 16:25:07.377780+0800 FJFBlogProjectDemo[15271:798689] --------Asset catalog加载图片 函数耗时:0.76401 ms
    2022-09-03 16:25:07.378743+0800 FJFBlogProjectDemo[15271:798689] --------Asset catalog加载图片 函数耗时:0.72801 ms
    2022-09-03 16:25:07.379187+0800 FJFBlogProjectDemo[15271:798689] --------Asset catalog加载图片 函数耗时:0.20504 ms
    2022-09-03 16:25:07.379620+0800 FJFBlogProjectDemo[15271:798689] --------Asset catalog加载图片 函数耗时:0.25606 ms
    2022-09-03 16:25:07.380062+0800 FJFBlogProjectDemo[15271:798689] --------Asset catalog加载图片 函数耗时:0.27001 ms
    2022-09-03 16:25:07.380984+0800 FJFBlogProjectDemo[15271:798689] --------Asset catalog加载图片 函数耗时:0.73600 ms
    2022-09-03 16:25:07.383440+0800 FJFBlogProjectDemo[15271:798689] --------Asset catalog加载图片 函数耗时:2.22194 ms
    2022-09-03 16:25:07.384820+0800 FJFBlogProjectDemo[15271:798689] --------Asset catalog加载图片 函数耗时:1.15597 ms
    
    

    B. 用bundle管理通过 imageNamed加载

    2022-09-03 16:27:19.256526+0800 FJFBlogProjectDemo[15289:800441] --------文件 imageName加载图片 函数耗时:189.96501 ms
    2022-09-03 16:27:19.266366+0800 FJFBlogProjectDemo[15289:800441] --------文件 imageName加载图片 函数耗时:9.21297 ms
    2022-09-03 16:27:19.273456+0800 FJFBlogProjectDemo[15289:800441] --------文件 imageName加载图片 函数耗时:6.66499 ms
    2022-09-03 16:27:19.278714+0800 FJFBlogProjectDemo[15289:800441] --------文件 imageName加载图片 函数耗时:4.87900 ms
    2022-09-03 16:27:19.283533+0800 FJFBlogProjectDemo[15289:800441] --------文件 imageName加载图片 函数耗时:4.44400 ms
    2022-09-03 16:27:19.287708+0800 FJFBlogProjectDemo[15289:800441] --------文件 imageName加载图片 函数耗时:3.83902 ms
    2022-09-03 16:27:19.290927+0800 FJFBlogProjectDemo[15289:800441] --------文件 imageName加载图片 函数耗时:2.94399 ms
    2022-09-03 16:27:19.292683+0800 FJFBlogProjectDemo[15289:800441] --------文件 imageName加载图片 函数耗时:1.63591 ms
    2022-09-03 16:27:19.294186+0800 FJFBlogProjectDemo[15289:800441] --------文件 imageName加载图片 函数耗时:1.41799 ms
    2022-09-03 16:27:19.295716+0800 FJFBlogProjectDemo[15289:800441] --------文件 imageName加载图片 函数耗时:1.43397 ms
    2022-09-03 16:27:19.296240+0800 FJFBlogProjectDemo[15289:800441] --------文件 imageName加载图片 函数耗时:0.44703 ms
    2022-09-03 16:27:19.296694+0800 FJFBlogProjectDemo[15289:800441] --------文件 imageName加载图片 函数耗时:0.39005 ms
    
    

    C. 用bundle管理通过 imageWithContentsOfFile加载

    2022-09-03 16:27:42.501943+0800 FJFBlogProjectDemo[15295:801035] --------文件 imageWithContentsOfFile加载图片 函数耗时:160.00700 ms
    2022-09-03 16:27:42.507223+0800 FJFBlogProjectDemo[15295:801035] --------文件 imageWithContentsOfFile加载图片 函数耗时:4.72999 ms
    2022-09-03 16:27:42.511637+0800 FJFBlogProjectDemo[15295:801035] --------文件 imageWithContentsOfFile加载图片 函数耗时:3.99196 ms
    2022-09-03 16:27:42.515078+0800 FJFBlogProjectDemo[15295:801035] --------文件 imageWithContentsOfFile加载图片 函数耗时:3.05498 ms
    2022-09-03 16:27:42.517940+0800 FJFBlogProjectDemo[15295:801035] --------文件 imageWithContentsOfFile加载图片 函数耗时:2.53499 ms
    2022-09-03 16:27:42.520895+0800 FJFBlogProjectDemo[15295:801035] --------文件 imageWithContentsOfFile加载图片 函数耗时:2.61807 ms
    2022-09-03 16:27:42.524116+0800 FJFBlogProjectDemo[15295:801035] --------文件 imageWithContentsOfFile加载图片 函数耗时:2.92397 ms
    2022-09-03 16:27:42.525691+0800 FJFBlogProjectDemo[15295:801035] --------文件 imageWithContentsOfFile加载图片 函数耗时:1.39809 ms
    2022-09-03 16:27:42.526938+0800 FJFBlogProjectDemo[15295:801035] --------文件 imageWithContentsOfFile加载图片 函数耗时:1.10292 ms
    2022-09-03 16:27:42.528083+0800 FJFBlogProjectDemo[15295:801035] --------文件 imageWithContentsOfFile加载图片 函数耗时:1.03700 ms
    2022-09-03 16:27:42.528171+0800 FJFBlogProjectDemo[15295:801035] --------文件 imageWithContentsOfFile加载图片 函数耗时:0.01800 ms
    2022-09-03 16:27:42.528236+0800 FJFBlogProjectDemo[15295:801035] --------文件 imageWithContentsOfFile加载图片 函数耗时:0.01597 ms
    
    

    从以上的实验数据,我们取十次数据的平均值来看,我们可以得出以下几个结果:

    • 相同图片,用bundle管理通过 imageNamed加载,耗时最多,无论是首次加载还是非首次。

    • 其次是用bundle管理通过 imageWithContentsOfFile加载耗时第二,首次加载耗时跟用bundle管理通过 imageNamed加载相差不大,非首次加载耗时为用bundle管理通过 imageNamed加载的耗时一半左右。

    • Assets.xcassets管理通过 imageNamed加载耗时最小,跟其他两者相比,都有至少1个量级的差距,无论是首次加载还是非首次加载。

    因此从这个结果,可以得出如下几个问题:

    • 为什么Assets.xcassets管理通过 imageNamed加载耗时最少,用bundle管理通过 imageWithContentsOfFile加载耗时第二,用bundle管理通过 imageNamed加载,耗时最多。
    • 为什么放在bundle无论是通过imageNamed还是imageWithContentsOfFile来加载,为什么首次加载耗时都如此大。

    三. 分析

    带着上面的两个疑问,我们通过抓捕堆栈和阅读源码等来分析,为什么三种加载方式会产生差异的原因。

    3. 用Assets.xcassets管理通过 imageNamed加载图片

    以下是通过InstrumentsTime Profiler获取到的用Assets.xcassets管理通过 imageNamed加载图片堆栈。

    Assets.xcassets管理通过 imageNamed首次加载图片:

    image.png

    Assets.xcassets管理通过 imageNamed非首次加载图片:

    image.png

    从堆栈我们可以看出imageNamed加载方法实际上调用的是一个叫做UIAssetManager的类,每个Bundle会有一个UIAssetManager,它有一个strong-strongNSMapTable的属性,用来做缓存,这个可以参考SDImageAssetManager

    因此这里可以大概推断下用Assets.xcassets管理通过 imageNamed加载图片过程:

    流程图.jpg

    备注:
    rendition是 CoreUI.framework 对某一图像资源的不同样式的统称,如@1x,@2x,每一个rendition有一个renditionKey与之对应,renditionKey包含了不同的attribute,用于记录图片资源的参数.
    CUIMutalbeStructuredThemeStore与CUIStructuredThemeStore,可以理解为可变和不可变的图像集,包含了不同的图像资源。

    从上面的分析我们也可以知道,用Assets.xcassets管理通过 imageNamed加载图片,首次加载图片之所以耗时比较多的原因:

    • 首次加载,需要去打开并加载Assets.car文件,涉及到I/O操作
    • 需要UIAssetManager的初始化操作

    那为什么通过Assets.car加载图片资源,会比直接加载从bundle上加载耗时少至少一个量级呢?

    这就需要了解下.car文件:

    .xcassets里面的所有资源在编译过程结束后会编译为.car文件,而.car文件实际上是一种特殊的bom文件,而bom(Bill of Materials)是从NeXTSTEP继承下来的一种文件格式:

    iOSmacOS操作系统,会通过私有库CoreUI.framework来解析car文件,中间会调用Bom.framework的接口来解析BOM.

    我们可以通过在命令行输入: assetutil -I Assets.car, 查看Assets.car文件内部结构

    assetutil -I Assets.car
    [
      {
        "Appearances" : {
          "UIAppearanceAny" : 0
        },
        "AssetStorageVersion" : "Xcode 13.4 (13F17a) via AssetCatalogSimulatorAgent",
        "Authoring Tool" : "@(#)PROGRAM:CoreThemeDefinition  PROJECT:CoreThemeDefinition-520\n",
        "CoreUIVersion" : 738,
        "DumpToolVersion" : 738.1,
        "Key Format" : [
          "kCRThemeAppearanceName",
          "kCRThemeLocalizationName",
          "kCRThemeScaleName",
          "kCRThemeIdiomName",
          "kCRThemeSubtypeName",
          "kCRThemeGlyphWeightName",
          "kCRThemeGlyphSizeName",
          "kCRThemeDimension2Name",
          "kCRThemeDimension1Name",
          "kCRThemeDeploymentTargetName",
          "kCRThemeDisplayGamutName",
          "kCRThemeDirectionName",
          "kCRThemeSizeClassHorizontalName",
          "kCRThemeSizeClassVerticalName",
          "kCRThemeGraphicsClassName",
          "kCRThemeMemoryClassName",
          "kCRThemeIdentifierName",
          "kCRThemeElementName",
          "kCRThemePartName",
          "kCRThemeStateName",
          "kCRThemeValueName"
        ],
        "MainVersion" : "@(#)PROGRAM:CoreUI  PROJECT:CoreUI-738.1\n",
        "Platform" : "ios",
        "PlatformVersion" : "11.0",
        "SchemaVersion" : 2,
        "StorageVersion" : 17,
        "ThinningParameters" : "optimized <idiom 1> <subtype 1792> <scale 2> <gamut 1> <graphics 6> <graphicsfallback (5,4,3,2,1,0)> <memory 4> <deployment 7> <hostedIdioms (4)>",
        "Timestamp" : 1662280005
      },
      {
        "AssetType" : "Image",
        "BitsPerComponent" : 8,
        "ColorModel" : "RGB",
        "Colorspace" : "srgb",
        "Compression" : "deepmap2",
        "DeploymentTarget" : "2019",
        "Encoding" : "ARGB",
        "Idiom" : "universal",
        "Name" : "little_icon_1",
        "NameIdentifier" : 1592,
        "Opaque" : false,
        "PixelHeight" : 60,
        "PixelWidth" : 60,
        "RenditionName" : "little_icon_1.png",
        "Scale" : 1,
        "SHA1Digest" : "C161BEAD4ABCF455C8DFA2EF7901CF40EF40F2A5",
        "SizeOnDisk" : 334,
        "State" : "Normal",
        "Template Mode" : "automatic",
        "Value" : "Off"
      },
    
    

    从解析出来的json我们可以看出,这个json里面存储图片的所有基本信息,比如名称,宽高、大小,倍数,编码类型,压缩类型,颜色空间等。

    我们知道加载图片,不仅要加载图片的二进制数据,还要加载图片相关的基本信息,这里通过Asset.car来加载,可以在将Asset.car解析之后,直接获取到图片的基本信息和加载图片的二进制。

    A. 用Assets.xcassets管理通过 imageNamed首次加载为什么耗时相对较大原因

    • 首次加载,需要去打开并加载Assets.car文件,涉及到I/O操作
    • 需要UIAssetManager的初始化操作

    B. 用Assets.xcassets管理通过 imageNamed加载为什么耗时相对最小

    • Assets.xcassets编译形成的.car文件里面的资源信息是提前编译好的,当加载完.car文件解析之后,可以直接通过图片名称从.car文件解析后文件去定位读取图片属性和图片资源,没有多余操作。

    4. 用bundle管理通过 imageNamed加载

    以下是通过InstrumentsTime Profiler获取到的用bundle管理通过 imageNamed加载图片的堆栈。

    bundle管理通过 imageNamed首次加载图片的堆栈:

    image.png image.png

    bundle管理通过 imageNamed非首次加载图片的堆栈:

    image.png

    通过这个调用堆栈,我们可以看出用bundle管理通过 imageNamed加载图片的过程如下:

    bundle管理通过 imageNamed加载图片.jpg

    从这个加载过程,我们可以分析出如下结论:

    A. 用bundle管理通过 imageNamed加载首次加载为什么耗时这么大

    • 首次加载,需要去打开并加载Assets.car文件,涉及到I/O操作
    • 需要UIAssetManager的初始化操作
    • 需要去初始化读取图片文件的相关环境,比如创建Reader_AVCI,加载CMPhotoSymbols等读。

    B. 为什么bundle管理通过 imageNamed加载图片耗时比用Assets.xcassets管理通过 imageNamed加载图片大(非首次)

    • Assets.xcassets编译形成的.car文件里面的资源信息是提前编译好的,可以直接定位去读取图片属性和图片资源,没有多余操作。
    • bundle的图片加载,需要先去Assets.car里面查询,由于图片资源并不再Assets.car里面,所以在获取renditionrenditionKey时多次调用canGetRenditionWithKeycanGetRenditionWithKey函数里面的通过renditionKey生成keySignature是一个copy操作和位操作,比较耗时,而且从从CUIMutableStructuredThemeStore的字典中取出rendition的操作添加了线程锁,导致耗时也相对高,由于图片资源并不再Assets.car,因此再重新通过mmap加载读取图片资源文件,形成renditionrenditionKey,总体耗时就比Assets.xcassets管理图片资源加载耗时高很多。

    5. 用bundle管理通过 imageWithContentsOfFile加载

    以下是通过InstrumentsTime Profiler获取到的用bundle管理通过 imageNamed加载图片堆栈。

    bundle管理通过 imageWithContentsOfFile首次加载图片的堆栈:

    image.png

    bundle管理通过 imageWithContentsOfFile非首次加载图片的堆栈:

    image.png

    通过这个调用堆栈,我们可以看出用bundle管理通过 imageWithContentsOfFile加载图片的过程如下:

    bundle管理通过 imageWithContentsOfFile加载图片.jpg

    从这个加载过程,我们可以分析出如下结论:

    A. 用bundle管理通过 imageWithContentsOfFile加载首次加载为什么耗时这么大

    • 首次加载,需要去初始化读取图片文件的相关环境,比如创建Reader_AVCI,加载CMPhotoSymbols等操作。

    B. 为什么bundle管理通过 imageWithContentsOfFile加载图片耗时比用bundle管理通过 imageWithContentsOfFile加载图片小(非首次)

    • bundle管理通过 imageWithContentsOfFile加载图片不需要去Assets.car里面查询,没有生成renditionrenditionKey的相关操作和缓存操作,只有读取图片属性和图片资源的操作耗时。

    四. 总结

    1. 为什么Assets.xcassets管理通过 imageNamed加载耗时最少,用bundle管理通过 imageWithContentsOfFile加载耗时第二,用bundle管理通过 imageNamed加载,耗时最多。

    • Assets.xcassets编译形成的.car文件里面的资源信息是提前编译好的,当加载完.car文件解析之后,可以直接通过图片名称从.car文件解析后文件去获取图片属性和读取图片资源,没有多余操作。

    • bundle管理通过 imageWithContentsOfFile加载图片不需要去Assets.car里面查询,没有生成renditionrenditionKey的相关操作和缓存操作,只有读取图片属性和图片二进制的操作耗时

    • bundle管理通过 通过imageName的图片加载,需要先去Assets.car里面查询,由于图片资源并不再Assets.car里面,所以在获取renditionrenditionKey时多次调用canGetRenditionWithKeycanGetRenditionWithKey函数里面的通过renditionKey生成keySignature是一个copy操作和位操作,比较耗时,而且从从CUIMutableStructuredThemeStore的字典中取出rendition的操作添加了线程锁,导致耗时也相对高,由于图片资源并不再Assets.car,因此再重新通过mmap加载读取图片属性和图片资源,形成renditionrenditionKey,总体耗时最大。

    2. 为什么放在bundle无论是通过imageNamed还是imageWithContentsOfFile来加载,为什么首次加载耗时都如此大。

    • 首次加载,需要去初始化读取图片文件的相关环境,比如创建Reader_AVCI,加载CMPhotoSymbols等操作。

    五. 引用

    Humble Assets Catalog
    iOS拾遗—— Assets Catalogs 与 I/O 优化

    相关文章

      网友评论

        本文标题:iOS 图片加载方式对比

        本文链接:https://www.haomeiwen.com/subject/amjgartx.html