-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(ssr): only cache computed getters during render phase
fix #5300
- Loading branch information
Showing
6 changed files
with
75 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { createSSRApp, defineComponent, h, computed, reactive } from 'vue' | ||
import { renderToString } from '../src/renderToString' | ||
|
||
// #5208 reported memory leak of keeping computed alive during SSR | ||
// so we made computed properties created during SSR non-reactive in | ||
// https://github.com/vuejs/core/commit/f4f0966b33863ac0fca6a20cf9e8ddfbb311ae87 | ||
// However, the default caching leads to #5300 which is tested below. | ||
// In Vue 2, computed properties are simple getters during SSR - this can be | ||
// inefficient if an expensive computed is accessed multiple times during render, | ||
// but because of potential mutations, we cannot cache it until we enter the | ||
// render phase (where no mutations can happen anymore) | ||
test('computed reactivity during SSR', async () => { | ||
const store = { | ||
// initial state could be hydrated | ||
state: reactive({ items: null }) as any, | ||
|
||
// pretend to fetch some data from an api | ||
async fetchData() { | ||
this.state.items = ['hello', 'world'] | ||
} | ||
} | ||
|
||
const getterSpy = jest.fn() | ||
|
||
const App = defineComponent(async () => { | ||
const msg = computed(() => { | ||
getterSpy() | ||
return store.state.items?.join(' ') | ||
}) | ||
|
||
// If msg value is falsy then we are either in ssr context or on the client | ||
// and the initial state was not modified/hydrated. | ||
// In both cases we need to fetch data. | ||
if (!msg.value) await store.fetchData() | ||
|
||
expect(msg.value).toBe('hello world') | ||
return () => h('div', null, msg.value + msg.value + msg.value) | ||
}) | ||
|
||
const app = createSSRApp(App) | ||
|
||
const html = await renderToString(app) | ||
expect(html).toMatch('hello world') | ||
|
||
// should only be called twice since access should be cached | ||
// during the render phase | ||
expect(getterSpy).toHaveBeenCalledTimes(2) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters