From 06e71140631f0c756652c7bb8514cc87fa0c03d3 Mon Sep 17 00:00:00 2001 From: "Anthony Fu (via agent)" Date: Sun, 16 Aug 2026 23:04:23 +0000 Subject: [PATCH] docs: add Performance Best Practices guide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A concise set of performance habits for a devframe tool — deferring a plugin's client assets into a lockstep '${name}--assets' package (bundle size), keeping setup cheap, streaming large results, keeping shared state small/serializable, and returning lean RPC payloads — each a short, self-contained tip. --- docs/.vitepress/config.ts | 6 ++++++ docs/guide/performance.md | 40 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 docs/guide/performance.md diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 62f948ab..7d0075f5 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -41,6 +41,12 @@ function guideGroups(prefix: string) { { text: 'Deep Linking', link: `${prefix}/guide/deep-linking` }, ], }, + { + text: 'Performance', + items: [ + { text: 'Performance Best Practices', link: `${prefix}/guide/performance` }, + ], + }, { text: 'JSON-Render', items: [ diff --git a/docs/guide/performance.md b/docs/guide/performance.md new file mode 100644 index 00000000..3c6a4bab --- /dev/null +++ b/docs/guide/performance.md @@ -0,0 +1,40 @@ +--- +outline: deep +--- + +# Performance Best Practices + +A few habits keep a devframe tool small to install and light to run. Each tip below stands on its own — adopt the ones that fit your tool. + +## Defer client assets + +A plugin's prebuilt SPA is usually ~90% of its npm tarball (the inspector: ~370 KB of UI against ~40 KB of node code). Ship it in a lockstep `@devframes/plugin---assets` package instead, and point `cli.distDir` at it — the UI is then served on demand through devframe's caching CDN back-proxy, so installing the node package drops to a fraction of the size (inspect: ~409 KB → ~18 KB). + +```ts +import type { RemoteAssets } from 'devframe' +import pkg from '../package.json' with { type: 'json' } + +const distDir: RemoteAssets = { + package: `${pkg.name}--assets`, + version: pkg.version, + resolveFrom: import.meta.url, // serve a locally installed copy with zero network +} +``` + +Resolution falls through installed package → on-disk cache → CDN, so the first visit fetches each file once and caches it. For offline or air-gapped use, `npm install` the `--assets` package (or set `offline: true`) and it's served locally. `package`/`version` are validated ([`DF0065`](../errors/DF0065)). + +## Keep `setup` cheap + +`setup` runs on every server start. Register RPC functions there, but defer expensive work — indexing, file watching, spawning processes — until a call actually needs it. A fast `setup` keeps startup and hot-reload snappy. + +## Stream large or growing results + +For large or incrementally-produced data, use a [streaming channel](./streaming) instead of returning one big value. The client renders as chunks arrive and node-side memory stays bounded, rather than buffering the whole payload. + +## Keep shared state small and serializable + +[Shared state](./shared-state) is synced to every connected client on change. Store identifiers and small summaries, and let clients fetch detail on demand via [RPC](./rpc), rather than mirroring large structures into state. + +## Return lean RPC payloads + +An RPC result is serialized and sent per call. Return only the fields the UI renders; page or filter server-side instead of shipping a whole dataset the client will slice. Cache results that are expensive to compute and safe to reuse.