Dynamic Importing:
https://github.com/nuxt/nuxt/discussions/9061#discussioncomment-539483
1) Keep your Pinia Stores lean
Move all your business logic to services or utils or datalayer
Ex:
export const useCartStore = defineStore("cartStore", {
state: () => ({
cartItems:[],
}),
actions: {
async addToCart(context, item){
const { addToCart } = await import('~/services/cartService');
return await addToCart(context, item);
}
},
});
2) Disable component auto import
In your nuxt.config.ts
, add:
components: {
global: true,
dirs: ['~/components/global'],
},
Keep your global components in components/global
folder
Import component dynamically:
const Example = defineAsyncComponent(() => import('@/components/Example.vue'));
3) Add compression and caching on assets
In your nuxt.config.ts
, add:
nitro: {
compressPublicAssets: true,
minify: true,
serveStatic: {
headers: {
'Cache-Control': 'public, max-age=31536000, immutable',
},
}
},
4) Add async
and defer
to scripts
5) Keep an eye on build sizes
You should run npm run build
and keep any on build sizes
6) Use transform to optimize payload
Ref: https://www.youtube.com/watch?v=laRJNkG_wls
7) Use ClientOnly
Wrap component under <ClientOnly>
tag which are not important for SEO, example:
<ClientOnly>
<NewsLetter />
</ClientOnly>
8) Use Pinia State management effectly
Ref: https://masteringpinia.com/blog/5-best-practices-for-scalable-vuejs-state-management-with-pinia
9) Dynamic loading of services
Note: You should avoid calling your store or nuxt composable in services, instead you must pass an instance of store from page or component.
Store in Page/Component
<script setup>
import { onMounted } from 'vue';
const myStore = useMyStore();
onMounted(async () => {
const { getItem } = await import('~/services/myService');
myStore.item = await getItem(myStore)
});
</script>
Store in middleware
export default defineNuxtRouteMiddleware(async (to, from) => {
// Conditionally determine if the auth store needs to be loaded
if (to.path.startsWith('/protected')) {
// Dynamically import the Pinia store
const { useAuthStore } = await import('~/stores/auth');
const authStore = useAuthStore();
// Perform the authentication check using the dynamically loaded store
if (!authStore.isAuthenticated) {
return navigateTo('/login');
}
}
// Other paths might not need the auth store and can proceed without loading it
});
10) Use export functions to avoid large bundle size
Smaller bundle size
// utils.ts
export const foo = () => {/* ... */};
export const bar = () => {/* ... */};
// Usage
import { foo, bar } from './utils';
Tree Shaking: When using module bundlers like Webpack or Rollup, it's easier to tree-shake unused functions, potentially resulting in a smaller bundle size.
Large Bundle Size
// MyClass.ts
export class MyClass {
foo() {/* ... */}
bar() {/* ... */}
}
// Usage
import { MyClass } from './MyClass';
const myInstance = new MyClass();
myInstance.foo();
11) SSR Calls
const { data } = await useAsyncData(
'results',
async () => {
const {searchResult} = await import("@/services/algoliaService")
return searchResult()
}
)
12) Use cachedEventHandler
for API routes
ref: https://hub.nuxt.com/docs/features/cache#api-routes-caching
ref: https://www.youtube.com/watch?v=QamuVgRiLVg
13) How to getCachedData
const { data, error, pending } = await useAsyncData(
'getPopularKeywords',
async () => {
const {getPopularKeywords} = await import("@/services-optimized/builderService")
return await getPopularKeywords(
runtimeConfig.public.builderApiKey
);
},
{
immediate: true,
getCachedData(key) {
if(!debug)
{
const cachedData = nuxtApp.payload.data[key] || nuxtApp.static.data[key];
if(!cachedData){
return;
}
//if data is too old
const expirationTime = new Date(cachedData.fetchedAt);
expirationTime.setTime(expirationTime.getTime() + 1000 * 60 * 60);
const isExpired = expirationTime.getTime() < new Date().getTime();
if(isExpired){
return;
}
}
},
}
)
Top comments (0)