Search code examples
vue.jsvuejs2componentsnuxt.jslazy-loading

Why is my Vue JS Nuxt lazy loaded component bundled in app.js, not loaded separately?


I've just started using Nuxt but have used VueJS for a while. For a test, I've tried lazy loading the tutorial component that is created with the create-nuxt-app command. (I've tried my own component too but went back to a fresh app to try and get Lazy Loading to work). Unfortunately, the component is not lazy loaded.

The index page in my new app is very simple. It has a button to show the tutorial component that is named "LazyTutorial" to indicate lazy loading. The component uses v-if to hide it until the button is clicked.

<template>
  <div>
    <h1>Welcome!</h1>
    <button @click="start">
      Show tutorial
    </button>
    <LazyTutorial v-if="showTutorial"></LazyTutorial>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
  name: 'IndexPage',
  data () {
    return {
      showTutorial: false
    }
  },
  methods: {
    start () {
      this.showTutorial = true
    }
  }
})
</script>

The Tutorial component is unchanged from the original.

According to what I've seen (eg: Debbie O'Brien's Nuxt Auto Components and Lazy Loading), it's simply a matter of using dynamically loaded components (components:true in nuxt.config.js) and the "Lazy" prefix on the component.

The app builds fine and works as expected from the user perspective - but the component code is bundled into the app.js file, it's NOT lazy loaded. It doesn't appear in the network tab when I click the button because it's already in the app file.

I'm running locally using npm run dev.

Have I missed some configuration settings? What's wrong here?

Here's my dependency list for version numbers:

"dependencies": {
    "@nuxtjs/axios": "^5.13.6",
    "@nuxtjs/pwa": "^3.3.5",
    "bootstrap": "^4.6.1",
    "bootstrap-vue": "^2.21.2",
    "core-js": "^3.19.3",
    "nuxt": "^2.15.8",
    "vue": "^2.6.14",
    "vue-server-renderer": "^2.6.14",
    "vue-template-compiler": "^2.6.14",
    "webpack": "^4.46.0"
  },

Running on Windows 10 (if relevant)


Solution

  • Nuxt2 uses Webpack4 and (probably for performance reasons) it is not showing the lazy loading of the .vue components during development.

    That being said, when you bundle your project (npm run build && npm run start in your case), it is working perfectly fine (can be seen in the Network tab of the devtools).


    As a side note, a Nuxt3 variant would be

    <template>
      <button @click="shownComponent = !shownComponent">toggle me please</button>
      <lazy-test v-if="shownComponent" />
    </template>
    
    <script setup>
    const shownComponent = ref(false)
    </script>
    

    And importing it properly even during development

    enter image description here

    This comes probably from the fact that Vite is better at this, or maybe have more explicit HMR settings. Anyway, the RC release is really close so I would recommend maybe checking . Especially if you're a heavy user of TS.

    Otherwise, you would need to find and see how to configure Webpack's HMR settings (disclaimer: I'm not sure if it's feasible).