skip to Main Content

We are working on optimizing the size of our app, and there is something we can’t figure out. It looks like Xcode includes rasterized versions of our SVG images, increasing the size of our app significantly.

Given these steps:

  1. Create a project from scratch in Xcode 15 (or 14.2)
  2. Add an SVG in the .xcassets with "Single Scale" and "Preserve Vector data" (like this one, notice it’s 9KB)
  3. Select Team and then Archive
  4. Export AdHoc and select a device to do the App Thinning (I usually use iPhone 14)
  5. Change .ipa to .zip, decompress .zip and "Show Package Contents" in .app
  6. Notice Assets.car size, over 100KB
  7. Run xcrun --sdk iphoneos assetutil --info Assets.car and check the json, notice there is a vector image, but also images @1x and @3x, adding up over 90KB (because these are not vectors)

Why is Xcode adding rasterized images in the .car apart of the vectorial one? This is increasing our app size some MBs (we have many SVGs), which I think is unnecessary and goes against the idea of using vectors in my opinion.

Does someone have a clue why is this happening? Thanks!

2

Answers


  1. A common misconception is that iOS 13 added native support for SVG images in asset catalogs. This is not correct.

    What was made available in Xcode 12 was the ability to add SVGs to asset catalogs and have the relevant raster image variants created at build time.

    iOS 13 (and the relevant versions of macOS, tvOS) released in 2020 have the ability to identify the correct raster image when an SVG is referred to. This is why there is a requirement to target iOS 13 as a minimum when using SVGs, not because of any native support for SVGs.

    As with adding PDFs to asset catalogs, adding SVGs is primarily a way of simplifying workflow and removing the potential of adding an incorrect resolution as a variant.

    There are 3rd party frameworks available with varying levels of SVG support that may meet your needs or you can go back to manually rasterising your images and adding the variants directly which will give you more control over image properties.

    Depending on the minimum iOS level and (therefore the oldest devices) you are targeting you may not require all variants of your images.

    Login or Signup to reply.
  2. I also wanted to replace my PDFs with SVGs (mostly to simplify sharing with sister Android apps). Goals/requirements were to keep performance great for scrolling through hundreds of images, resolution great for one-at-a-time large image viewing, minimise deployed app bundle size, and ideally use SVGs.

    TLDR: I’m sticking with just PDFs, using the Xcode generated PNGs for scrolling thumbnails quickly and also using the "Preserve Vector Data" setting so I can show much larger versions of the images without compromising image quality.

    Along the way I found the following, using Xcode 15.4:

    • providing ONLY a PDF results in Xcode building smaller PNGs than Xcode re-processing supplied PNGs. Xcode converted my PDF to a 20k @3x PNG (versus, see further down, Xcode converted my "hand tweaked" 17k PNG file to 21k)
    • providing ONLY a SVG results in Xcode building LARGER PNGs than providing a PDF (@3x was 27k vs 20k with the identical PDF)
    • supplying "hand tweaked" @1x, @2x and @3x PNGs (only) for both iPhone and iPad, not specified as Universal, resulted in Xcode growing the files (e.g. a 17k @x3 file became 21k)
    • supplying an SVG and individual @1, @2 and @3 PNG files resulted in Xcode displaying the following error, but everything worked as expected "Image set has a child with bitmap content and the "Any" scale. The image set also has children with specific scales and content. Please remove the content with specific scales or change the content of the "Any" scale to vector content."
    • supplying a PDF and individual @1, @2 and @3 files removed the error, but as the PNG files were growing in size per above (e.g. a 17k @x3 file became 21k) we didn’t go this route
    • a build setting COMPRESS_PNG_FILES that would disable this Xcode PNG processing is still documented by Apple but no longer appears in Xcode so we didn’t explore this
    • some likely outdated information on Xcode’s PNG processing is provided by imageoptim

    Here’s the Xcode settings we’re using now in case it helps. The image is a PDF file.

    enter image description here

    Related, there’s some magical (undocumented) things happening in the iOS Image apis. With some experimentation, on iOS 17.5 and iOS 15.6.1, it was possible to force iOS to use the vector image instead of the generated PNGs (we did this by asking for larger sized images than the PNGs). It seems if you ask for a smaller image than an available PNG, then the PNG is used and scaled down. If you ask for a larger image then it uses the vector. Performance was inconclusive. It seemed to be (only?) 20-30% slower to render the vector images, but we also hit layout issues and decided we’d done enough before we properly separated everything out. (Measuring performance is hard!). Note that we could find no simple way to stop Xcode from generating PNGs entirely which also complicated measurements.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search