When a webpage loads several images, especially of small sizes, the requests can become quite costly. If we combine them into a single image, we reduce the load on our server as well client load time. Creating sprites can be challenging as well as consuming them. Let us learn how we can easily use them in a Nuxt.Js app.
Codesandbox
The completed project is available on Codesandbox.
You can find the full codebase on my Github
Cloudinary setup
Cloudinary is a media management platform geared at allowing developers to unleash their full potential. We are going to use their platform to store our images and generate the image sprite. If you do not have an account, register here
Once your account is setup, proceed to the media library
and create a folder called nuxtjs-image-sprites
. Within this folder, upload the following files:
- nuxtjs-image-sprites/comic-book.png
- nuxtjs-image-sprites/mushrooms.png
- nuxtjs-image-sprites/cartoon.png
- nuxtjs-image-sprites/leonardo.png
- nuxtjs-image-sprites/chick.png
Once uploaded, you should have a folder similar to this one:
Select all the images in the folder and give them the tag nis-cartoons
.
Nuxt.Js Setup
Nuxt.Js is a VueJS framework that boasts of simplicity and productivity.
Ensure you have Yarn or npm v5.2+/v6.1+ installed and navigate to your preferred working directory in the terminal
1yarn create nuxt-app nuxtjs-image-sprites2# OR3npx create-nuxt-app nuxtjs-image-sprites4# OR5npm init nuxt-app nuxtjs-image-sprites
This will result in a set of questions to customize your project. Here are our recommended defaults:
Project name: nuxtjs-image-sprites Programming language: JavaScript Package manager: Yarn UI framework: Tailwind CSS Nuxt.js modules: N/A Linting tools: N/A Testing frameworks: None Rendering mode: Universal (SSR/SSG) Deployment target: Server (Node.js hosting) Development tools: N/A What is your Github username?
<your-github-username>
Version control system: Git
Once complete, you may run the project on http://localhost:3000
1cd nuxtjs-image-sprites23yarn dev4# OR5npm run dev
Generating the image sprite
Cloudinary makes generating the image sprite a very easy process. You simply need to replace the <cloud_name>
with your Cloudinary cloud name.
1https://res.cloudinary.com/<cloud_name>/image/sprite/nis-cartoons.png
The generated image sprite should be similar to this one.
Using the image sprite
Let us first store our images in our page state for reference.
1// pages/index.vue2<script>3export default {4 data(){5 return {6 images:[7 {8 class: 'cartoon',9 credit: 'Cartoon icons created by wanicon - Flaticon',10 link: 'https://www.flaticon.com/free-icons/cartoon'11 },12 {13 class: 'chick',14 credit: 'Cartoon icons created by surang - Flaticon',15 link: 'https://www.flaticon.com/free-icons/cartoon'16 },17 {18 class: 'comic_book',19 credit: 'Cartoon icons created by Freepik - Flaticon',20 link: 'https://www.flaticon.com/free-icons/cartoon'21 },22 {23 class: 'leonardo',24 credit: 'Cute icons created by Smashicons - Flaticon',25 link: 'https://www.flaticon.com/free-icons/cute'26 },27 {28 class: 'mushrooms',29 credit: 'Mushroom icons created by Rabbixcons - Flaticon',30 link: 'https://www.flaticon.com/free-icons/mushroom'31 },32 ]33 }34 }35}36</script>
As visible above, we store the class
of our images. This is because we will use CSS to display our images. Let us generate the CSS we are going to use.
1/* pages/index.vue */2<style>3.cartoon, .chick, .comic_book, .leonardo , .mushrooms {4 background: url('//res.cloudinary.com/hackit-africa/image/sprite/w_280,c_fit/nis-cartoons.png') no-repeat;5}6.cartoon { background-position: 0px 0px; width: 280px; height: 280px; }7.chick { background-position: 0px -280px; width: 280px; height: 280px; }8.comic_book { background-position: 0px -560px; width: 280px; height: 280px; }9.leonardo { background-position: 0px -840px; width: 280px; height: 280px; }10.mushrooms { background-position: 0px -1120px; width: 280px; height: 280px; }1112</style>
As visible in the above CSS code, we add a transformation to our image sprite limiting the width to 280px.
http://res.cloudinary.com/hackit-africa/image/sprite/w_280,c_fit/nis-cartoons.png
For each image, we create a class limiting width and height to 280px as we know the images we use are square-shaped. We change the background-position
y-axis position by an offset of 280px per class. This will display different images contained in the image sprite.
Now to display image sprite, we simply need to iterate the images
adding the classes.
1// pages/index.vue2<template>3 ...4 <div5 v-for="(image,index) in images"6 :key="index"7 >8 <div>9 <div :class="`${image.class} w-full h-full mx-auto`"></div>10 </div>11 <div>12 <div>13 <h3>14 <a15 :href="image.link"16 target="_blank"17 >18 {{image.credit}}19 </a>20 </h3>21 </div>22 </div>23 </div>24 ...25</template>
With the above code, we should now have an output similar to this one.
Conclusion
With the above code, we only load our images once instead of having 5 separate requests being sent to our backend. Because we add the resize and crop transformation, we are even able to add more data savings to our app.
To learn more about image sprites, feel free to review the Cloudinary documentation.