You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: Docs/README.MD
+7-7Lines changed: 7 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -110,7 +110,7 @@ We run this through npm:
110
110
npm run build-dotnet6
111
111
```
112
112
113
-
The resulting js bundle is build to the wwwroot folder in the DotNet6 project as react18example.js: https://github.com/knowit/SSR.Net/tree/main/src/SSR.Net.DotNet6/wwwroot
113
+
The resulting js bundle is built to the wwwroot folder in the DotNet6 project as react18example.js: https://github.com/knowit/SSR.Net/tree/main/src/SSR.Net.DotNet6/wwwroot
The code above adds both a server side polyfill named React18TextEncoderPolyfill.js (React 18 needs this, and it's missing in the Java Script Engine), and the bundle we created in [Building a JavaScript bundle fit for SSR](#Building-a-JavaScript-bundle-fit-for-SSR), react18example.js. These script files will be run on each server side JavaScript engine during initialization. This means that each JavaScript engine on the server side will be able to run React, ReactDOMServer, ReactDOMClient and access our FrontPage component through the global variable Components.
144
144
145
-
We use the V8 JavaScript engine in this example. This, and the scripts, is configured in a JavaScriptEnginePool. This pool will manage JavaScript engines, create new ones proactively, dispose exhausted engines and be a broker for the actual rendering commands.
145
+
We use the V8 JavaScript engine in this example. This, and the scripts, is configured in a JavaScriptEnginePool. This pool will manage JavaScript engines, create new ones proactively, dispose exhausted engines and forward the rendering calls to the JavaScript engines.
146
146
147
147
To make this work, we have to reference some packages in our web project:
@@ -227,7 +227,7 @@ The view is kept very simple (https://github.com/knowit/SSR.Net/blob/main/src/SS
227
227
</html>
228
228
```
229
229
230
-
Here we use RenderedComponent as our model. We set Layout to null, because we only use the markup in this file. We include the react18example.js script that we created in [Building a JavaScript bundle fit for SSR](#Building-a-JavaScript-bundle-fit-for-SSR) in a <script> tag in the <head> tag.
230
+
Here we use a RenderedComponent as our model. We set Layout to null, because we only use the markup in this file. We include the react18example.js script that we created in [Building a JavaScript bundle fit for SSR](#Building-a-JavaScript-bundle-fit-for-SSR) in a <script> tag in the <head> tag.
231
231
232
232
Inside the <body> tag, there are just two lines. The first one takes the HTML from our RenderedComponent and renders it as a raw string in the view. The second one takes the initialization script and renders it as a raw string inside a <script> tag.
233
233
@@ -237,7 +237,7 @@ When running the solution and visiting the React 18 view, we see that it's worki
237
237
238
238

239
239
240
-
If we view the source, we see that we get markup from the server and not just an empty <div>. We also see the initialization script, which instructs React to latch on to the DOM in the <div> with the markup by calling ReactDOMClient.hydrateRoot:
240
+
If we view the source, we see that we get markup from the server and not just an empty <div>. We also see the initialization script, which instructs React to latch on to the <div> with the markup by calling ReactDOMClient.hydrateRoot:
241
241
242
242

243
243
@@ -249,7 +249,7 @@ If the rendering was done without SSR, then the div would be empty and the initi
249
249
In order to be ready to render components quickly, SSR.Net ensures that a configurable number of JavaScript engines are initialized with a given JavaScript bundle. This is done when instantiating a new JavaScriptEnginePool. There are several thresholds controlling this:
250
250
* Minimum engines: When starting or reconfiguring SSR.Net, it will make sure there are at least this number of engines in the engine pool.
251
251
* Maximum engines: The number of engines in the engine pool will never exceed this threshold.
252
-
* Standby engines: The number of unoccupied (spare) engines in the pool.
252
+
* Standby engines: The number of vacant engines the pool should have (while not exceeding the maximum number of engines).
253
253
* Maximum engine usages: A given engine can be used this number of times before it gets disposed of.
254
254
255
255
There are methods to configure this when initializing the JavaScriptEnginePool:
@@ -272,7 +272,7 @@ Example:
272
272
Let's say we have configured a minimum of 5 engines, a maximum of 25 engines and 3 engines on standby. Before any requests come in, there will be 5 vacant engines.
273
273
Then 3 requests come in at the same time, occupying 3 engines. SSR.Net will see that there are only 2 engines on standby, and will initialize another engine to comply with the "3 engines on standby" requirement.
274
274
275
-
Traffic increases drastically, and at some point 23 engines are occupied concurrently. SSR.Net will ensure that there are 25 engines initialized, but will not exceed this threshold, to comply with the "maximum of 25 engines" requirement.
275
+
Traffic increases drastically, and at some point 23 engines are occupied concurrently. SSR.Net will ensure that there are 25 engines initialized, but will not exceed this threshold. This is to comply with the "maximum of 25 engines" requirement.
276
276
277
277
Then, there are only 2-3 concurrent requests for a long time. The engines will eventually be exhausted and disposed of, and the number of engines declines. At some point, there are only 5 engines left. The next time an engine gets exhausted, SSR.Net will dispose of it and see that there are only 4 engines left. Then SSR.Net will initialize a new engine to comply with the "minimum of 5 engines" requirement.
278
278
@@ -286,7 +286,7 @@ if (typeof window !== 'undefined')
286
286
```
287
287
* Global variables must not be used (except the ones described above for exposing objects to SSR.Net). Each JavaScript Engine is used multiple times, so global variables will cause state to be shared between requests, meaning data can leak from one user to another.
288
288
* Some 3rd party packages may fail, if they use the window object or global variables.
289
-
* SSR in React won't run useEffect hooks. So using the window object in a useEffect is safe. Also, if you have code that requires the window object and that doesn't contain markup that you need served from the server side, then you can defer including it to after the first contentful paint:
289
+
* SSR in React won't run useEffect hooks. So using the window object in a useEffect is safe. Also, if you have code that requires the window object and that doesn't contain markup that you need served from the server side, then you can defer rendering it until after the SSR has been performed:
0 commit comments