react-async-ssr
Advanced tools
Comparing version 0.4.0 to 0.4.1
@@ -176,7 +176,24 @@ /* -------------------- | ||
// Suspend suspense and add to fallbacks queue if it is outside of current render cycle | ||
// Suspend suspense | ||
const {suspenseNode} = this; | ||
suspenseNode.suspended = true; | ||
if (!suspenseNode.frame) this.fallbacksQueue.push(suspenseNode); | ||
const suspenseFrame = suspenseNode.frame; | ||
if (!suspenseFrame) { | ||
// Outside current render cycle - Add to fallbacks queue | ||
this.fallbacksQueue.push(suspenseNode); | ||
} else if (this.fallbackFast) { | ||
// Suspense is in current render cycle and `fallbackFast` option set. | ||
// Skip all further rendering within current Suspense boundary. | ||
// Stack will unwind down to Suspense and fallback will be rendered. | ||
const {stack} = this; | ||
let stackIndex = stack.length - 1; | ||
while (true) { // eslint-disable-line no-constant-condition | ||
const frame = stack[stackIndex]; | ||
frame.childIndex = frame.children.length; | ||
if (frame === suspenseFrame) break; | ||
stackIndex--; | ||
} | ||
} | ||
// Abort all promises within Suspense and trigger fallbacks of nested Suspenses | ||
@@ -203,3 +220,4 @@ for (let child of suspenseNode.children) { | ||
if (!inLazy) { | ||
// NB If `fallbackFast` option set, do not suspend nested Suspenses | ||
if (!inLazy && !this.fallbackFast) { | ||
if (node.containsLazy) { | ||
@@ -206,0 +224,0 @@ node.suspended = true; |
@@ -13,8 +13,8 @@ /* -------------------- | ||
module.exports = { | ||
renderToStringAsync(element) { | ||
return render(element, false); | ||
renderToStringAsync(element, options) { | ||
return render(element, false, options); | ||
}, | ||
renderToStaticMarkupAsync(element) { | ||
return render(element, true); | ||
renderToStaticMarkupAsync(element, options) { | ||
return render(element, true, options); | ||
} | ||
@@ -27,6 +27,10 @@ }; | ||
* @param {boolean} makeStaticMarkup - `true` for a `renderToStaticMarkup()`-style render | ||
* @param {Object} [options] - Options object | ||
* @param {boolean} [options.fallbackFast=false] - `true` to bail out of Suspense | ||
* nodes as soon as suspended | ||
* @return {Promise} - Resolves to HTML result of render | ||
*/ | ||
function render(element, makeStaticMarkup) { | ||
const renderer = new Renderer(element, makeStaticMarkup); | ||
function render(element, makeStaticMarkup, options) { | ||
const fallbackFast = !!(options && options.fallbackFast); | ||
const renderer = new Renderer(element, makeStaticMarkup, fallbackFast); | ||
@@ -33,0 +37,0 @@ return new Promise((resolve, reject) => { |
@@ -28,6 +28,10 @@ /* -------------------- | ||
* @param {boolean} makeStaticMarkup - `true` for equivalent of `renderToStaticMarkup()` | ||
* @param {boolean} fallbackFast - `true` to bail out of Suspense nodes as soon as suspended | ||
*/ | ||
constructor(children, makeStaticMarkup) { | ||
constructor(children, makeStaticMarkup, fallbackFast) { | ||
super(children, makeStaticMarkup); | ||
// Record options | ||
this.fallbackFast = fallbackFast; | ||
// Init boundary tree | ||
@@ -34,0 +38,0 @@ const tree = { |
{ | ||
"name": "react-async-ssr", | ||
"version": "0.4.0", | ||
"version": "0.4.1", | ||
"description": "Render React Suspense on server", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -65,3 +65,3 @@ [![NPM version](https://img.shields.io/npm/v/react-async-ssr.svg)](https://www.npmjs.com/package/react-async-ssr) | ||
const html = await ReactDOM.renderToStringAsync(<App />); | ||
const html = await ReactDOMServer.renderToStringAsync(<App />); | ||
``` | ||
@@ -147,3 +147,3 @@ | ||
const html = await ReactDOM.renderToStringAsync(<App />); | ||
const html = await ReactDOMServer.renderToStringAsync(<App />); | ||
``` | ||
@@ -198,3 +198,3 @@ | ||
If the promise has this property, the component will not be rendered and the next Suspense boundary above's fallback will be triggered. | ||
If the promise has this property, the component will not be rendered and the enclosing Suspense boundary's fallback will be triggered. | ||
@@ -223,4 +223,28 @@ ```js | ||
### Aborting unnecessary loading | ||
#### Optimization: Bail out of rendering when suspended | ||
When a `[NO_SSR]` promise is thrown, default behavior is to continue rendering the rest of the Suspense boundary. | ||
However, this content will not be output as the Suspense fallback will be rendered and output instead. | ||
As an optimization, you can cause the render to bail out of rendering all further content within the Suspense as soon as the fallback is triggered, by providing a `fallbackFast` option to `.renderToStringAsync()`. | ||
```js | ||
function App() { | ||
return ( | ||
<React.Suspense fallback={<div>Loading...</div>}> | ||
<LazyNoSSR/> <!-- throws `[NO_SSR]` promise --> | ||
<LazySSR/> <!-- will not be rendered --> | ||
</React.Suspense> | ||
); | ||
} | ||
const html = await ReactDOMServer.renderToStringAsync( | ||
<App />, | ||
{fallbackFast: true} | ||
); | ||
``` | ||
#### Optimization: Aborting unnecessary loading | ||
It's possible for a lazy component to begin loading, but then its result not to be required, because an enclosing Suspense boundary's fallback gets triggered. If so the result will not be displayed. | ||
@@ -227,0 +251,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
43941
923
302