Esc

Loading Strategies

Streak.js offers three ways to control when a widget's HTML and JS reach the browser. Each strategy trades off initial payload size against time-to-interactive.


Default (No loadingStrategy)

When a widget has no loadingStrategy field in the sitemap, both its HTML and JS are part of the initial page load.

{
  "id": "HelloBanner",
  "type": "HelloBanner"
}

Behavior:

  • HTML is rendered at build time and included in the initial HTML payload.
  • JS (Script components) executes immediately when the browser parses the page.
  • app.js processes this widget first, before any lazy widgets.

Best for: above-the-fold content, hero sections, navigation, anything the user sees immediately.


Lazy (loadingStrategy: "lazy")

The widget's HTML is still in the initial payload, but app.js defers loading its JS assets until after the page is interactive.

{
  "id": "HelloMessage",
  "type": "HelloMessage",
  "loadingStrategy": "lazy"
}

Behavior:

  • HTML is rendered at build time and present in the initial HTML.
  • JS assets are queued and loaded after all default (eager) widgets finish.
  • The user sees the widget's HTML immediately, but interactivity arrives later.

Best for: below-the-fold sections that need HTML for SEO or first paint, but whose JS can wait.


Dynamic Component

Content is removed from the initial HTML entirely. A placeholder element is rendered instead, and the content is injected on demand via gDom.loadDynamicComponent().

import { Dynamic, Script } from "streak/components";

<Dynamic id="nav-submenu">
  <ul>
    <li>Item A</li>
    <li>Item B</li>
  </ul>
</Dynamic>

<Script id="nav-submenu-trigger">
  {(gDom: any) => {
    document.getElementById("nav-btn")
      ?.addEventListener("click", () => {
        gDom.loadDynamicComponent("nav-submenu", () => {
          console.info("submenu injected");
        });
      });
  }}
</Script>

Behavior:

  • At build time, children are stripped from the HTML. A placeholder with component-type="__dynamicWidgetType__" is emitted.
  • At runtime, calling gDom.loadDynamicComponent(id, callback) injects the content into the placeholder.
  • Nothing loads until your code explicitly triggers it.

Best for: modals, menus, overlays, or any content that should not be in the initial HTML payload.


Comparison Table

HTML in initial payloadJS loadedTriggered by
Default (no loadingStrategy)YesImmediately on page loadAutomatic
Lazy (loadingStrategy: "lazy")YesAfter page is interactiveAutomatic (deferred)
Dynamic (<Dynamic> component)NoOn demandgDom.loadDynamicComponent()

When to Use Which

ScenarioStrategy
Hero banner, primary navigation, LCP contentDefault
Footer, testimonials section, analytics scriptsLazy
Modal dialogs, dropdown menus, accordion panelsDynamic
Content that must be in the HTML for SEODefault or Lazy
Content that hurts initial page weightDynamic

A single page can mix all three strategies. Use default for critical above-the-fold widgets, lazy for visible-but-non-urgent sections, and dynamic for content that only appears on interaction.