You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
So I've recently created a website using next.js for a client and everything has gone fairly smooth. There has been some slight issue with images taking longer than 1 second to load due to the initial cold startup and multiple cache "MISS". After a couple of days of the site running, things started to smooth out with a few images sometimes taking around 400ms to load due to a cache "STALE". Through testing I believe I have an idea as to how next/image is handled in the background. I've looked through the code and I think I have some idea as to how it works, but I'm hoping someone is able to confirm this.
From what I believe is happening, every request with a "src", "q", "w" are handled as a single image request meaning that the origin image is fetched every single time when the transformed image is not present in the cache. I assume that the fetch request only happens for absolute images an not relative images (relative should be read using "fs" I assume?). For examples
src=/example.png&w=32&q=50 -> get transform cache -> MISS -> fetch origin image -> set transform cache -> response
src=/example.png&w=64&q=50 -> get transform cache -> MISS -> fetch origin image -> set transform cache -> response
src=/example.png&w=32&q=50 -> get transform cache -> HIT -> response
If I assume that this is how next/image handles images where a fetch request has to be made for the same image when only the width has changed, would performance be improved by also caching the origin image on the server? That way the examples would look more like this.
src=/example.png&w=32&q=50 -> get transform cache -> MISS -> get origin cache -> MISS -> fetch origin image -> set origin cache -> set transform cache -> response
src=/example.png&w=64&q=50 -> get transform cache -> MISS -> get origin cache -> set transform cache -> response
src=/example.png&w=32&q=50 -> get transform cache -> HIT -> response
From testing locally with express + sharp, I found that the average "MISS" response for a large image was around 1s to 5s with a "STALE" response being around 200ms to 400ms with the old method. Using the method I described above, the average "MISS" response was reduced to around 200ms to 400ms which was almost exactly the same as the "STALE" response! (Keeping in mind that the very first request for the image would still take around 1s to 5s, but all requests with changed width/quality would only take as long as the toBuffer() method on the sharp object)
Because of my findings, I started to believe that next/image uses the first method and not the second one, but I would love to know whether or not I've made a mistake. If not, when it comes to the second method where we cache the origin image, I believe the best method for handling this would be to use the same logic currently being used for caching, with cache-control being set on the cached origin image, and transformed images having their own cache control being set in a similar fashion whenever requested.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
So I've recently created a website using next.js for a client and everything has gone fairly smooth. There has been some slight issue with images taking longer than 1 second to load due to the initial cold startup and multiple cache "MISS". After a couple of days of the site running, things started to smooth out with a few images sometimes taking around 400ms to load due to a cache "STALE". Through testing I believe I have an idea as to how next/image is handled in the background. I've looked through the code and I think I have some idea as to how it works, but I'm hoping someone is able to confirm this.
From what I believe is happening, every request with a "src", "q", "w" are handled as a single image request meaning that the origin image is fetched every single time when the transformed image is not present in the cache. I assume that the fetch request only happens for absolute images an not relative images (relative should be read using "fs" I assume?). For examples
src=/example.png&w=32&q=50 -> get transform cache -> MISS -> fetch origin image -> set transform cache -> response
src=/example.png&w=64&q=50 -> get transform cache -> MISS -> fetch origin image -> set transform cache -> response
src=/example.png&w=32&q=50 -> get transform cache -> HIT -> response
If I assume that this is how next/image handles images where a fetch request has to be made for the same image when only the width has changed, would performance be improved by also caching the origin image on the server? That way the examples would look more like this.
src=/example.png&w=32&q=50 -> get transform cache -> MISS -> get origin cache -> MISS -> fetch origin image -> set origin cache -> set transform cache -> response
src=/example.png&w=64&q=50 -> get transform cache -> MISS -> get origin cache -> set transform cache -> response
src=/example.png&w=32&q=50 -> get transform cache -> HIT -> response
From testing locally with express + sharp, I found that the average "MISS" response for a large image was around 1s to 5s with a "STALE" response being around 200ms to 400ms with the old method. Using the method I described above, the average "MISS" response was reduced to around 200ms to 400ms which was almost exactly the same as the "STALE" response! (Keeping in mind that the very first request for the image would still take around 1s to 5s, but all requests with changed width/quality would only take as long as the toBuffer() method on the sharp object)
Because of my findings, I started to believe that next/image uses the first method and not the second one, but I would love to know whether or not I've made a mistake. If not, when it comes to the second method where we cache the origin image, I believe the best method for handling this would be to use the same logic currently being used for caching, with cache-control being set on the cached origin image, and transformed images having their own cache control being set in a similar fashion whenever requested.
Beta Was this translation helpful? Give feedback.
All reactions