webp-in-css
webp-in-css copied to clipboard
Not compatible with SSR
Well, this library is not SSR compatible, and there are only two reasons why not:
READMEtells to add it to theheadorbundle, while it has to be inlined just afterbodytag- it uses
onLoad/onErrorhandlers which are async
Let's make it work right!
Long story short - here is working sandbox - https://codesandbox.io/s/crazy-ganguly-hmhe8
- it inlines
base64 imgbefore the body to tell the browser about it. Theimgis invisible. - it "checks"
imgsynchronously after creating, and it does work! (only with a realimgtag, preload does not help). - so it sets class to the body here and now, and the following HTML would use
webp - as long as dataURI inlined in the same document - it does not affect gzip size.
Tested
In Chrome(webp ✅), FireFox(webp ✅), and Safari(no webp, as expected)
Outcome
This library becomes SSR friendly!
Happy to open PR with a more compact version of the sandboxed example, however, the main changes are expected at the README level
Updated version, more compact, simple and sound:
<img
id="webp-checker"
style="display:none"
src="data:image/webp;base64,UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA=="
/>
<script>
document.body.classList.add(
document.getElementById("webp-checker").height === 1
? "webp"
: "no-webp"
);
</script>
Tell me more about your SSR? How do you use library in SSR? What behaviour you expect for SSR?
Don't forget to test in IE.
- given an image, which shall not be an
imgtag as long it does not have any contentual sense - given a
css
&--XXX {
background-image: url("./assets/XXX-Medium.png");
@media (min-resolution: 144dpi), (min-resolution: 1.5dppx) {
background-image: url("./assets/XXX-Large.png");
}
}
- page content is SSR-ed, so should be loaded correctly even without JS (one of the tests - disable JS at all, and applicating should work, more or less)
- as a result css should be changed to
&--XXX {
background-image: url("./assets/XXX-Medium.png");
+ :global(.webp) & {
+ background-image: url("./assets/XXX-Medium.webp");
+ }
@media (min-resolution: 144dpi), (min-resolution: 1.5dppx) {
background-image: url("./assets/XXX-Large.png");
+ :global(.webp) & {
+ background-image: url("./assets/XXX-Large.webp");
+ }
}
}
- and make
webp-in-cssworksynchronously, not to download all the images twice. In short - this is the main expectation from the library - and the initial version was working well only for CRS SPAs.
make webp-in-css work synchronously
Yeap, this is a good point. But how SSR is related to this? I am worry of missing something important here.
Well, not SSR itself, but preexisting HTML in a root cause. For SPAs, which would render their content on the client-side current behavior is ok - once they would be ready - plugin also would be ready. But for any static content coming from the server - the plugin should also do the job before a browser renders that content. So SSR is not changing the moment "when" plugin should work - always before content render, but adding one more time constraint.
Got it. You mean for static websites it is great to have synchronous detection.
Let’s test this method in IE and we are ready for PR.
- In ie it "does not work", as expected
- in Chrome always works, even if the network cache is disabled
- in FireFox does not work if dev tools are open, and network cache is disabled.
- In Safari it "does not work", as expected
- I am a bit concerned about Chome+Android+Low power mode, where it might automatically "lazy" images, but dont have any device to test.
- probably due to ^that^ onload/onerror "safety net" should be used.
In ie it "does not work", as expected
In Safari it "does not work", as expected
What is the probem?
They don't support webp? So that's not a problem at all.
Got it. Wait for PR.
But let’s keep old JS-only file for compatibility.