PreRender - React / React Native
PreRender
A concept of rendering the upcoming component in advance, to prevent the user from waiting.
Understanding PreRender
Think of tinder view for swiping pictures. Let’s say these images are huge in size a few MegaBytes. Now if you want to render each image after the user has swiped over the current one, the image is gonna load for few seconds before displaying it actually (eg: 2 seconds for each image to be rendered). Any user is going to lose patience by this slow rendering experience.
<img src={current_image} />
Now how can I solve this problem?
Use two image slots instead of one. Initially load the first image’s data and render in slot one as usual. Now here comes the trick with the second one. Instead of waiting till the user swipes and then loading the image, Start rendering the image immediately after the first image is assigned to slot one.
By doing so we are not blocking the current image from being visible but instead render the next one in advance. Now we hide the pre-rendered image from user either using hide className or setting to height 0px in case of React Native.
Treating data as an array of two elements and keeping track of active index we can decide which data to fetch and which one to display.
onSwipe() {
// make pre-render the active imageconst availableSlot = this.state.active;
if (this.state.active === 0) {
this.setState({ active: 1 });
} else {
this.setState({ active: 0});
}// now start fetching the next image and assign it to the availableSlot const images = this.state.images;
images[availableSlot] = newImage;
this.setState({ images });
}render() {
return (
<div>
{
this.state.images.map((image, index) => {
return (<img
src={image}
key={index}
style={{ height: this.state.active === index ? '100%' : 0
}} />);
});
}
</div>
);
}
If you take a closer look, actually we are taking advantage of react’s ability to avoid re-render of a component when the key remains same for same dataset. So we have set key={index} even though it’s not suggested.
Efficiency
Previously assuming the rendering a each image took t seconds and the user was viewing the image for x seconds. The total time spent only on waiting for n images to render will be n * t seconds.
But with pre-render in place, the user has to just wait for t seconds which was for the first image and every other image loads during the view time of x seconds.
Irrespective of any number of images we will always end up with t render time given that the user views every image more than the rendering time (x > t).
Note: It need not be explicitly images that has to be pre-rendered. Any component whose data is known upfront can be pre-rendered.
Upgrade
By scaling Array to n elements we can also support multiple slots, out of which you can choose one to display next. eg: Having three slots and based on swipe direction choose the active slot and the available slots to replace data.
you can also support back / previous this way without fetching and rendering the data from server again. Obviously there are better pre-rendering algorithms but this gives a basic idea.
Awesome ❤, Now we have achieved high performance user interfaces. We have similar use cases in product views on e-commerce, images on photo gallery, etc..