Lesson 09-Nuxt.js Performance Optimization and Internationalization

Performance Optimization

Nuxt.js offers several methods to optimize application performance, including using the nuxt optimize command, configuring Webpack optimizations, and generating static sites with nuxt generate. Below, we detail these optimization strategies and their implementation.

Using the nuxt optimize Command

The nuxt optimize command helps automatically optimize Nuxt.js applications by compressing JavaScript and CSS files, reducing HTTP requests, and more.

Run the nuxt optimize command:

npx nuxt optimize

Configuring Webpack Optimizations

Configuring Webpack allows further optimization of the build process, such as enabling production mode and code splitting.

Configure Webpack in nuxt.config.js:

// nuxt.config.js
export default {
  build: {
    // Enable production mode
    production: process.env.NODE_ENV === 'production',
    // Code splitting
    splitChunks: {
      layouts: true,
      pages: true,
      components: true,
      server: true,
    },
    // Additional Webpack configuration
    extend(config, ctx) {
      // Example: Minify JavaScript
      config.optimization.minimize = true;
      config.optimization.minimizer = [
        new TerserPlugin({
          terserOptions: {
            compress: {},
            mangle: true,
          },
        }),
      ];
    },
  },
};

Using nuxt generate for Static Site Generation

The nuxt generate command converts a Nuxt.js application into static HTML files, significantly improving first-page load speed.

Run the nuxt generate command:

npx nuxt generate

Code Splitting

Using Nuxt.js’s dynamic import feature enables on-demand module loading, reducing initial load times.

Using Dynamic Imports in Pages or Components:

// pages/about.vue
export default {
  async asyncData({ $axios }) {
    const { default: AboutPage } = await import('./AboutPage.vue');
    return { component: AboutPage };
  },
};

Lazy Loading

Lazy loading defers the loading of non-critical resources, such as images and videos.

Use the vue-lazyload plugin for lazy loading:

// plugins/lazyload.js
import Vue from 'vue';
import VueLazyload from 'vue-lazyload';

Vue.use(VueLazyload, {
  loading: require('~/assets/loading.gif'),
  error: require('~/assets/error.png'),
});

Use lazy loading in templates:

<!-- pages/index.vue -->
<template>
  <div>
    <img v-lazy="imageSrc" alt="Lazy loaded image">
  </div>
</template>

<script>
export default {
  data() {
    return {
      imageSrc: '/path/to/image.jpg',
    };
  },
};
</script>

Using a CDN

Deploying static assets to a CDN can significantly improve load times.

Configure a CDN in nuxt.config.js:

// nuxt.config.js
export default {
  build: {
    publicPath: 'https://cdn.example.com/',
  },
};

Image Optimization

Compressing and optimizing image formats can significantly reduce file sizes.

Use the imagemin plugin for image optimization:

// nuxt.config.js
export default {
  build: {
    transpile: [/^imagemin/],
    plugins: [
      new ImageminWebp({
        test: /\.(jpe?g|png)/,
        options: {
          quality: 70,
        },
      }),
    ],
  },
};

Caching Strategies

Effective caching strategies can reduce server load and speed up page loading.

Set HTTP cache headers:

// nuxt.config.js
export default {
  server: {
    middleware: [
      // Set cache control headers
      (req, res, next) => {
        res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');
        next();
      },
    ],
  },
};

Reducing Dependencies

Unnecessary dependencies increase build times and file sizes.

Use purgecss-webpack-plugin to remove unused CSS:

// nuxt.config.js
export default {
  build: {
    plugins: [
      new PurgecssPlugin({
        paths: glob.sync(`${__dirname}/pages/**/*.{vue,js}`),
        whitelist: ['html', 'body'],
      }),
    ],
  },
};

Server Performance Optimization

Optimizing server configuration can also enhance performance.

Use Node.js’s cluster module for load balancing:

