@@ -37,7 +37,7 @@ type RootComponentInfo = {
37
37
assignedRendererId ?: WebRendererId ;
38
38
uniqueIdAtLastUpdate ?: number ;
39
39
interactiveComponentId ?: number ;
40
- }
40
+ } ;
41
41
42
42
export class WebRootComponentManager implements DescriptorHandler , RootComponentManager < never > {
43
43
private readonly _rootComponents = new Set < RootComponentInfo > ( ) ;
@@ -193,7 +193,7 @@ export class WebRootComponentManager implements DescriptorHandler, RootComponent
193
193
}
194
194
195
195
private circuitMayHaveNoRootComponents ( ) {
196
- const isCircuitInUse = this . hasAnyExistingOrPendingServerComponents ( ) ;
196
+ const isCircuitInUse = this . rendererHasExistingOrPendingComponents ( WebRendererId . Server , 'server' , 'auto' ) ;
197
197
if ( isCircuitInUse ) {
198
198
// Clear the timeout because we know the circuit is in use.
199
199
clearTimeout ( this . _circuitInactivityTimeoutId ) ;
@@ -208,31 +208,38 @@ export class WebRootComponentManager implements DescriptorHandler, RootComponent
208
208
209
209
// Start a new timeout to dispose the circuit unless it starts getting used.
210
210
this . _circuitInactivityTimeoutId = setTimeout ( ( ) => {
211
- if ( ! this . hasAnyExistingOrPendingServerComponents ( ) ) {
211
+ if ( ! this . rendererHasExistingOrPendingComponents ( WebRendererId . Server , 'server' , 'auto' ) ) {
212
212
disposeCircuit ( ) ;
213
213
this . _circuitInactivityTimeoutId = undefined ;
214
214
}
215
215
} , this . _circuitInactivityTimeoutMs ) as unknown as number ;
216
216
}
217
217
218
- private hasAnyExistingOrPendingServerComponents ( ) : boolean {
219
- // If there are active Blazor Server components on the page, we shouldn't dispose the circuit.
220
- const renderer = getRendererer ( WebRendererId . Server ) ;
221
- if ( renderer && renderer . getRootComponentCount ( ) > 0 ) {
218
+ private rendererHasComponents ( rendererId : WebRendererId ) : boolean {
219
+ const renderer = getRendererer ( rendererId ) ;
220
+ return renderer !== undefined && renderer . getRootComponentCount ( ) > 0 ;
221
+ }
222
+
223
+ private rendererHasExistingOrPendingComponents ( rendererId : WebRendererId , ...descriptorTypesToConsider : ComponentMarker [ 'type' ] [ ] ) : boolean {
224
+ if ( this . rendererHasComponents ( rendererId ) ) {
222
225
return true ;
223
226
}
224
227
225
- // If we have SSR components that may become Blazor Server components in the future,
226
- // we shouldn't dispose the circuit.
228
+ // We consider SSR'd components on the page that may get activated using the specified renderer.
227
229
for ( const { descriptor : { type } , assignedRendererId } of this . _rootComponents ) {
228
- if ( assignedRendererId === WebRendererId . Server ) {
229
- // The component has been assigned to use Blazor Server .
230
+ if ( assignedRendererId === rendererId ) {
231
+ // The component has been assigned to use the specified renderer .
230
232
return true ;
231
233
}
232
234
233
- if ( assignedRendererId === undefined && ( type === 'auto' || type === 'server' ) ) {
234
- // The component has not been assigned a renderer yet, so it's possible it might
235
- // use Blazor Server.
235
+ if ( assignedRendererId !== undefined ) {
236
+ // The component has been assigned to use another renderer.
237
+ continue ;
238
+ }
239
+
240
+ if ( descriptorTypesToConsider . indexOf ( type ) !== - 1 ) {
241
+ // The component has not been assigned a renderer yet, but it might get activated with the specified renderer
242
+ // if it doesn't get removed from the page.
236
243
return true ;
237
244
}
238
245
}
@@ -298,9 +305,20 @@ export class WebRootComponentManager implements DescriptorHandler, RootComponent
298
305
}
299
306
300
307
private getAutoRenderMode ( ) : 'webassembly' | 'server' | null {
301
- // If the WebAssembly runtime has loaded, we will always use WebAssembly
302
- // for auto components. Otherwise, we'll wait to activate root components
303
- // until we determine whether the WebAssembly runtime can be loaded quickly.
308
+ // If WebAssembly components exist or may exist soon, use WebAssembly.
309
+ if ( this . rendererHasExistingOrPendingComponents ( WebRendererId . WebAssembly , 'webassembly' ) ) {
310
+ return 'webassembly' ;
311
+ }
312
+
313
+ // If Server components exist or may exist soon, use WebAssembly.
314
+ if ( this . rendererHasExistingOrPendingComponents ( WebRendererId . Server , 'server' ) ) {
315
+ return 'server' ;
316
+ }
317
+
318
+ // If no interactive components are on the page, we use WebAssembly
319
+ // if the WebAssembly runtime has loaded. Otherwise, we'll wait to activate
320
+ // root components until we determine whether the WebAssembly runtime can be
321
+ // loaded quickly.
304
322
if ( hasLoadedWebAssemblyPlatform ( ) ) {
305
323
return 'webassembly' ;
306
324
}
0 commit comments