Image Optimization at Grailed, Part 2: The Refactor (React Hooks)

Scott McCreary
Grailed Engineering
2 min readDec 9, 2019

A few months ago we rethought how we optimize our images at Grailed. Like true software developers, we decided to redo the whole thing 6 months later.

To recap, the problem we were trying to solve was this:

<img src="" />

An image tag? What’s wrong with that? Well, over the years, as we tried to make the site faster while preserving the quality of our images, we noticed a few things:

  • The images were unnecessarily big for mobile devices, causing mobile web to be slow.
  • The images were too small for desktop, causing those same images to look blurry.
  • We weren’t taking advantage of next-gen image formats like webp, which gives you the same image quality for half the size on Chrome and Firefox.

Our “one size fits all” approach wasn’t working. The right image would depend on a few variables:

  • How big is the device?
  • Is webp supported?

Our original solution involved compositions of several shared stateful components. It was a great example of the Higher Order component pattern in React, but it was pretty inscrutable for the next developer.

A few months after the first article, we upgraded React to include the version with Hooks. And, well… they’re better! And more “scrutable.” So we refactored. What follows is a slightly simplified version of the code we use to handle device size changes and image format support to build that perfect src.

React Hooks

Let’s start from the inside and work out. Here’s a Hook we can use anywhere to return whether webp is supported:

Here’s a function we can call to get the current device as a string, like “laptop” or “mobile”:

… and here’s a Hook to call the above function and return the current device whenever the window size changes:

Finally, we can combine these in a Hook that takes an src and a set of options from the developer, watches for changes to device and webpSupport, and returns that perfectsrc :

buildSrcwill depend on the API you’re using. We use Filepicker, so our optimized srcs end up looking something like filepicker.com/<id>/width:420/output=format:webp

And now we can useSrchowever we’d like:

Now our images are optimized, responsive, and maybe a bit friendlier to the next developer. If you see a blurry image on the site, let us know! If you know how to fix it, even better. Until next time!

--

--