-
Notifications
You must be signed in to change notification settings - Fork 820
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Helper for responsive images #24
Comments
@mullens has kindly volunteered to work on a design doc for this one and was interested in hacking on it. (Lucas I've sent you an invite to the repo so we can get you assigned once accepted) :) |
Talked to @mullens about status. A few docs have been worked on trying to explore the design. We're going to try to nail down some milestones around this work we can aim for shortly. |
@mullens when you get a chance, could we share an external friendly copy of the research + conclusions you reached and the next steps forward? ⭐️ |
@mullens ended up implementing a proof-of-concept of this idea and is going to keep iterating on it as time allows. We're going to close this issue up as it was explored and will continue looking at how that piece fits into the overall workbox collection next. |
@addyosmani any idea? |
I'm going to reopen this as we never did end up shipping anything, and it's come up again recently. |
From my perspective it'd be a great addition to workbox to access the network information API as based on the results regarding the user's connection it'd be trivial to return optimised images. Here's what I'm thinking: I am using Cloudinary to store my images and Cloudinary has a feature which allows developers to return images in the most optimised way - for example if the user accesses the site via Chrome it returns a WebP image. Now, it'd be great if I could further control this and say, if the user is accessing the site via Chrome and from a 2G or a 3G connection, return a WebP with a quality of 40 for faster load, whereas if they have a 4G connection I wouldn't care much about the quality but still would return the WebP. Based on this approach I could also cache the appropriate files - for 2G users, cache a lower quality version of the image using Workbox. |
@tpiros, what's the mechanism for requesting specific formats/qualities of images in Cloudinary? Is it URL query parameters, headers, or something else? |
@jeffposnick it's based on the URL. So for example here's a full image https://res.cloudinary.com/idemo/image/upload/woman.jpg and here's https://res.cloudinary.com/idemo/image/upload/q_20/woman.jpg a lower quality version (quality reduced by 80%) |
Gotcha. Well, if you want to experiment, here's some completely untested code that I threw together which might be a starting point: const cloudinaryPlugin = {
requestWillFetch: async ({request}) => {
// Proof-of-concept with hacky URL manipulation.
const urlParts = request.url.split('/');
let newPart;
// Client hints, etc. could also be consulted.
switch ((navigator && navigator.connection) ? navigator.connection.effectiveType : '') {
case '4g':
newPart = 'q_40';
break;
case '3g':
newPart = 'q_30';
break;
case'2g':
case 'slow-2g':
newPart = 'q_20';
break;
default:
// Come up with some sort of reasonable default.
newPart = 'q_30';
break;
}
const newUrl = urlParts
.splice(urlParts.length - 1, 0, newPart)
.join('/')
// Hacky JPG => PNG replacement. Maybe check for WebP?
.replace('.jpg', '.png');
const newRequest = new Request(newUrl.href, {headers: request.headers});
// I'm assuming Cloudinary supports CORS?
// Forcing the image requests to use CORS would avoid opaque response
// storage bloat: https://stackoverflow.com/a/39109790/385997
newRequest.mode = 'cors';
return newRequest;
},
};
workbox.routing.registerRoute(
// This RegExp could also be published in a module,
// if there's a canonical one to use.
new RegExp('^https://.+\.cloudinary\.com'),
workbox.strategies.cacheFirst({
cacheName: 'cloudinary-images',
plugins: [
// Add in the cloudinaryPlugin.
cloudinaryPlugin,
// Mix in any of the other plugins.
workbox.expiration.Plugin({
maxEntries: 50,
purgeOnQuotaError: true,
}),
],
})
); The nice thing is that this plugin is just building on top of the standard request/response lifecycle events that Workbox exposes, and doesn't have to do anything "official" to register with Workbox or anything. If Cloudinary thinks that code along those lines would be useful for your users (and it seems like it would be!) you could publish your plugin, and folks can just mix it in to their current Workbox code.
That's a very valid use case that we haven't had time to work on. We've been using #155 for discussion. |
@jeffposnick sorry for the late response - this looks great. I will give this a go. At the moment I'm juggling a few projects but will get to this as well and update you. I do like this approach. It's a similar one to what I saw here: https://deanhume.com/dynamic-resources-using-the-network-information-api-and-service-workers/ |
@jeffposnick I tried your example (with a few changes) but unfortunately I couldn't get it working. The reason is that I can't seem to be able to modify the Request. I saw in the Workbox docs that I should be able to ("
I added a few log statements to print the URL and the old and new requests and as you can see the requests are the same even though the URL has changed
Here's the corresponding code - I am assigning the new URL to the new request. console.log('new url ', final);
const newRequest = new Request(request);
newRequest.url = final;
newRequest.mode = 'cors';
console.log('request', request);
console.log('newRequest', newRequest);
return newRequest; Any thoughts? |
Actually I think I figured it out: const newUrl = new URL(final);
console.log(new Request(newUrl.href, {headers: request.headers})); // this now returns the right URL
return new Request(newUrl.href, {headers: request.headers}); |
@tpiros Oops, sorry about the Glad that things are working, and looking forward to seeing this publicized a bit! |
I'm going to close this as https://www.npmjs.com/package/cloudinary-workbox-plugin exists for Cloudinary, and I think that model works best—instead of Workbox's official repo hosting provider-specific plugins, providers can publish their own. |
Could you create helper for responsive images using DPR + WebP?
Check out this resources...
The text was updated successfully, but these errors were encountered: