@decocms/start 0.37.2 → 0.37.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/routes/cmsRoute.ts +14 -108
package/package.json
CHANGED
package/src/routes/cmsRoute.ts
CHANGED
|
@@ -544,66 +544,19 @@ export function cmsRouteConfig(options: CmsRouteOptions) {
|
|
|
544
544
|
await preloadSectionComponents(keys);
|
|
545
545
|
}
|
|
546
546
|
|
|
547
|
-
//
|
|
548
|
-
//
|
|
549
|
-
//
|
|
547
|
+
// Deferred sections use client-side IntersectionObserver loading.
|
|
548
|
+
// DecoPageRenderer renders skeletons (LoadingFallback) during SSR and
|
|
549
|
+
// loads full section content via _serverFn when scrolled into view.
|
|
550
550
|
//
|
|
551
|
-
//
|
|
552
|
-
//
|
|
553
|
-
//
|
|
554
|
-
//
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
url: page.pageUrl ?? serverUrl.toString(),
|
|
561
|
-
path: page.pagePath ?? basePath,
|
|
562
|
-
cookies: getCookies(),
|
|
563
|
-
request: originRequest,
|
|
564
|
-
};
|
|
565
|
-
const deferredRequest = new Request(page.pageUrl ?? serverUrl.toString(), {
|
|
566
|
-
headers: originRequest.headers,
|
|
567
|
-
});
|
|
568
|
-
|
|
569
|
-
const deferredPromises: Record<string, Promise<ResolvedSection | null>> = {};
|
|
570
|
-
for (const ds of page.deferredSections) {
|
|
571
|
-
deferredPromises[`d_${ds.index}`] = resolveDeferredSectionFull(
|
|
572
|
-
ds,
|
|
573
|
-
page.pagePath ?? basePath,
|
|
574
|
-
deferredRequest,
|
|
575
|
-
matcherCtx,
|
|
576
|
-
).catch((e) => {
|
|
577
|
-
console.error(`[CMS] Deferred section "${ds.component}" failed:`, e);
|
|
578
|
-
return null;
|
|
579
|
-
});
|
|
580
|
-
}
|
|
581
|
-
return { ...page, deferredPromises };
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
// Client SPA navigation: resolve all deferred sections via server
|
|
585
|
-
// function batch and merge into resolvedSections for immediate render.
|
|
586
|
-
if (!isServer && page.deferredSections?.length) {
|
|
587
|
-
const resolved = await Promise.all(
|
|
588
|
-
page.deferredSections.map((ds: DeferredSection) =>
|
|
589
|
-
loadDeferredSection({
|
|
590
|
-
data: {
|
|
591
|
-
component: ds.component,
|
|
592
|
-
rawProps: ds.rawProps,
|
|
593
|
-
pagePath: page.pagePath ?? basePath,
|
|
594
|
-
pageUrl: page.pageUrl,
|
|
595
|
-
index: ds.index,
|
|
596
|
-
},
|
|
597
|
-
}).catch(() => null),
|
|
598
|
-
),
|
|
599
|
-
);
|
|
600
|
-
const all = [
|
|
601
|
-
...page.resolvedSections,
|
|
602
|
-
...resolved.filter((s): s is ResolvedSection => s != null),
|
|
603
|
-
].sort((a, b) => (a.index ?? 0) - (b.index ?? 0));
|
|
604
|
-
return { ...page, resolvedSections: all, deferredSections: [] };
|
|
605
|
-
}
|
|
606
|
-
|
|
551
|
+
// Previously, SSR streaming via TanStack <Await> resolved ALL deferred
|
|
552
|
+
// sections server-side and streamed them in the initial HTML. This caused
|
|
553
|
+
// the browser to load ALL product shelf images at once (~3x more image
|
|
554
|
+
// requests than the IntersectionObserver path). Client SPA navigation
|
|
555
|
+
// also blocked on await Promise.all() for all deferred sections.
|
|
556
|
+
//
|
|
557
|
+
// The IO path (DeferredSectionWrapper) only fetches section data when
|
|
558
|
+
// the skeleton scrolls into view, matching Fresh/Deno partial behavior
|
|
559
|
+
// and significantly reducing initial image load and TBT.
|
|
607
560
|
return page;
|
|
608
561
|
},
|
|
609
562
|
|
|
@@ -653,55 +606,8 @@ export function cmsHomeRouteConfig(options: {
|
|
|
653
606
|
await preloadSectionComponents(keys);
|
|
654
607
|
}
|
|
655
608
|
|
|
656
|
-
//
|
|
657
|
-
|
|
658
|
-
const originRequest = getRequest();
|
|
659
|
-
const serverUrl = getRequestUrl();
|
|
660
|
-
const matcherCtx: MatcherContext = {
|
|
661
|
-
userAgent: getRequestHeader("user-agent") ?? "",
|
|
662
|
-
url: page.pageUrl ?? serverUrl.toString(),
|
|
663
|
-
path: "/",
|
|
664
|
-
cookies: getCookies(),
|
|
665
|
-
request: originRequest,
|
|
666
|
-
};
|
|
667
|
-
const deferredRequest = new Request(page.pageUrl ?? serverUrl.toString(), {
|
|
668
|
-
headers: originRequest.headers,
|
|
669
|
-
});
|
|
670
|
-
|
|
671
|
-
const deferredPromises: Record<string, Promise<ResolvedSection | null>> = {};
|
|
672
|
-
for (const ds of page.deferredSections) {
|
|
673
|
-
deferredPromises[`d_${ds.index}`] = resolveDeferredSectionFull(
|
|
674
|
-
ds, "/", deferredRequest, matcherCtx,
|
|
675
|
-
).catch((e) => {
|
|
676
|
-
console.error(`[CMS] Deferred section "${ds.component}" failed:`, e);
|
|
677
|
-
return null;
|
|
678
|
-
});
|
|
679
|
-
}
|
|
680
|
-
return { ...page, deferredPromises };
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
// Client SPA navigation: resolve all deferred via server function batch
|
|
684
|
-
if (!isServer && page.deferredSections?.length) {
|
|
685
|
-
const resolved = await Promise.all(
|
|
686
|
-
page.deferredSections.map((ds: DeferredSection) =>
|
|
687
|
-
loadDeferredSection({
|
|
688
|
-
data: {
|
|
689
|
-
component: ds.component,
|
|
690
|
-
rawProps: ds.rawProps,
|
|
691
|
-
pagePath: "/",
|
|
692
|
-
pageUrl: page.pageUrl,
|
|
693
|
-
index: ds.index,
|
|
694
|
-
},
|
|
695
|
-
}).catch(() => null),
|
|
696
|
-
),
|
|
697
|
-
);
|
|
698
|
-
const all = [
|
|
699
|
-
...page.resolvedSections,
|
|
700
|
-
...resolved.filter((s): s is ResolvedSection => s != null),
|
|
701
|
-
].sort((a, b) => (a.index ?? 0) - (b.index ?? 0));
|
|
702
|
-
return { ...page, resolvedSections: all, deferredSections: [] };
|
|
703
|
-
}
|
|
704
|
-
|
|
609
|
+
// Deferred sections use client-side IntersectionObserver loading.
|
|
610
|
+
// See cmsRouteConfig loader for rationale.
|
|
705
611
|
return page;
|
|
706
612
|
},
|
|
707
613
|
...(options.pendingComponent ? { pendingComponent: options.pendingComponent } : {}),
|