From f6827c0beb8970e2ad7fc85875f3914ea3615722 Mon Sep 17 00:00:00 2001 From: "jhuang@hsk-partners.com" Date: Mon, 5 Sep 2022 13:41:47 +0200 Subject: [PATCH 1/2] perf(nuxt): use a cache for createClientOnly components --- .../nuxt/src/app/components/client-only.mjs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/nuxt/src/app/components/client-only.mjs b/packages/nuxt/src/app/components/client-only.mjs index 957020156a3..a5f5308981e 100644 --- a/packages/nuxt/src/app/components/client-only.mjs +++ b/packages/nuxt/src/app/components/client-only.mjs @@ -1,4 +1,4 @@ -import { ref, onMounted, defineComponent, createElementBlock, h, Fragment } from 'vue' +import { ref, onMounted, defineComponent, createElementBlock, h } from 'vue' export default defineComponent({ name: 'ClientOnly', @@ -18,13 +18,19 @@ export default defineComponent({ } }) +const cache = {} + export function createClientOnly (component) { + if (cache[component.__name]) { + return cache[component.__name] + } + const { setup, render: _render, template: _template } = component if (_render) { // override the component render (non script setup component) component.render = (ctx, ...args) => { return ctx.mounted$ - ? h(Fragment, null, [h(_render(ctx, ...args), ctx.$attrs ?? ctx._.attrs)]) + ? _render(ctx, ...args) : h('div', ctx.$attrs ?? ctx._.attrs) } } else if (_template) { @@ -34,7 +40,8 @@ export function createClientOnly (component) { ` } - return defineComponent({ + + const definition = defineComponent({ ...component, setup (props, ctx) { const mounted$ = ref(false) @@ -46,11 +53,12 @@ export function createClientOnly (component) { ? { ...setupState, mounted$ } : (...args) => { return mounted$.value - // use Fragment to avoid oldChildren is null issue - ? h(Fragment, null, [h(setupState(...args), ctx.attrs)]) + ? setupState(...args) : h('div', ctx.attrs) } }) } }) + cache[component.__name] = definition + return definition } From 6e7c5ea984cb079e7542f76bb7d324534c86d950 Mon Sep 17 00:00:00 2001 From: "jhuang@hsk-partners.com" Date: Mon, 5 Sep 2022 14:04:00 +0200 Subject: [PATCH 2/2] fx(nuxt): fix fragment h() breaking rerender --- packages/nuxt/src/app/components/client-only.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/nuxt/src/app/components/client-only.mjs b/packages/nuxt/src/app/components/client-only.mjs index a5f5308981e..d782e319c6d 100644 --- a/packages/nuxt/src/app/components/client-only.mjs +++ b/packages/nuxt/src/app/components/client-only.mjs @@ -1,4 +1,4 @@ -import { ref, onMounted, defineComponent, createElementBlock, h } from 'vue' +import { ref, onMounted, defineComponent, createElementBlock, h, Fragment } from 'vue' export default defineComponent({ name: 'ClientOnly', @@ -30,7 +30,7 @@ export function createClientOnly (component) { // override the component render (non script setup component) component.render = (ctx, ...args) => { return ctx.mounted$ - ? _render(ctx, ...args) + ? h(Fragment, ctx.props, [_render(ctx, ...args)]) : h('div', ctx.$attrs ?? ctx._.attrs) } } else if (_template) { @@ -53,7 +53,7 @@ export function createClientOnly (component) { ? { ...setupState, mounted$ } : (...args) => { return mounted$.value - ? setupState(...args) + ? h(Fragment, null, [setupState(...args)]) : h('div', ctx.attrs) } })