Portals & deferred UI
Goal
Render into named slots (Portal / PortalMount), split narrow/main columns with
SplitView, and mark lower-priority subtrees with DeferredFragment when
Streamlit exposes st.fragment.
Portals
Read the contract in Phase 2 portals & prefetch. Portals let you gather children in one pass and mount them elsewhere in the shell (sidebar, dialog targets, etc.) while keeping a single StreamTree tree.
Deferred fragments
DeferredFragment wraps children in st.fragment when available so reruns can
isolate expensive regions. Demo:
"""Deferred region via :class:`DeferredFragment` (``st.fragment`` when available).
Run: ``streamlit run examples/deferred_region_demo.py``
On Streamlit builds with ``st.fragment``, children render inside a fragment for
lower scheduling priority; otherwise they render inline like a normal subtree.
"""
from __future__ import annotations
from streamtree import component, render
from streamtree.core.element import Element
from streamtree.elements import DeferredFragment, Page, Text, VStack
@component
def DeferredRegionDemo() -> Element:
heavy = tuple(Text(f"Row {i}") for i in range(12))
return Page(
VStack(
Text("## DeferredFragment demo"),
Text("Heavy block below is wrapped for fragment scheduling when supported."),
DeferredFragment(*heavy),
)
)
if __name__ == "__main__":
render(Page(DeferredRegionDemo()))
Composite layout stress test
phase2_composite_demo.py mixes Routes, ErrorBoundary, submit_many, and
shell-friendly structure—use it as a “kitchen sink” reference when learning portals-adjacent
patterns.
See also
- Async & loading
- Performance — large-tree + fragment guidance
- Examples