Skip to content

Commit 91b9587

Browse files
authored
Merge pull request #67 from Codebrahma/blogpost_how-to-smoothly-render-images-in-react-app
Blog Post - How to Smoothly Render Images in React App?
2 parents 48908a9 + 8e2c16d commit 91b9587

File tree

6 files changed

+167
-0
lines changed

6 files changed

+167
-0
lines changed
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
---
2+
templateKey: "blog-post"
3+
title: "How to Smoothly Render Images in React App?"
4+
date: 2020-03-09
5+
featuredpost: false
6+
description: >-
7+
Improve your web apps UX by enhancing image render with React's onLoad event and simple SCSS
8+
keywords:
9+
- react
10+
- image-rendering
11+
- scss
12+
- smooth-image
13+
- ux
14+
image: ./images/smooth_image_rendering_cover.png
15+
link: /how-to-smoothly-render-images-in-react-app
16+
category:
17+
- Tutorial
18+
tags:
19+
- react
20+
- scss
21+
- ux
22+
- image-rendering
23+
author: Sai Krishna Prasad
24+
---
25+
26+
![Smooth Image Rendering](./images/smooth_image_rendering_cover.png)
27+
28+
Improve your web apps UX by enhancing image render with React's `onLoad` event and simple SCSS.
29+
30+
Let's cut to the chase. The GIF below shows what we are going to achieve by the end of this post.
31+
32+
![Default Image Rendering vs Smooth Image Rendering using render-smooth-image-react](./images/render_smooth_image_demo.gif)
33+
34+
Here is the Completed Component Gist - [RenderSmoothImage](https://gist.github.com/KRRISH96/48b4200bc73f1071da804911c05ea373).
35+
36+
I have published this as an `npm` package [render-smooth-image-react](https://www.npmjs.com/package/render-smooth-image-react). The source code is available on [GitHub](https://github.com/KRRISH96/render-smooth-image-react).
37+
38+
---
39+
40+
## **Little Back Story**
41+
42+
I recently started working on a media-heavy app. Everything was cool until I noticed a bunch of images rendering poorly. Which looked something like this.
43+
44+
![Example: Poor image rendering (printing)](./images/poor_image_rendering.gif)
45+
46+
For a moment I thought, “Did I end up building a 🖨 _printer simulator app_?”
47+
48+
Overall customer satisfaction will take a hit with such poor loading UX (even if the rest of the app is great). This is especially true for media-heavy apps.
49+
50+
Alright, Let’s see what we can do to fix this.
51+
52+
---
53+
54+
## **Load and Fire** 🔫
55+
56+
> _Let the browser download the image and render it._
57+
58+
The perfect moment to render an image is after downloading completely. Till then we just show a loader/placeholder and hide the image.
59+
60+
We can achieve this by using React’s [onLoad](https://reactjs.org/docs/events.html#image-events) event on the image tag. You can read more about [React.js](https://reactjs.org/) events [here](https://reactjs.org/docs/events.html).
61+
62+
```html
63+
<img onLoad={'callbackAfterImageIsDownloaded'} />
64+
```
65+
66+
## **Code it**
67+
68+
We will create a functional component and use hooks to maintain a couple of states. If you are new to React Hooks, You can learn more [here](https://reactjs.org/docs/hooks-intro.html).
69+
70+
```jsx
71+
// RenderSmoothImage.jsx
72+
73+
function RenderSmoothImage({src, alt}) {
74+
const [imageLoaded, setImageLoaded]=React.useState(false);
75+
76+
return (
77+
<div className="smooth-image-wrapper">
78+
<img
79+
src={src}
80+
alt={alt}
81+
className={`smooth-image image-${
82+
imageLoaded ? 'visible' : 'hidden'
83+
}`}
84+
onLoad={()=> setImageLoaded(true)}}
85+
/>
86+
{!imageLoaded && (
87+
<div className="smooth-preloader">
88+
<span className="loader" />
89+
</div>
90+
)}
91+
</div>
92+
)
93+
}
94+
```
95+
96+
```css
97+
/** styles.css */
98+
99+
.smooth-image {
100+
transition: opacity 1s;
101+
}
102+
.image-visible {
103+
opacity: 1;
104+
}
105+
.image-hidden {
106+
opacity: 0;
107+
}
108+
```
109+
110+
Here, we maintain a state `imageLoaded` defaults to `false`. Which will then be set to `true`, once the image is downloaded. We use the `onLoad` event to trigger this.
111+
112+
Then we use `imageLoaded` state to conditionally add classes to the `img` tag, `image-visible` vs `image-hidden`. We can add transitions/animations to make it smoother. Please refer to the linked Gist at the top for complete styles.
113+
114+
That’s it! No more printer simulators on the page.
115+
116+
---
117+
118+
## **What if Image Download Fails / Invalid Src?**
119+
120+
![Image for alternate text with image tag](./images/default_alt_text.png)
121+
122+
By using the `alt` attribute we can show alternate text for the image. However, the default icon and styling isn’t too great.
123+
124+
To fix this we can display custom `alt` text.
125+
126+
```jsx
127+
// RenderSmoothImage.jsx
128+
129+
function RenderSmoothImage({src, alt}) {
130+
.....
131+
const [isValidSrc, setIsValidSrc] = React.useState(!!src);
132+
133+
return (
134+
<div className="smooth-image-wrapper">
135+
{isValidSrc ? (
136+
<img
137+
....
138+
onError={() => setIsValidSrc(false)}
139+
/>
140+
) : (
141+
<div className="smooth-no-image">{alt}</div>
142+
)}
143+
{isValidSrc && !imageLoaded && (
144+
<div className="smooth-preloader">
145+
<span className="loader" />
146+
</div>
147+
)}
148+
</div>
149+
)
150+
}
151+
```
152+
153+
```css
154+
/** styles.css */
155+
...... .smooth-no-image {
156+
background-image: linear-gradient(90deg, #ccc, #999, #ccc);
157+
color: #fff;
158+
}
159+
```
160+
161+
There you go,
162+
163+
![Customized Alternate Text for Image](./images/custom_alt_text.png)
164+
165+
You can style the Alternative text any way you want.
166+
167+
I made things easy for you and published a light-weight npm package [render-smooth-image-react](https://www.npmjs.com/package/render-smooth-image-react).
Loading
Loading
Loading
Loading
Loading

0 commit comments

Comments
 (0)