// server.js
if (cluster.isMaster) {
  const numWorkers = os.cpus().length;
  for (let i = 0; i < numWorkers; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} died`);
  });
} else {
  const app = require('./index');
  const port = process.env.PORT || 3000;
  app.listen(port, () => {
    console.log(`App listening on port ${port}`);
  });
}

Internationalization

Installing vue-i18n

First, install the vue-i18n package, a Vue.js internationalization plugin that integrates seamlessly with Nuxt.js projects.

Example Code
Install vue-i18n:

npm install --save vue-i18n

Configuring vue-i18n

Next, configure vue-i18n in your Nuxt.js project.

Create i18n.js in the plugins folder:

// plugins/i18n.js
import Vue from 'vue';
import VueI18n from 'vue-i18n';

Vue.use(VueI18n);

export default ({ app }, inject) => {
  const i18n = new VueI18n({
    locale: 'en', // Default language
    fallbackLocale: 'en', // Fallback language if translation is missing
    messages: {
      en: {
        message: {
          hello: 'Hello world!',
        },
      },
      de: {
        message: {
          hello: 'Hallo Welt!',
        },
      },
    },
  });

  inject('i18n', i18n);
};

Register the plugin in nuxt.config.js:

// nuxt.config.js
export default {
  plugins: ['~/plugins/i18n'],
};

Creating Language Files

To manage translations for different languages, create corresponding .json files in the locales folder.

Example Code
Create language files:

locales/
├── en.json
└── de.json

Content Example:

// locales/en.json
{
  "message": {
    "hello": "Hello world!"
  }
}

// locales/de.json
{
  "message": {
    "hello": "Hallo Welt!"
  }
}

Dynamically Loading Language Files

To enable vue-i18n to dynamically load language files, update i18n.js.

Update plugins/i18n.js:

// plugins/i18n.js
import Vue from 'vue';
import VueI18n from 'vue-i18n';

Vue.use(VueI18n);

const messages = {};
const files = require.context('~locales', true, /\.json$/i);
files.keys().forEach(key => {
  const matched = key.match(/([A-Za-z0-9-_]+)\./i);
  if (matched && matched.length > 1) {
    const locale = matched[1];
    messages[locale] = files(key);
  }
});

export default ({ app }, inject) => {
  const i18n = new VueI18n({
    locale: 'en', // Default language
    fallbackLocale: 'en', // Fallback language if translation is missing
    messages,
  });

  inject('i18n', i18n);
};

Route Configuration

To support multilingual routes, configure routes in nuxt.config.js.

Configure routes in nuxt.config.js:

// nuxt.config.js
export default {
  router: {
    middleware: ['i18n'],
  },
  i18n: {
    locales: [
      { code: 'en', iso: 'en-US', file: 'en.json' },
      { code: 'de', iso: 'de-DE', file: 'de.json' },
    ],
    defaultLocale: 'en',
    vueI18n: {
      fallbackLocale: 'en',
      messages: {},
    },
  },
};

Creating the _lang Folder

To support different language versions of pages, create a _lang folder in the pages directory.

Create the _lang Folder:

pages/
├── _lang/
│   ├── en/
│   │   └── index.vue
│   └── de/
│       └── index.vue
└── index.vue

Using Internationalization Tags

Use i18n tags in templates to display translated text.

Use i18n tags in pages/index.vue:

<template>
  <div>
    <h1>{{ $t('message.hello') }}</h1>
  </div>
</template>

Switching Languages

To allow users to switch between languages, implement language-switching logic.

Example Code
Add language-switching functionality in pages/index.vue:

// pages/index.vue
export default {
  methods: {
    changeLanguage(lang) {
      this.$i18n.locale = lang;
    },
  },
};

Example Project Structure

project/
├── plugins/
│   └── i18n.js
├── locales/
│   ├── en.json
│   └── de.json
├── pages/
│   ├── _lang/
│   │   ├── en/
│   │   │   └── index.vue
│   │   └── de/
│   │       └── index.vue
│   └── index.vue
└── nuxt.config.js
Share your love