Feasibility of Including ~600 SVG Images in Connect IQ App

I'm developing my first Connect IQ app and looking for some guidance on handling a large number of images efficiently.

The app is designed to display a sequence of SVG images — potentially up to around 600 in total (each ranging from 2KB to 20KB). Currently, I'm listing all the images in drawables.xml and assigning the Rex.Drawable.ImageIds to arrays that users can scroll through.

Here's the relevant snippet for how I'm currently displaying each frame:

bmpId = frames[_frameIndex];
_curImage = null;
_curImage = WatchUi.loadResource(bmpId);
dc.drawBitmap(0, 0, _curImage);

I've tested the app successfully with 60 images so far, but before I scale up, I have a few questions:

  • Are all images loaded into memory at app start, or are they loaded on demand?

  • Is it technically feasible to include around 600 images in a Connect IQ app?

  • Are there best practices or optimizations I should consider to handle this more efficiently?

Any insights or suggestions would be much appreciated. Thanks!

  • 1. svg is converted to pixel format during compilation

    2. adding lot of files (bytes) is OK, it'll take more time for users to download and occupy more on their device, but it should probably work

    3. Not sure about drawables, but with strings there's a 255 limit. If there's no such limit for drawables, then it shouldn't matter how many you have.

    4. You load them with loadResource. Just don't hold on to their reference for long. Of course you'll only be able to keep a few of them in the memory at a time.

    But unless your app is called Depleate Battery Fast I would not recommend doing that... Loading and rendering 600 images will just kill the battery IMHO.

    What exactly are you trying to do? Display a movie?

  • #3 - Isn't the 255 limit in strings for older watches only?

    Which makes me ask a relevant question for the OP - are you aiming at the more recent watches only? As this has more likelihood of succeeding

  • 4. You load them with loadResource. Just don't hold on to their reference for long. Of course you'll only be able to keep a few of them in the memory at a time.

    To clarify this, on CIQ 4 devices, loadResource will load resources into the shared graphics pool, not your app's memory.

    e.g. pre-CIQ 4:

    var b = loadResource(Rez.Drawables.someBitmap); // b is a Bitmap which is loaded into app memory and freed when there are no more references to the object

    CIQ 4 and higher:

    var b = loadResource(Rez.Drawables.someBitmap); // b is a BitmapReference which points to bitmap that's loaded into the shared graphics pool, which is automatically managed by the system. If you want to lock the resource in the graphics pool, you can call b.get()

    [https://developer.garmin.com/connect-iq/core-topics/graphics/#graphicspool]

    Some devs have found that the graphics pool may actually be a disadvantage when loading large numbers of bitmaps simultaneously (I don't have any experience with this myself):

    [https://forums.garmin.com/developer/connect-iq/f/discussion/328086/how-to-force-system-to-not-using-graphics-pool]

  • _curImage = WatchUi.loadResource(bmpId);
    dc.drawBitmap(0, 0, _curImage);

    If you are loading bitmaps in onUpdate and onUpdate is firing once per second, this will be a huge CPU/battery drain on the device, as storage is extremely slow. Not only may the user notice the battery drain, but the user may also notice general sluggishness during updates (e.g. the watch may be slow to respond to button presses).

    iirc, Garmin tends to suggest loading resources in other functions, like onLayout() or onShow(), which aren't being called constantly.

    Ofc it may be unavoidable to load images regularly since you have 600, but maybe you could try loading 10 at a time, once every 10 seconds / updates, for example?