ember-svg-jar
ember-svg-jar copied to clipboard
Allow loading SVGs asynchronously and one by one
Would be pretty sweet, if we could have a new loading strategy, that allows us to not bundle the SVGs into the JS or some joint SVG file.
This allows us to:
- use proper caching on a per-asset basis
- only load required SVGs on-demand, thus greatly reducing initial load time
Problems:
- When do we load SVGs?
- How does the component / controller of a template know when all SVGs have been loaded?
- What if the SVG name is dynamic and changes (
{{svg-jar someVar}}
)
I would like this too. Probably so would #45.
I have some ideas based on previous work with preloading img
content.
General idea:
- user moves their svgs out of public to avoid name conflicts, sets new sourceDirs in config
- svg-jar compiles and optimises svgs like before, but instead of writing to js it writes to new svg files somewhere in the public/assets dir so they're available to browsers in the deployed app
- svg-jar downloads the svg files then displays them, like an
img
tag. Like now, but adding concurrency/async issues.
When do we load SVGs
Depends. I'd start with when the component is inserted, and not do anything smart unless the developer opts-in. For example giving them a service to preload particular svgs, so they can block and wait in their route's model hook. Or perhaps giving them a loadAll method they can put in their application route, if we can tell what "All" means – more below.
How does the component / controller of a template know when all SVGs have been loaded?
Does it need to? <img>
don't.
Preloading could be another approach: let developers load svgs in routes when they know they're going to need them. The previously mentioned service could handle this. It could also provide information about ongoing downloads without preloading, perhaps to implement a progress bar or similar.
What if the SVG name is dynamic and changes ({{svg-jar someVar}})
Ember components and computed properties should handle this nicely?
I wonder if there's a security issue though. Imaging the developer passes user data in. If {{svg-jar}}
loads up arbitrary urls then that looks like a code injection problem. If they can only pick svg file names from a pre-set list of svg names – like with the other strategies – then it's probably ok.
Any URL, or just SVGs from sourceDirs
This last point brings up a point that seems like an important fork in the road.
Should {{svg-jar}}
load arbitrary URLs, or only names from a list or manifest of svg files it processed at compile-time?
For preloading, if {{svg-jar}}
can load a svg from any path or URL then you don't know what "All" means, so best to let them state which files they're going to preload and wait for. Provide a service/API where they say what they want to display, wait for it to load (e.g. route model / loading screen), then display it from the cache.
If just using SVGs from sourceDirs – like the other strategies do – it could create a manifest file listing which svgs it processed and where to find them (relative path or url, asset fingerprinting). That list defines "all SVGs" for a loadAll method.
Manifest / any URL:
- Both can support loading up with nothing and just getting the SVGs you need for a particular page.
- With a manifest, a loadAll method in the application route model can make
{{svg-jar}}
work like inlining. - Both support caching, but fingerprinting details vary
- List/Manifest seems like a lot more work for this addon, but maybe it's already doing a lot of it
Or just let the browser do it for you? https://css-tricks.com/svg-use-with-external-reference-take-2/
<svg width="24" height="24">
<use width="24" height="24" xlink:href="/some-file-in-public-assets.svg#some-id"></use>
</svg>