Speed Up your React App Using Cloudinary and Lazy Loading
Problem?
According to Neil Patel, akamai.com and Gomez, about 40% of people abandon a website if it takes more than 3 seconds to load. What’s more, half of the web users expect to load the content within 2 seconds!
There are a few elements that can slow down a website and cause that ‘effect’, let’s focus on one thing at the time — images.
This is how can you handle the images so they load faster and don’t slow down the page:
- Downsize larger images to the size needed by your design — even on the desktop, there is no need to go for the biggest image possible.
- Remove metadata from delivered images — by default images contain a lot of information useful for cameras and graphics applications, but not for your web users.
- Format images to newer formats like JPEG-XR and WebP — common formats like PNG, JPG or GIF are not optimized to be sent wireless.
- Lower image quality — many images have an extra-high resolution, however, it’s possible to lower quality without any significant visual impact.
- Use lazy loading — allow your images to wait with download until user scrolls down to them, it can really shorten page initialization.
- Hold a position of element — so the page doesn’t jump while the images load.
- Use the “Blur-up” technique — show a very low-resolution image before the original loads.
- On small devices downsize the image even more — mobiles usually have a slower Internet connection, and on small screens, users don’t need super high resolutions.
Optimizing images manually could be a real torture. But hey, as Bobby McFerrin says ‘don’t worry’ — there is a ready band-aid for you.
Solution!
Cloudinary
Using Cloudinary API resolves most of our problems. Making a long story short, Cloudinary manages your media assets in the cloud. It covers all the hard work listed in our problematic points from 1 to 4 above. You can see Cloudinary.
We just need to create a component that handles points 5 to 8.
React-Cloudinary-lazy-image
When Cloudinary is doing their work, we can focus on ours. Let’s handle lazy loading by using the React-Cloudinary-lazy-image.
- It allows us to start the image download only when the element is within a user's screen.
- Of course, we don’t want our page to jump, so it thinks about rendering a placeholder.
- What’s more, it would be cool not to have an empty space waiting for the image. We can either set some background colour or load a very small version of the original image.
- At last, we can create breakpoints in order to have different sizes on different screens adding source set to image tags.
Example 1
Have a look at this code:
import React from 'react'
import Img from ‘react-cloudinary-lazy-image’export const LazyImage = () => (
<Img
cloudName={‘CloudName’}
imageName={'black-hole'}
fixed={{
width: 800,
height: 600
}}
alt={'black_hole'}
/>
)
And here is the result:
This is an example of a fixed version of the component. It’s made for cases where the image won’t change its size on smaller screens. To handle it properly, height and width should be set in a fixed property. The cloudName and imageName params are passed directly to Cloudinary. First is just a cloud name, and second is public id in Cloudinary assets. To have all set, it’s good practice to pass alt property as well.
Example 2
On the other hand, it’s common to have a full-width picture on the website. A fixed-size asset won’t solve the problem, so there is a fluid version. The fluid parameter takes an object with one or two keys, maxWidth is required and defines the max size of the picture, which will be than scale down, both width and height. However, often images stay the same of similar height despite screen width. To have it constant you can also pass height key.
All values in both image types should be numbers in pixels.
This is the code example:
<Img
cloudName={‘CloudName’}
imageName={'black-hole'}
fluid={{
maxWidth: 800,
height: 300
}}
alt={'black_hole'}
/>
Customizable
React-Cloudinary-lazy-image can handle multiple parameters to give you full control over your pictures.
Styles
- style — define style to wrapper component
- imgStyle — define style of img element
- placeholderStyle — define the style of placeholder img element
- backgroundColor — when set, instead of ‘blur up’ effect desired colour is displayed
- fadeIn — have a fading effect when the original image is showing up
Cloudinary
- urlParams — Cloudinary can take many image transformation params. Set what you need in string format, ex.: ‘g_center,c_scale,r_max`
- imgFormat — it’s image transformation format parameter, but it’s quite important and has own prop in the component
- quality — Cloudinary quality parameter, same as above
Callbacks
- onLoad -> callback when the original image is loaded
- onError -> callback when image failed to load