Studio Docs

Performance + Bundle-Size Playbook

Studio adds runtime weight to your app. @contentstack/studio-react is a few hundred KB compressed, and @contentstack/live-preview-utils adds more. For most sites that’s fine. It’s the cost of authorability. For weight-sensitive surfaces (landing pages, AMP-style targets, edge-deployed routes) you can drop the runtime cost substantially with a small set of patterns.

Do It With a Skill

register-component registers lazily by default, which is the single biggest lever on bundle size here.

curl -fsSL https://studio-documentation.contentstackapps.com/install.sh | sh

The rest of this page is measurement and judgement, and no skill substitutes for profiling your own build.

The Model

Studio’s runtime weight has three layers:

  1. Authoring weight: the canvas iframe, the section preview machinery, post-message channels. Loaded by <StudioCanvas /> on the canvas route only.
  2. Visitor weight: what <StudioComponent /> ships to real visitor pages. Lighter than <StudioCanvas />, but still meaningfully bigger than a hand-coded render.
  3. Component weight: your own registered components, plus any dependencies they pull in.

Layer 1 only loads on the canvas route. Stop worrying about that one. It’s not in visitor pages. Layers 2 and 3 are where the win is.

Lazy-register heavy components

registerLazyComponent lets Studio defer the import until the component is actually placed on a page:

import { registerLazyComponent } from "@contentstack/studio-react";

registerLazyComponent(
  {
    type: "video-player",
    displayName: "Video Player",
    props: { /* … */ },
  },
  () => import("./components/VideoPlayer").then(m => m.default),   // only fetched when used
);

Use this for anything > 50 KB minified or that pulls in a heavy dependency (a chart library, a video player, a rich text renderer). Pages that don’t use the component pay zero weight for it.

Code-split per-route

Studio’s <StudioComponent /> should not be in your shared bundle. Mount it from a route file that’s automatically code-split by your framework (Next.js App Router page.tsx, Remix route files, Astro pages). The framework’s per-route splitting handles this for you. Just don’t accidentally import @contentstack/studio-react from a top-level layout.

Server-side resolution where possible

csStudio.fetchCompositionData(queryOptions, options) (the SSR path) returns the full spec server-side. Render the result to HTML at request time. Ship hydration data only. The CSR useCompositionData hook is convenient but adds runtime cost. Use it only when SSR isn’t an option (auth-gated content, runtime-only data).

See configure-csr-vs-ssr for the wiring.

Don’t ship Live Preview to visitors

@contentstack/live-preview-utils is for editors, not visitors. Gate ContentstackLivePreview.init() behind a check:

if (process.env.NEXT_PUBLIC_ENABLE_LIVE_PREVIEW === "true") {
  ContentstackLivePreview.init({ /* … */ });
}

Set the env var only in your preview/staging deployment. Production visitor pages never load the Live Preview channel, never pay its weight.

Measure before optimizing

Run a Next/Astro bundle analyzer or source-map-explorer against your production build. Confirm the actual weight Studio adds before guessing. Most of the time it’s smaller than you think. Sometimes a transitive dep blows up: measurement tells you which.

Patterns to Avoid

PatternWhy it bites
Importing @contentstack/studio-react from a top-level layoutDefeats code-splitting. Every route now ships Studio runtime
Eagerly registering every component up frontDefeats registerLazyComponent. Defeats per-route splitting
Bundling Live Preview into production buildsEditor-only weight in every visitor’s bundle
Using CSR useCompositionData for content that could be fetched server-sideAdds an extra round-trip + runtime cost. SSR is faster + lighter
Pre-loading all sections via linked_sections for SSRPulls down sections the route may never render. Only the sections in the composition’s UI tree are needed

What’s Still Unsolved

  • Tree-shaking Studio’s internal renderer. Some internal Studio modules can’t be tree-shaken effectively today. If your bundle analysis shows @contentstack/studio-react larger than expected, file an issue with your analyzer output. The SDK team prioritizes these.
  • Edge-runtime size limits. Studio currently exceeds the Vercel Edge / Cloudflare Workers 1 MB limit on some configurations. For edge-deployed routes, use the Node runtime. See Production deployment edges.

See Also