Include all :data page component deps in every page's client bundle
Per-page bundling now unions deps from all :data pages in the service, so navigating between data pages uses client-side rendering + cache instead of expensive server fetch + SX parse. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -740,8 +740,9 @@ def sx_page(ctx: dict, page_sx: str, *,
|
||||
from .jinja_bridge import components_for_page, css_classes_for_page
|
||||
from .css_registry import lookup_rules, get_preamble, registry_loaded, store_css_hash
|
||||
|
||||
# Per-page component bundle: only definitions this page needs
|
||||
component_defs, component_hash = components_for_page(page_sx)
|
||||
# Per-page component bundle: this page's deps + all :data page deps
|
||||
from quart import current_app as _ca
|
||||
component_defs, component_hash = components_for_page(page_sx, service=_ca.name)
|
||||
|
||||
# Check if client already has this version cached (via cookie)
|
||||
# In dev mode, always send full source so edits are visible immediately
|
||||
@@ -755,7 +756,7 @@ def sx_page(ctx: dict, page_sx: str, *,
|
||||
sx_css_classes = ""
|
||||
sx_css_hash = ""
|
||||
if registry_loaded():
|
||||
classes = css_classes_for_page(page_sx)
|
||||
classes = css_classes_for_page(page_sx, service=_ca.name)
|
||||
# Always include body classes
|
||||
classes.update(["bg-stone-50", "text-stone-900"])
|
||||
rules = lookup_rules(classes)
|
||||
|
||||
@@ -332,17 +332,32 @@ def client_components_tag(*names: str) -> str:
|
||||
return f'<script type="text/sx" data-components>{source}</script>'
|
||||
|
||||
|
||||
def components_for_page(page_sx: str) -> tuple[str, str]:
|
||||
def components_for_page(page_sx: str, service: str | None = None) -> tuple[str, str]:
|
||||
"""Return (component_defs_source, page_hash) for a page.
|
||||
|
||||
Scans *page_sx* for component references, computes the transitive
|
||||
closure, and returns only the definitions needed for this page.
|
||||
|
||||
When *service* is given, also includes deps for all :data pages
|
||||
in that service so the client can render them without a server
|
||||
roundtrip on navigation.
|
||||
|
||||
The hash is computed from the page-specific bundle for caching.
|
||||
"""
|
||||
from .deps import components_needed
|
||||
from .parser import serialize
|
||||
|
||||
needed = components_needed(page_sx, _COMPONENT_ENV)
|
||||
|
||||
# Include deps for all :data pages so the client can render them
|
||||
if service:
|
||||
from .pages import get_all_pages
|
||||
for page_def in get_all_pages(service).values():
|
||||
if page_def.data_expr is not None and page_def.content_expr is not None:
|
||||
content_src = serialize(page_def.content_expr)
|
||||
data_deps = components_needed(content_src, _COMPONENT_ENV)
|
||||
needed |= data_deps
|
||||
|
||||
if not needed:
|
||||
return "", ""
|
||||
|
||||
@@ -375,16 +390,24 @@ def components_for_page(page_sx: str) -> tuple[str, str]:
|
||||
return source, digest
|
||||
|
||||
|
||||
def css_classes_for_page(page_sx: str) -> set[str]:
|
||||
def css_classes_for_page(page_sx: str, service: str | None = None) -> set[str]:
|
||||
"""Return CSS classes needed for a page's component bundle + page source.
|
||||
|
||||
Instead of unioning ALL component CSS classes, only includes classes
|
||||
from components the page actually uses.
|
||||
from components the page actually uses (plus all :data page deps).
|
||||
"""
|
||||
from .deps import components_needed
|
||||
from .css_registry import scan_classes_from_sx
|
||||
from .parser import serialize
|
||||
|
||||
needed = components_needed(page_sx, _COMPONENT_ENV)
|
||||
|
||||
if service:
|
||||
from .pages import get_all_pages
|
||||
for page_def in get_all_pages(service).values():
|
||||
if page_def.data_expr is not None and page_def.content_expr is not None:
|
||||
content_src = serialize(page_def.content_expr)
|
||||
needed |= components_needed(content_src, _COMPONENT_ENV)
|
||||
classes: set[str] = set()
|
||||
|
||||
for key, val in _COMPONENT_ENV.items():
|
||||
|
||||
Reference in New Issue
Block a user