Scaling Performance in Vue.js Applications

Scaling performance and optimization in Vue.js applications.

John Philip
JavaScript in Plain English

--

Photo by Luke Peters on Unsplash

Performance optimizing of vue applications plays an important role in the application architecture.

A higher performance application will ensure an increase in user retention, improved user experience and higher conversion rates.

According to research by Google, 53% of the mobile users leave a site if it takes more than 3 seconds to load? On top of that, more than half of the pages tested have weighed more than 2MB.

Your app performance directly affects its search ranking and conversion rates. On the other hand, Pinterest reduced their initial wait time by 40%, which resulted in a 15% increase in search engine traffic and sign-ups. Walmart had similar results, for every second of reduction in load time their conversions increased by 2%.

On the other hand, research by Bing shows that a 2-second delay resulted in a 4.3% loss in revenue per visitor and 3.75% reduction in clicks.

Higher performance will ensure that your company or business increase its user retention and that means an increase in sales or profits.

How do we achieve performance in VueJS applications?

In this article, we are going to see the various ways we can implement to improve performance and optimization in VueJS applications.

Asynchronous components loading/lazy loading

Asynchronous loading of components is the process of loading parts(chunks) of your application lazily. It ensures that components are only loaded when they are needed.

According to vueshool.io Lazy loading ensures that the bundle is split and serve only the needed parts so users are not wasting time to download and parse code that will not be used.

Synchronous/Static loading of components

Static loading of components is loading the components with the default import statement., we use the native import syntax as shown below.

Components loaded with a static import statement will be added to the existing application bundle. If code splitting is not used then the application core will become larger and thereby affecting the overall performance of the application.

The code snippet below will dynamically load the photos component.

// static loading of the photo componentimport Photos from “@/components/photos”;

To dynamically load a component, we have to change from the default static import of component to the dynamic import of components.

Dynamic Loading of Components

To dynamically load a component, we declare a const and append an arrow function followed by the default static import statement.

We can also add a web packs magic comment. The comment will tell webpack to assign our chunk the name we provided otherwise webpack will auto-generate a name by itself.

See the example below.

// dynamic import of the photos componentconst Photos = () =>import(/* webpackChunkName: “Photos” */ “@/components/photos”);

If we head over to our developer tools and open the network tab we can see that our chunk has been assigned the name we provided in the webpack’s chunk name comment.

See below

Webpack’s magic comment

With vue3 we can use the suspense defineAsyncComponent to lazily load components.

Suspense makes it easy to show fallback content during loading. Suspense boundary also helps control when view sections are ready for rendering.

To use defineAsyncComponent, we first have to import it from vue to make it available for use in our application.

// dynamic import of the photos component with suspense<template><img alt=”Vue logo” src=”./assets/logo.png” /><HelloWorld msg=”Welcome to Your Vue.js App” /></template><script>import { defineAsyncComponent } from “vue”;const HelloWorld = defineAsyncComponent(() =>import(“./components/HelloWorld.vue”));export default {name: “App”,components: {HelloWorld,},};</script>

More about asynchronous loading of components in vue 3

Lazy loading routes

When using Nuxtjs which is built entirely on top of VueJS, it does per-route code-splitting out of the box.

To lazy load routes, just use the same way we lazy load components.

WebP images and image compression

Image compression is really important when optimizing applications. Lighter images will perform faster as compared to larger image files. Apart from that, smaller images also lead to less load time.

By compressing the images, we make our site much lighter and hence providing lower load times.

What is WebP?

WebP A new image format for the Web.

WebP is a modern image format that provides superior lossless and lossy compression for images on the web. Using WebP, webmasters and web developers can create smaller, richer images that make the web faster.

According to dev Mozilla, WebP lossless images are 26% smaller in size compared to PNGs. WebP lossy images are 25–34% smaller than comparable JPEG images at equivalent SSIM quality index.

Lossless WebP supports transparency (also known as alpha channel) at a cost of just 22% additional bytes. For cases when lossy RGB compression is acceptable, lossy WebP also supports transparency, typically providing 3× smaller file sizes compared to PNG.

WebP is supported by Chrome, Firefox, Edge and Safari from version 14.

Let us convert a JPG image to WebP and notice the difference in size and performance. WebP images have the smallest size while maintaining image quality.

Before conversion

Jpg image file (70.1kb)

Unoptimized jpg file

original jpg image (before conversion)

After conversion

WebP image file (3.43kb)

the final image (After conversion)

I hope you see the drastic shred in size into a much smaller image file.

From 70.1kb to a feather size of 3.43kb. Lighter image files aren’t it?

I also found this website that helped me convert the images to WebP

Code splitting

Code splitting is the process of splitting the app into lazily loaded chunks.

According to dev Mozilla Code splitting is the splitting of code into various bundles or components which can then be loaded on-demand or in parallel.

As an application grows in complexity or is maintained, CSS and JavaScripts files or bundles grow in byte size, especially as the number and size of included third-party libraries increases.

To prevent the requirement of downloading ginormous files, scripts can be split into multiple smaller files. Then features required at page load can be downloaded immediately with additional scripts being lazy-loaded after the page or application is interactive, thus improving performance. While the total amount of code is the same (and perhaps even a few bytes larger), the amount of code needed during initial load can be reduced.

Code splitting is a feature supported by bundlers like Webpack and Browserify which can create multiple bundles that can be dynamically loaded at runtime.

How we can do the code splitting with webpack

// Build Configuration (https://go.nuxtjs.dev/config-build)build: {configureWebpack: {optimization: {runtimeChunk: ‘single’,splitChunks: {chunks: ‘all’,maxInitialRequests: Infinity,minSize: 0,cacheGroups: {vendor: {test: /[\\/]node_modules[\\/]/,name(module) {const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];return `npm.${packageName.replace(‘@’, ‘’)}`;},},},},},},analyze: true,}

Use purge to extract unused CSS

When you are building your application, you might decide to use a CSS framework like TailwindCSS, Bootstrap, MaterializeCSS, Foundation, etc. But you will only use a small set of the framework styles, and a lot of unused CSS styles will be included.

According to PurgeCSS is a tool to remove unused CSS. It can be part of your development workflow.

This is where PurgeCSS comes into play. PurgeCSS analyzes our application content, styles and your CSS files. Then it matches the selectors used in your files with the one in your content files. It removes unused selectors from your CSS, resulting in smaller CSS files

Resources

Conclusion

Just to recap that we have seen some of the best practices to implement to optimize a VueJS application for performance and optimizations.

Some of the ways of scaling performance and optimization in VueJS applications are:

  • Asynchronous loading of components
  • Asynchronous loading routes
  • Image compression or using WebP images
  • Tree shaking of Unused CSS styles (when using a CSS frameworks)

Thank you for reading through this article. If you found this piece helpful please do not hesitate to share it out.

More reading:

--

--