From 4e98ac174600d594354aeafdf4e95a6ed71fe425 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Mon, 4 Sep 2023 22:30:24 +0100 Subject: [PATCH] perf(nuxt): decrease default bundle size (#22999) --- packages/nuxt/src/app/composables/payload.ts | 8 +++++--- packages/nuxt/src/app/composables/router.ts | 9 ++++----- packages/nuxt/src/app/plugins/router.ts | 7 +++---- packages/nuxt/src/pages/runtime/plugins/router.ts | 7 +++---- test/bundle.test.ts | 6 +++--- 5 files changed, 18 insertions(+), 19 deletions(-) diff --git a/packages/nuxt/src/app/composables/payload.ts b/packages/nuxt/src/app/composables/payload.ts index 7d0e782dc9..a1958e76ce 100644 --- a/packages/nuxt/src/app/composables/payload.ts +++ b/packages/nuxt/src/app/composables/payload.ts @@ -56,10 +56,12 @@ function _getPayloadURL (url: string, opts: LoadPayloadOptions = {}) { async function _importPayload (payloadURL: string) { if (import.meta.server) { return null } + const payloadPromise = renderJsonPayloads + ? fetch(payloadURL).then(res => res.text().then(parsePayload)) + : import(/* webpackIgnore: true */ /* @vite-ignore */ payloadURL).then(r => r.default || r) + try { - return renderJsonPayloads - ? parsePayload(await fetch(payloadURL).then(res => res.text())) - : await import(/* webpackIgnore: true */ /* @vite-ignore */ payloadURL).then(r => r.default || r) + return await payloadPromise } catch (err) { console.warn('[nuxt] Cannot load payload ', payloadURL, err) } diff --git a/packages/nuxt/src/app/composables/router.ts b/packages/nuxt/src/app/composables/router.ts index 0ffead1cdd..6e86a087ce 100644 --- a/packages/nuxt/src/app/composables/router.ts +++ b/packages/nuxt/src/app/composables/router.ts @@ -7,7 +7,6 @@ import { hasProtocol, isScriptProtocol, joinURL, parseURL, withQuery } from 'ufo import { useNuxtApp, useRuntimeConfig } from '../nuxt' import type { NuxtError } from './error' import { createError, showError } from './error' -import { useState } from './state' import type { PageMeta } from '#app' import { PageRouteSymbol } from '#app/components/injections' @@ -222,14 +221,14 @@ export const abortNavigation = (err?: string | Partial) => { } export const setPageLayout = (layout: unknown extends PageMeta['layout'] ? string : PageMeta['layout']) => { + const nuxtApp = useNuxtApp() if (import.meta.server) { - if (import.meta.dev && getCurrentInstance() && useState('_layout').value !== layout) { + if (import.meta.dev && getCurrentInstance() && nuxtApp.payload.state._layout !== layout) { console.warn('[warn] [nuxt] `setPageLayout` should not be called to change the layout on the server within a component as this will cause hydration errors.') } - useState('_layout').value = layout + nuxtApp.payload.state._layout = layout } - const nuxtApp = useNuxtApp() - if (import.meta.dev && nuxtApp.isHydrating && nuxtApp.payload.serverRendered && useState('_layout').value !== layout) { + if (import.meta.dev && nuxtApp.isHydrating && nuxtApp.payload.serverRendered && nuxtApp.payload.state._layout !== layout) { console.warn('[warn] [nuxt] `setPageLayout` should not be called to change the layout during hydration as this will cause hydration errors.') } const inMiddleware = isProcessingMiddleware() diff --git a/packages/nuxt/src/app/plugins/router.ts b/packages/nuxt/src/app/plugins/router.ts index 4060ca79fa..6920fdea46 100644 --- a/packages/nuxt/src/app/plugins/router.ts +++ b/packages/nuxt/src/app/plugins/router.ts @@ -4,7 +4,6 @@ import { createError } from 'h3' import { defineNuxtPlugin, useRuntimeConfig } from '../nuxt' import { clearError, showError } from '../composables/error' import { navigateTo } from '../composables/router' -import { useState } from '../composables/state' // @ts-expect-error virtual file import { globalMiddleware } from '#build/middleware' @@ -226,12 +225,12 @@ export default defineNuxtPlugin<{ route: Route, router: Router }>({ named: {} } - const initialLayout = useState('_layout') + const initialLayout = nuxtApp.payload.state._layout nuxtApp.hooks.hookOnce('app:created', async () => { router.beforeEach(async (to, from) => { to.meta = reactive(to.meta || {}) - if (nuxtApp.isHydrating && initialLayout.value && !isReadonly(to.meta.layout)) { - to.meta.layout = initialLayout.value + if (nuxtApp.isHydrating && initialLayout && !isReadonly(to.meta.layout)) { + to.meta.layout = initialLayout } nuxtApp._processingMiddleware = true diff --git a/packages/nuxt/src/pages/runtime/plugins/router.ts b/packages/nuxt/src/pages/runtime/plugins/router.ts index b8de9504b9..6405ba772a 100644 --- a/packages/nuxt/src/pages/runtime/plugins/router.ts +++ b/packages/nuxt/src/pages/runtime/plugins/router.ts @@ -14,7 +14,6 @@ import { isEqual, withoutBase } from 'ufo' import type { PageMeta, Plugin, RouteMiddleware } from '../../../app/index' import { defineNuxtPlugin, useRuntimeConfig } from '#app/nuxt' import { clearError, showError, useError } from '#app/composables/error' -import { useState } from '#app/composables/state' import { navigateTo } from '#app/composables/router' // @ts-expect-error virtual file @@ -134,11 +133,11 @@ const plugin: Plugin<{ router: Router }> = defineNuxtPlugin({ await nuxtApp.runWithContext(() => showError(error)) } - const initialLayout = useState('_layout') + const initialLayout = nuxtApp.payload.state._layout router.beforeEach(async (to, from) => { to.meta = reactive(to.meta) - if (nuxtApp.isHydrating && initialLayout.value && !isReadonly(to.meta.layout)) { - to.meta.layout = initialLayout.value as Exclude + if (nuxtApp.isHydrating && initialLayout && !isReadonly(to.meta.layout)) { + to.meta.layout = initialLayout as Exclude } nuxtApp._processingMiddleware = true diff --git a/test/bundle.test.ts b/test/bundle.test.ts index 8458ff8625..9ea2358084 100644 --- a/test/bundle.test.ts +++ b/test/bundle.test.ts @@ -19,7 +19,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM for (const outputDir of ['.output', '.output-inline']) { it('default client bundle size', async () => { const clientStats = await analyzeSizes('**/*.js', join(rootDir, outputDir, 'public')) - expect.soft(roundToKilobytes(clientStats.totalBytes)).toMatchInlineSnapshot('"97.0k"') + expect.soft(roundToKilobytes(clientStats.totalBytes)).toMatchInlineSnapshot('"95.5k"') expect(clientStats.files.map(f => f.replace(/\..*\.js/, '.js'))).toMatchInlineSnapshot(` [ "_nuxt/entry.js", @@ -32,7 +32,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM const serverDir = join(rootDir, '.output/server') const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir) - expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot('"300k"') + expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot('"299k"') const modules = await analyzeSizes('node_modules/**/*', serverDir) expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"1822k"') @@ -71,7 +71,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM const serverDir = join(rootDir, '.output-inline/server') const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir) - expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot('"606k"') + expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot('"605k"') const modules = await analyzeSizes('node_modules/**/*', serverDir) expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"70.6k"')