diff --git a/packages/subapp-web/lib/load.js b/packages/subapp-web/lib/load.js index caa5011b1..f987b5aff 100644 --- a/packages/subapp-web/lib/load.js +++ b/packages/subapp-web/lib/load.js @@ -24,6 +24,14 @@ const { loadSubAppByName, loadSubAppServerByName } = require("subapp-util"); // V1: version 1. const xarc = "window.xarcV1"; +// Size threshold of initial state string to embed it as a application/json script tag +// It's more efficent to JSON.parse large JSON data instead of embedding them as JS. +// https://quipblog.com/efficiently-loading-inlined-json-data-911960b0ac0a +// > The data sizes are as follows: large is 1.7MB of JSON, medium is 130K, +// > small is 10K and tiny is 781 bytes. +const INITIAL_STATE_SIZE_FOR_JSON = 1024; +let INITIAL_STATE_TAG_ID = 0; + module.exports = function setup(setupContext, { props: options }) { // TODO: create JSON schema to validate props @@ -203,12 +211,28 @@ module.exports = function setup(setupContext, { props: options }) { outputSpot.add(ssrContent); } + let dynInitialState = ""; + let initialStateScript; + if (!initialStateStr) { + initialStateScript = "{}"; + } else if (initialStateStr.length < INITIAL_STATE_SIZE_FOR_JSON) { + initialStateScript = initialStateStr; + } else { + // embed large initial state as text and parse with JSON.parse instead. + const dataId = `${name}-initial-state-${Date.now()}-${++INITIAL_STATE_TAG_ID}`; + dynInitialState = ` +`; + initialStateScript = `JSON.parse(document.getElementById("${dataId}").innerHTML)`; + } + outputSpot.add(` - `); };