Create A Property Wrapper To Lazily Load Data
As suggested by @tal in #55 Boutique's performance when loading large blobs of data like an image or video can be rather underwhelming. I thought through and wrote about this in #20, but I'd like to prioritize this a feature for Boutique to support.
It seems intuitive to see Boutique and think of using it to store images, but unfortunately that can have real performance issues since those images can balloon the size of your app's memory. In fact it’s what @samalone completely reasonably attempted to do https://github.com/mergesort/Boutique/discussions/17#discussioncomment-3025556, and I'd like to offer a good solution that promises performance, avoids code duplication, and is simple.
The shape of what I'd like to build is a new @Deferred property wrapper. A @Deferred value would not immediately load it's value into memory when a Store is created, instead it would point to a DeferredValue that could be loaded upon a property's access.
This matches a feature that other databases and ORMs provide, the ability to lazy load data, or in Core Data terms this would be called faulting. Marking a property as @Deferred would be most useful when the upfront cost of loading data is high, but a user likely wouldn't notice the cost of loading an item on demand.
Building this would require three (or potentially more steps).
- Creating a new
DeferredValuetype that signals to the Store that it's ok to not load data in real time. This type would still have to maintain some reference to the underlying data, that way it can be loaded when accessed. - Creating a
@Deferredproperty wrapper which exposes the semantics ofDeferredValuewithout having to explicitly wrap every value you wish to defer in aDeferredValue. - Adding support to load a
DeferredValueon demand when reading from a Store's items, since currently all data is loaded upfront.
There may be more to do or another way of approaching this problem so I'm very open to feedback!