iOS13 UIImage imageNamed poor performance compared to iOS12

My project will load several images using [UIImage imageNamed:] when a button is pressed, it runs smoothly under iOS12, but when I switch deploy target to iOS13, the action takes several seconds to completion which is unacceptable. (even loading 1px image become slower)

After some research, using the same .jpg image in default .xcassets , same code environment, I found that since iOS13, the default implementation of UIImage imageNamed: may have different call stacks.

the faster way
Code Block
+[UIImage imageNamed:inBundle:withConfiguration:]
+[_UIAssetManager newAssetNamed:fromBundle:]
_UIImageCollectImagePathsForPath
_UIImageCollectImagePathsForPath_block_invoke
_UIImageCollectImagePathsForPath_block_invoke_2.168
___UIImageCollectImagePathsForPath_block_invoke.155
-[NSFileManager fileExistsAtPath:]


the time consuming way
Code Block
+[UIImage imageNamed:inBundle:withConfiguration:]
-[_UIAssetManager imageNamed:configuration:]
-[_UIAssetManager imageNamed:configuration:cachingOptions:attachCatalogImage:]
78-[_UIAssetManager imageNamed:configuration:cachingOptions:attachCatalogImage:]_block_invoke
-[_UIAssetManager _lookUpObjectForTraitCollection:withAccessorWithAppearanceName:]
-[UITraitCollection _enumerateThemeAppearanceNamesForLookup:]
82-[_UIAssetManager _lookUpObjectForTraitCollection:withAccessorWithAppearanceName:]_block_invoke
78-[_UIAssetManager imageNamed:configuration:cachingOptions:attachCatalogImage:]_block_invoke_2
-[CUICatalog namedLookupWithName:scaleFactor:deviceIdiom:deviceSubtype:displayGamut:layoutDirection:sizeClassHorizontal:sizeClassVertical:appearanceName:]
-[CUICatalog _namedLookupWithName:scaleFactor:deviceIdiom:deviceSubtype:displayGamut:layoutDirection:sizeClassHorizontal:sizeClassVertical:appearanceName:]
-[CUICatalog _resolvedRenditionKeyFromThemeRef:withBaseKey:scaleFactor:deviceIdiom:deviceSubtype:displayGamut:layoutDirection:sizeClassHorizontal:sizeClassVertical:memoryClass:graphicsClass:graphicsFallBackOrder:deviceSubtypeFallBackOrder:adjustRenditionKeyWithBlock:]
-[CUICatalog _private_resolvedRenditionKeyFromThemeRef:withBaseKey:scaleFactor:deviceIdiom:deviceSubtype:displayGamut:layoutDirection:sizeClassHorizontal:sizeClassVertical:memoryClass:graphicsClass:graphicsFallBackOrder:deviceSubtypeFallBackOrder:localizationIdentifier:adjustRenditionKeyWithBlock:]
-[CUIStructuredThemeStore _canGetRenditionWithKey:isFPO:lookForSubstitutions:]
-[CUIStructuredThemeStore assetExistsForKey:]
-[CUICommonAssetStorage assetExistsForKeyData:length:]
_os_unfair_lock_lock_slow
ulock_wait

In the later way, ulock_wait is one of the heaviest methods.

I made some efforts, like dispatching imageNamed: to global queue, but nothing helps. I have no clues how to make it call the faster way.

Under iOS12, the call stack is as below
Code Block
+[UIImage imageNamed:inBundle:withConfiguration:]
-[_UIAssetManager imageNamed:configuration:]
-[_UIAssetManager imageNamed:configuration:cachingOptions:attachCatalogImage:]
-[_UIAssetManager imageNamed:configuration:cachingOptions:attachCatalogImage:]_block_invoke
-[_UIAssetManager _lookUpObjectForTraitCollection:withAccessorWithAppearanceName:]
-[UITraitCollection _enumerateThemeAppearanceNamesForLookup:]
-[_UIAssetManager _lookUpObjectForTraitCollection:withAccessorWithAppearanceName:]_block_invoke
-[_UIAssetManager imageNamed:configuration:cachingOptions:attachCatalogImage:]_block_invoke_2
-[CUICatalog namedVectorGlyphWithName:scaleFactor:deviceIdiom:layoutDirection:glyphSize:glyphWeight:glyphPointSize:appearanceName:]
-[CUICatalog _resolvedRenditionKeyFromThemeRef:withBaseKey:scaleFactor:deviceIdiom:deviceSubtype:displayGamut:layoutDirection:sizeClassHorizontal:sizeClassVertical:memoryClass:graphicsClass:graphicsFallBackOrder:deviceSubtypeFallBackOrder:adjustRenditionKeyWithBlock:]
-[CUICatalog _private_resolvedRenditionKeyFromThemeRef:withBaseKey:scaleFactor:deviceIdiom:deviceSubtype:displayGamut:layoutDirection:sizeClassHorizontal:sizeClassVertical:memoryClass:graphicsClass:graphicsFallBackOrder:deviceSubtypeFallBackOrder:localizationIdentifier:adjustRenditionKeyWithBlock:]
-[CUIStructuredThemeStore copyLookupKeySignatureForKey:]

it's much faster than iOS13
The difference is between those 2 lines
iOS 13:
  • [CUICatalog _namedLookupWithName:scaleFactor:deviceIdiom:deviceSubtype:displayGamut:layoutDirection:sizeClassHorizontal:sizeClassVertical:appearanceName:]

iOS 12:
  • [CUICatalog namedVectorGlyphWithName:scaleFactor:deviceIdiom:layoutDirection:glyphSize:glyphWeight:glyphPointSize:appearanceName:]

But I cannot find any reference to this private API.

Are there ny information about the images that could explain (try png format ?)
The image is 60px square jpg, very common file type. This problem only occurs on my iPhone7 Plus, not on my iPhoneXS. I think it only happens on old devices.
Updated:
under iOS13, I found only on iPhone7 Plus (not on XS), it calls -[CUIStructuredThemeStore _canGetRenditionWithKey:isFPO:lookForSubstitutions:] which is a hight cost API.
Any information about that?




iOS13 UIImage imageNamed poor performance compared to iOS12
 
 
Q