vue icon indicating copy to clipboard operation
vue copied to clipboard

SSR Component Cache doesn't cache Strings

Open MartinLG opened this issue 7 years ago • 15 comments

Version

2.5.13

Reproduction link

https://runkit.com/martinlg/issue-vue-renderer-cache

Steps to reproduce

Run the Runkit code. If you prefer a git repository I can provide you one.

What is expected?

The value passed to the set function should be a string.

What is actually happening?

The value passed to the set function is an object, with 2 properties:

  • html: a string containing the rendered component
  • components: a Set containing nothing or function, depending on context (sub-components I think)

This issue breaks any external cache possibility (Redis in my case). The only possible cache is in the process memory, like the LRUCache, but it seems impossible to scale processes and share a common cache.

Moreover, the documentation explain clearly that the cached value should be a string, and even provides a small Redis example implementation, that could just not work.

I think that the documentation describe the expected behavior, so I don't want to "fix" the documentation, I think we should fix the behavior.

I will try to help but I may need some explanations on some parts of the RenderContext, can I ask my questions on this thread ?

MartinLG avatar Feb 02 '18 19:02 MartinLG

#7593 Old issue, rejected for heavy example.

MartinLG avatar Feb 02 '18 19:02 MartinLG

I don't think SSR cache behavior is expected, either.

https://github.com/vuejs/vue/blob/dev/packages/vue-server-renderer/types/index.d.ts#L46-L48

However, component cache also needs to cache component's lifecycle in rendering. So the type definition and documentation are both outdated.

HerringtonDarkholme avatar Feb 04 '18 04:02 HerringtonDarkholme

Actually, I don't see why we should cache component's lifecycle in rendering.

The component should be rendered, its template should be cached as a string (the html part of the currently stored object). Then when the component get fetched from the cache, it's template is static, and should not depend of the store. So I don't see why we should register all its child components.

Of course the browser takes back the hand, and make them dynamic like every components.

Did I miss something ?

MartinLG avatar Feb 04 '18 16:02 MartinLG

I just tried to remove the component registration and I see now that it breaks the inline styles on the cached version.

Still looking for a solution to store the cache on an external data store.

MartinLG avatar Feb 05 '18 13:02 MartinLG

@Atinux This is the issue I told you about. If you have any suggestions that could help me on SSR, I would love to ear it.

MartinLG avatar Mar 12 '18 19:03 MartinLG

I don't believe caching doesn't work as it should be o_O Maybe some PR will help fix this? And it still opened... from February? Does no one use the cache or what?

KindWizzard avatar Oct 09 '18 20:10 KindWizzard

Any updates on this? Having same issue with redis client.

dbrekalo avatar Feb 14 '19 09:02 dbrekalo

the same issue . I want to use redis client , but the components is a Set .

luoyang125024608 avatar Jul 26 '19 17:07 luoyang125024608

Wow, this is just extremely disappointing. Especially since the SSR docs explicitly show a redis client example. https://ssr.vuejs.org/api/#cache

chriz-hoepfner avatar Sep 06 '19 06:09 chriz-hoepfner

Has there been any progress on this or has everyone given up on having a shared cache?

dylancopeland avatar Jun 10 '20 17:06 dylancopeland

This will make it work, but I am not sure how safe it is considering that is doesn't provide back the register callbacks (no idea what they're needed for):

cache: {
  get: (key, cb) => {
    redisClient.get(key).then((res) => {
      if (!res) cb();
      else cb({ components: [], html: res });
    });
  },
  set: (key, val) => {
    redisClient.set(key, val.html);
  },
},

CyberAP avatar Feb 12 '21 12:02 CyberAP

The same problem, now try use similar code as @CyberAP, but my inline styles not worked UPDATE Try add yahoo/serialize-javascript, but code include some global vars: injectStyles, moduleIdentifier

function (context) {
  // 2.3 injection
  context =
    context || // cached call
    (this.$vnode && this.$vnode.ssrContext) || // stateful
    (this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext) // functional
  // 2.2 with runInNewContext: true
  if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
    context = __VUE_SSR_CONTEXT__
  }
  // inject component styles
  if (injectStyles) {
    injectStyles.call(this, context)
  }
  // register component module identifier for async chunk inferrence
  if (context && context._registeredComponents) {
    context._registeredComponents.add(moduleIdentifier)
  }
}

Kolobok12309 avatar Sep 01 '21 15:09 Kolobok12309

@CyberAP solutions seems working but I don't think it's too safe to use cache without components set. So is there any other solution for this?

gokalpfirat05 avatar Nov 03 '21 07:11 gokalpfirat05

The same problem, now try use similar code as @CyberAP, but my inline styles not worked UPDATE Try add yahoo/serialize-javascript, but code include some global vars: injectStyles, moduleIdentifier

function (context) {
  // 2.3 injection
  context =
    context || // cached call
    (this.$vnode && this.$vnode.ssrContext) || // stateful
    (this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext) // functional
  // 2.2 with runInNewContext: true
  if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
    context = __VUE_SSR_CONTEXT__
  }
  // inject component styles
  if (injectStyles) {
    injectStyles.call(this, context)
  }
  // register component module identifier for async chunk inferrence
  if (context && context._registeredComponents) {
    context._registeredComponents.add(moduleIdentifier)
  }
}

Sorry, where actually did you put this code?

SuperIbm avatar Oct 28 '22 10:10 SuperIbm

@SuperIbm This code i get from cache.set arg val.components, it some internally function of vue-renderer

Get it when try place it to redis

Kolobok12309 avatar Oct 28 '22 11:10 Kolobok12309