`st.fragment(lazy=True)` — defer fragment execution until visible (viewport-triggered loading) · Issue #14788 · streamlit/streamlit · GitHub
Skip to content

st.fragment(lazy=True) — defer fragment execution until visible (viewport-triggered loading) #14788

@sfc-gh-lwilby

Description

@sfc-gh-lwilby

Summary

Add a lazy parameter to @st.fragment that defers fragment execution until the fragment's placeholder scrolls into the browser viewport. This is inspired by how Sigma Computing dashboards lazy-load visualizations — tiles below the fold don't execute their queries until the user scrolls them into view, dramatically reducing initial page load time for long dashboards.

Proposed API

@overload
def fragment(
    func: F,
    *,
    run_every: int | float | timedelta | str | None = None,
    parallel: bool = False,
    lazy: bool = False,
) -> F: ...

Usage example:

@st.fragment(lazy=True)
def expensive_chart():
    data = fetch_from_database()  # only runs when scrolled into view
    st.line_chart(data)

# Top of page — runs immediately
summary_metrics()

# Below the fold — deferred until user scrolls down
expensive_chart()
another_expensive_section()

Combined with parallel fragments:

@st.fragment(lazy=True, parallel=True)
def dashboard_card(query):
    data = run_query(query)
    st.metric(data["label"], data["value"])

# Visible row runs in parallel immediately
for q in visible_queries:
    dashboard_card(q)

# Below-the-fold row defers until scrolled into view,
# then runs its cards in parallel too
for q in more_queries:
    dashboard_card(q)

Use cases

  • Long dashboard pages with many SQL-backed sections — only the visible ones run queries on initial load, reducing total query cost and page load time.
  • Infinite-scroll-style apps with many sections where most content is below the fold.

Relationship to parallel fragments

Lazy fragments are orthogonal to parallel=True (#8490):

  • lazy controls when a fragment enters the execution pipeline (immediately vs. on viewport visibility).
  • parallel controls how scheduled fragments share the machine (sequential vs. concurrent threads).

Both can be True simultaneously. A dashboard's visible row of cards runs in parallel on initial load; the user scrolls down and the next row triggers lazily — and those should also run in parallel so they don't block each other.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature:st.fragmentRelated to `st.fragment` commandtype:enhancementRequests for feature enhancements or new features

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions