Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MANUAL INJECTION] renderState in script of type application/json #12276

Open
andoniabedul opened this issue Sep 13, 2021 · 1 comment
Open

[MANUAL INJECTION] renderState in script of type application/json #12276

andoniabedul opened this issue Sep 13, 2021 · 1 comment

Comments

@andoniabedul
Copy link

@andoniabedul andoniabedul commented Sep 13, 2021

What problem does this feature solve?

Right now when we use the functionality of renderState of createRenderer or createBundleRenderer it saves the data that you send in a window.INITIAL_STATE or the variable that you defined in the options, changing for example the name of the window variable.

As defined in the docs: https://ssr.vuejs.org/guide/build-config.html#client-config

This require that the browser process the data that will be storing it in the window variable. This take time with large objects.

PROPOSAL: Add a new option, for example plainStorage with the ID of the script that will save the data in a script of type application/json, by giving the JSON data a non-standard type in the <script> tag, the browser won't try to parse it as JavaScript. With this we can save some ms on the server side rendering.

Obviusly, this will be moving the operational cost of process the data when you hydrate the app on client doing a JSON.parse.

What does the proposed API look like?

context.renderState({
  plainStorage: '__STATE__'
})
// -> <script id="__STATE__" type="application/json">{ vue: { awesome: true } }</script>
@andoniabedul
Copy link
Author

@andoniabedul andoniabedul commented Sep 13, 2021

Code proposal, on https://github.com/vuejs/vue/blob/dev/src/server/template-renderer/index.js

 renderState (context: Object, options?: Object): string {
    const {
      plainStorage = null,
      contextKey = 'state',
      windowKey = '__INITIAL_STATE__'
    } = options || {}
    const state = this.serialize(context[contextKey])
    const autoRemove = process.env.NODE_ENV === 'production'
      ? ';(function(){var s;(s=document.currentScript||document.scripts[document.scripts.length-1]).parentNode.removeChild(s);}());'
      : ''
    const nonceAttr = context.nonce ? ` nonce="${context.nonce}"` : ''
    if(plainStorage) {
      return context[contextKey]
      ? `<script${nonceAttr} id="${plainStorage}" type="application/json">${state}${autoRemove}</script>`
      : ''
    }
    return context[contextKey]
      ? `<script${nonceAttr}>window.${windowKey}=${state}${autoRemove}</script>`
      : ''
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant