Image Optimization

Building a fast web application that instantly provides joy to its users whenever it is accessed (rather than introducing delays) typically requires paying attention to a number of different components.

RONIN aims to automatically provide you with the optimizations you need to guarantee the fastest experience possible, additionally letting you fine-tune those improvements where necessary.

One of those optimizations is that images are displayed instantaneously, which RONIN ensures via a number of different features available for images (image MIME type data) stored in the Blob field type.

Image Metadata

When retrieving records that contain fields of type “Blob”, you will be provided with a value that looks similar to the following for each of those fields:

TypeScript
export interface Blob {
  key: string;
  /** The URL of the binary object. */
  src: string;
  meta: {
    /** The byte size of the binary object. */
    size: number;
    /** The pixel width of the image, if the binary object is an image. */
    width: number;
    /** The pixel height of the image, if the binary object is an image. */
    height: number;
    /** The MIME type of the binary object. */
    type: string;
  };
  /** A base64 encoded preview to display while the image is loading, if the binary object is an image. */
  placeholder: {
    base64: string;
  };
}

Image Placeholders

If you are building a web application, in order to ensure the smoothest possible experience for the people making use of your application, we strongly advice displaying a low-quality blurred version of every image, until the full image has finished loading.

Like this, you can avoid empty white gaps in your page, and instead always display something that at least remotely resembles what the image will look like, until the image is available in its entirety. At this point the image can overlay the blurred low-quality version.

When using Next.js, for example, you can easily display the placeholder like so:

TSX
<Image
  src={field.src}
  placeholder={field.placeholder.base64}
  alt="A description of the image"
  width={500}
  height={500}
/>

In order to allow the remote image to be loaded securely (when deploying to Vercel), you will need to add the following config to your next.config.js file:

TypeScript
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'storage.ronin.co',
        port: '',
        pathname: '/**',
      },
    ],
  },
};

If you aren’t using Next.js, you may render the placeholder like so:

TSX
<img src={field.placeholder.base64} />

Image Performance

To ensure that the final image finishes loading as quickly as possible, it is recommended to have its size automatically optimized by RONIN, or your deployment provider.

Other additional options can be used as well, in order to guarantee the most ideal experience possible:

  • w: The desired pixel width of the image.

  • h: The desired pixel height of the image.

  • q: The desired quality of the image (number between 1 and 100).

  • fm: The file format of the image (avif, webp, png, or jpeg).

  • fit: How the image should be fit to its frame (cover, contain, inside, outside, fill).

  • blur: The strength of a gaussian blur effect applied to the image (number between 0.3 and 1000).

Download

By default, all images are opened inside the browser when accessing them. If you wish to download them when accessing the image URL, add ?download=true or download=desired-filename.png to the URL. This will instruct browsers (set the Content-Disposition header to attachment) to download the image.

Framework Example

Since all of the options mentioned above can be provided to the src URL of the image as query string parameters, the optimization method is agnostic of any framework, meaning it works regardless of the framework, and even with vanilla HTML:

TSX
<img src={`${src}?w=200&h=400&blur=40`} />

If you’re using Next.js, you can use a custom image loader to accomplish the same:

TSX
const imageLoader = ({ src, width, quality }: { src: string; width: number; quality: number }) => {
  return `${src}?w=${width}&q=${quality || 75}`;
};
 
<Image
  src={field.src}
  placeholder={field.placeholder.base64}
  loader={imageLoader}
  alt="A description of the image"
  width={500}
  height={500}
/>;

As shown above, a placeholder prop is provided to the Image component, which contains the value of the placeholder.base64 field that is returned from RONIN when the record is retrieved. This field (as mentioned in the “Image Placeholder” section above), ensures that a blurred version of the image is loaded ahead of time, before the final image finishes loading.