When rendering the image, see if there’s a BlurHash generated. If so, render a component passing the BlurHash to it:
<blurhash-image blurhash="L78;My-@ngE0R6t9s,WUIoIUWBxu"></blurhash>. (I don’t want to SSR the rendered image because the generated PNG file is several times larger than the BlurHash. For example, the Blurhash
L78;My-@ngE0R6t9s,WUIoIUWBxurendered to 16x16 PNG image resulted in a data URL that’s 800+ bytes long)
The client-side component then renders the BlurHash on the page.
This 3rd step went almost smoothly, but it turns out the client side components are not initialized until the main Vue app is loaded and being hydrated into the DOM.
Therefore, I decided to extract the component into an HTML Custom Element.
This custom element should be small enough to be inlined into the web page.
This resulted in this
<blurhash-image> Web Component.
It is distributed as a 2.7 KB (minified and gzipped) snippet that would make the
Tooling: I decided to use TSDX for ease-of-development. I don't want to configure Rollup and stuff by myself. I encountered a few issues though:
The resulting bundle is larger than it needs to be because classes are transpiled down to ES5. This is fixed by adding
package.json. I used
"since 2018 and not dead". I'm sure there are better strings that I could use, but since this element is designed to be run on its own
<script>tag (not bundled), any incompatibilities that arises will not bring the whole webpage down with it (graceful degradation).
HTML snippet: I want to put the HTML snippet right inside README file. This is a good time to try out
markdown-magic. I like that it made self-updating Markdown files much easier, but don’t like that, as of v1.0.0, processors must all be synchronous...