Skip to content

Commit c61ad65

Browse files
thePunderWomanAndrewKushnir
authored andcommitted
refactor(core): incremental hydration TODO cleanup (#59032)
This adds a few helper functions and ensures we call complete fns when error state is rendered. It also eliminates serialized views from being copied. PR Close #59032
1 parent 9085a8f commit c61ad65

File tree

2 files changed

+24
-42
lines changed

2 files changed

+24
-42
lines changed

packages/core/src/defer/rendering.ts

Lines changed: 20 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -223,17 +223,9 @@ function findMatchingDehydratedViewForDeferBlock(
223223
lContainer: LContainer,
224224
lDetails: LDeferBlockDetails,
225225
): DehydratedContainerView | null {
226-
// TODO(incremental-hydration): extract into a separate util function and use in relevant places.
227-
const views = lContainer[DEHYDRATED_VIEWS];
228-
if (views === null || views.length === 0) {
229-
return null;
230-
}
231-
232226
// Find matching view based on serialized defer block state.
233-
// TODO(incremental-hydration): reconcile this logic with the regular logic that looks up
234-
// dehydrated views to see if there is anything missing in this function.
235227
return (
236-
views.find(
228+
lContainer[DEHYDRATED_VIEWS]?.find(
237229
(view: any) => view.data[SERIALIZED_DEFER_BLOCK_STATE] === lDetails[DEFER_BLOCK_STATE],
238230
) ?? null
239231
);
@@ -279,41 +271,33 @@ function applyDeferBlockState(
279271
injector = createDeferBlockInjector(hostLView[INJECTOR], tDetails, providers);
280272
}
281273
}
282-
283274
const dehydratedView = findMatchingDehydratedViewForDeferBlock(lContainer, lDetails);
284-
// Render either when we don't have dehydrated views at all (e.g. client rendering)
285-
// or when dehydrated view is found (in which case we hydrate).
286-
// Otherwise, do nothing, since we'd end up erasing SSR'ed content.
287-
// TODO(incremental-hydration): Use the util function for checking dehydrated views mentioned above
288-
const isClientOnly =
289-
lContainer[DEHYDRATED_VIEWS] === null || lContainer[DEHYDRATED_VIEWS].length === 0;
290-
if (isClientOnly || dehydratedView) {
291-
// Erase dehydrated view info, so that it's not removed later
292-
// by post-hydration cleanup process.
293-
// TODO(incremental-hydration): we need a better mechanism here.
294-
lContainer[DEHYDRATED_VIEWS] = null;
295-
296-
const embeddedLView = createAndRenderEmbeddedLView(hostLView, activeBlockTNode, null, {
297-
injector,
298-
dehydratedView,
299-
});
300-
addLViewToLContainer(
301-
lContainer,
302-
embeddedLView,
303-
viewIndex,
304-
shouldAddViewToDom(activeBlockTNode, dehydratedView),
305-
);
306-
markViewDirty(embeddedLView, NotificationSource.DeferBlockStateUpdate);
307-
}
275+
// Erase dehydrated view info, so that it's not removed later
276+
// by post-hydration cleanup process.
277+
lContainer[DEHYDRATED_VIEWS] = null;
278+
279+
const embeddedLView = createAndRenderEmbeddedLView(hostLView, activeBlockTNode, null, {
280+
injector,
281+
dehydratedView,
282+
});
283+
addLViewToLContainer(
284+
lContainer,
285+
embeddedLView,
286+
viewIndex,
287+
shouldAddViewToDom(activeBlockTNode, dehydratedView),
288+
);
289+
markViewDirty(embeddedLView, NotificationSource.DeferBlockStateUpdate);
308290

309291
// TODO(incremental-hydration):
310292
// - what if we had some views in `lContainer[DEHYDRATED_VIEWS]`, but
311293
// we didn't find a view that matches the expected state?
312294
// - for example, handle a situation when a block was in the "completed" state
313295
// on the server, but the loading failing on the client. How do we reconcile and cleanup?
314296

315-
// TODO(incremental-hydration): should we also invoke if newState === DeferBlockState.Error?
316-
if (newState === DeferBlockState.Complete && Array.isArray(lDetails[ON_COMPLETE_FNS])) {
297+
if (
298+
(newState === DeferBlockState.Complete || newState === DeferBlockState.Error) &&
299+
Array.isArray(lDetails[ON_COMPLETE_FNS])
300+
) {
317301
for (const callback of lDetails[ON_COMPLETE_FNS]) {
318302
callback();
319303
}

packages/core/src/hydration/annotate.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,6 @@ export function annotateForHydration(appRef: ApplicationRef, doc: Document) {
303303

304304
if (deferBlocks.size > 0) {
305305
const blocks: {[key: string]: SerializedDeferBlock} = {};
306-
// TODO(incremental-hydration): we should probably have an object here instead of a Map?
307306
for (const [id, info] of deferBlocks.entries()) {
308307
blocks[id] = info;
309308
}
@@ -447,11 +446,10 @@ function serializeLContainer(
447446
}
448447

449448
if (!isHydrateNeverBlock) {
450-
// TODO(incremental-hydration): avoid copying of an object here
451-
serializedView = {
452-
...serializedView,
453-
...serializeLView(lContainer[i] as LView, parentDeferBlockId, context),
454-
};
449+
Object.assign(
450+
serializedView,
451+
serializeLView(lContainer[i] as LView, parentDeferBlockId, context),
452+
);
455453
}
456454
}
457455

0 commit comments

Comments
 (0)