2

I have the following Nuxt.JS setup:

Vuex-persist plugin:

import VuexPersistence from 'vuex-persist'
  
export default ({ store }) => {
    new VuexPersistence({
      key: 'vuex', 
      storage: window.localStorage, 
    }).plugin(store);
}

package.json:

{
  "name": "",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
    "lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .",
    "lint": "yarn lint:js",
    "test": "jest"
  },
  "dependencies": {
    "@nuxtjs/axios": "^5.13.6",
    "@nuxtjs/firebase": "^7.6.1",
    "@nuxtjs/pwa": "^3.3.5",
    "@tailwindcss/forms": "^0.3.3",
    "core-js": "^3.15.1",
    "firebase": "^8.6.8",
    "lodash": "^4.17.21",
    "nuxt": "^2.15.7",
    "nuxt-i18n": "^6.27.2",
    "sass": "^1.35.1",
    "vue-lodash": "^2.1.2",
    "vue-tailwind": "^2.4.1",
    "vuelidate": "^0.7.6",
    "vuex-persist": "^3.1.3"
  },
  "devDependencies": {
    "@babel/eslint-parser": "^7.14.7",
    "@nuxtjs/dotenv": "^1.4.1",
    "@nuxtjs/eslint-config": "^6.0.1",
    "@nuxtjs/eslint-module": "^3.0.2",
    "@nuxtjs/moment": "^1.6.1",
    "@nuxtjs/tailwindcss": "^4.2.0",
    "@vue/test-utils": "^1.2.1",
    "add": "^2.0.6",
    "babel-core": "7.0.0-bridge.0",
    "babel-jest": "^27.0.5",
    "eslint": "^7.29.0",
    "eslint-plugin-nuxt": "^2.0.0",
    "eslint-plugin-vue": "^7.12.1",
    "jest": "^27.0.5",
    "node-sass": "^6.0.1",
    "postcss": "^8.3.5",
    "sass-loader": "^10",
    "vue-jest": "^3.0.4",
    "yarn": "^1.22.10"
  }
}

nuxt.config.js

export default {
  // Global page headers: https://go.nuxtjs.dev/config-head
  head: {
    title: '',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: '' },
      { name: 'format-detection', content: 'telephone=no' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },

  // Global CSS: https://go.nuxtjs.dev/config-css
  css: [
  ],

  // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
  plugins: [
    {
      src: '~/plugins/vuelidate.js',
      mode: 'all',
    },
    {
      src: '~/plugins/vue-lodash',
    },
    {
      src: '~plugins/vue-tailwind',
    },
    {
      src: '~/plugins/vuex-persist',
      mode: 'client'
    }


  ],

  // Auto import components: https://go.nuxtjs.dev/config-components
  components: true,

  // Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
  buildModules: [
    // https://go.nuxtjs.dev/eslint
    // '@nuxtjs/eslint-module',
    // https://go.nuxtjs.dev/tailwindcss
    '@nuxtjs/tailwindcss',
    '@nuxtjs/dotenv',
    '@nuxtjs/moment',
  ],

  // Modules: https://go.nuxtjs.dev/config-modules
  modules: [
    '@nuxtjs/axios',
    '@nuxtjs/pwa',
    '@nuxtjs/firebase',
    'nuxt-i18n',
  ],

  axios: { credentials: false },

  i18n: {
    locales: [
      {
        code: 'nl',
        iso: 'nl-NL',
        name: 'Nederlands',
      },
    ],
    defaultLocale: 'nl',
    noPrefixDefaultLocale: true,
    vueI18n: {
      fallbackLocale: 'nl',
      messages: {
        nl: require('./locales/nl.json'),
      },
    },
  }
  ,

  firebase: {
    config: {
      apiKey: process.env.FIREBASE_API_KEY,
      authDomain: process.env.FIREBASE_AUTH_DOMAIN,
      projectId: process.env.FIREBASE_PROJECT_ID,
      storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
      messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,
      appId: process.env.FIREBASE_APP_ID,
      measurementId: process.env.FIREBASE_MEASUREMENT_ID,
    },
    services: {
      auth: true
    }
  },

  // Axios module configuration: https://go.nuxtjs.dev/config-axios
  axios: {},

  // PWA module configuration: https://go.nuxtjs.dev/pwa
  pwa: {
    manifest: {
      lang: 'en'
    }
  },

  // Build Configuration: https://go.nuxtjs.dev/config-build
  build: {
  }
}

cart.js

<template>
  <div>
    <h1>Cart</h1>
    <CartCard
      v-for="product in products"
      :key="product.id"
      :product="product"
    />
  </div>
</template>

<script>
import { mapGetters } from "vuex";
export default {
  computed: {
    ...mapGetters({
      products: "cart/products",
    }),
  },
};
</script>

Whenever I load the card page, I see the H1 loading instantly, and the card components take a good second to render from my localStorage where the persist plugin is putting my vuex-store at the moment. I am only retrieving a getter from the state, which returns an array of producs, without any complexity behind it,

Is there a way to speed up / streamline this process, so that the page will load synchronously?

Bowis
  • 541
  • 8
  • 31
  • 1
    `ssr: false` is outdated for the plugins, use `mode: client` instead: https://nuxtjs.org/docs/2.x/directory-structure/plugins How do you render your app? Are you sure the `localStorage` is the blocker and not the page itself? Can you please do a quick bench with a `console.log` in `created()` and `mounted()` to see if your app is mounted sooner than your `localStorage` is fetched. – kissu Jul 09 '21 at 16:25
  • 1
    Also, are you maybe doing something time-consuming in your getter? – kissu Jul 09 '21 at 16:27
  • App is rendered using the 'universal' mode with server-side rendering. The getter is merely: `products: (state) => state.products`, returning an array. Even when I have only 1 product in my cart, it takes a noticeable second. If i call the getter in the created() hook, it is logged before the page is mounted. – Bowis Jul 09 '21 at 17:03
  • 1
    `mode: universal` is outdated too: https://stackoverflow.com/questions/68272663/how-to-setup-nuxt-for-an-isomorphic-universal-app Also, I forgot to ask when is the getter called in comparison to `mounted` (far less relevant in fact lol). Also, if you're only doing this in the getter, you could later strip it and only use `mapState`. – kissu Jul 09 '21 at 17:06
  • Far more relevant* – kissu Jul 09 '21 at 18:15
  • @kissu ah gotcha, what would be an easy way to check this regarding the getter? – Bowis Jul 09 '21 at 18:41
  • 1
    As before, simply make a `console.log` into the getter. If you do have a big delay between your `mounted` and `getter`, this could be coming from `vuex-persist`. If the 2 `console.log` are pretty much hapenning at the same time, the issue is not coming from this package but from your rendering. Another idea, would be to try a localStorage solution manually, see if the module is maybe slow? Also, are you sure this is not coming from your hardware (laptop you're working on)? – kissu Jul 09 '21 at 18:44
  • Hmm, the getter is called at 20:46:15.245 server-side, 20:46:15:734 client-side, and the page is mounted at 20:46:15:745, so I guess i should look somewhere else – Bowis Jul 09 '21 at 18:48
  • 1
    Yep, this looks like a quick fetch of the Vuex data haha! Could you maybe share your `package.json` or `nuxt.config.js`? – kissu Jul 09 '21 at 18:50
  • @kissu added the package.json and config files – Bowis Jul 10 '21 at 11:56
  • Any updates on this one? – Robert Mar 22 '22 at 21:26
  • @Robert i changed the SSR setup. – Bowis Mar 28 '22 at 13:08
  • thanks for letting me know – Robert Mar 28 '22 at 18:21

0 Answers0