|
| 1 | +--- |
| 2 | +outline: deep |
| 3 | +--- |
| 4 | + |
| 5 | +# Performance Best Practices |
| 6 | + |
| 7 | +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. |
| 8 | + |
| 9 | +## Defer client assets |
| 10 | + |
| 11 | +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-<name>--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). |
| 12 | + |
| 13 | +```ts |
| 14 | +import type { RemoteAssets } from 'devframe' |
| 15 | +import pkg from '../package.json' with { type: 'json' } |
| 16 | + |
| 17 | +const distDir: RemoteAssets = { |
| 18 | + package: `${pkg.name}--assets`, |
| 19 | + version: pkg.version, |
| 20 | + resolveFrom: import.meta.url, // serve a locally installed copy with zero network |
| 21 | +} |
| 22 | +``` |
| 23 | + |
| 24 | +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)). |
| 25 | + |
| 26 | +## Keep `setup` cheap |
| 27 | + |
| 28 | +`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. |
| 29 | + |
| 30 | +## Stream large or growing results |
| 31 | + |
| 32 | +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. |
| 33 | + |
| 34 | +## Keep shared state small and serializable |
| 35 | + |
| 36 | +[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. |
| 37 | + |
| 38 | +## Return lean RPC payloads |
| 39 | + |
| 40 | +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. |
0 commit comments