Files
moeka-project/.agents/skills/pnpm/references/best-practices-performance.md
T

262 lines
5.2 KiB
Markdown

---
name: pnpm-performance-optimization
description: Tips and tricks for faster installs and better performance
---
# pnpm Performance Optimization
pnpm is fast by default, but these optimizations can make it even faster.
## Install Optimizations
### Use Frozen Lockfile
Skip resolution when lockfile exists:
```bash
pnpm install --frozen-lockfile
```
This is faster because pnpm skips the resolution phase entirely.
### Prefer Offline Mode
Use cached packages when available:
```bash
pnpm install --prefer-offline
```
### Skip Optional Dependencies
If you don't need optional deps:
```bash
pnpm install --no-optional
```
### Skip Scripts
For CI or when scripts aren't needed:
```bash
pnpm install --ignore-scripts
```
**Caution:** Some packages require postinstall scripts to work correctly.
### Only Build Specific Dependencies
Build-script approval is a single `allowBuilds` map (replaces `onlyBuiltDependencies`/`neverBuiltDependencies`). Only allowed packages run install scripts:
```yaml title="pnpm-workspace.yaml"
allowBuilds:
esbuild: true
'@swc/core': true
core-js: false # explicitly skip
```
Packages not listed are treated as unreviewed (blocked by default). See `features-supply-chain-security` for the full build-approval workflow.
## Store Optimizations
### Side Effects Cache
Cache native module build results (enabled by default):
```yaml title="pnpm-workspace.yaml"
sideEffectsCache: true
```
This caches the results of postinstall scripts, speeding up subsequent installs.
### Global Virtual Store
For many checkouts of the same repo (e.g. git worktrees / multiple agents), enable the global virtual store so each project's `node_modules` is just symlinks into one shared store — near-zero per-checkout cost. Auto-disabled in CI.
```yaml title="pnpm-workspace.yaml"
enableGlobalVirtualStore: true
```
### Shared Store
A single content-addressable store is used for all projects by default:
```yaml title="pnpm-workspace.yaml"
storeDir: ~/.local/share/pnpm/store
```
Benefits: packages downloaded once, hard links save disk space, faster cached installs.
### Store Maintenance
Periodically clean unused packages:
```bash
# Remove unreferenced packages
pnpm store prune
# Check store integrity
pnpm store status
```
## Workspace Optimizations
### Parallel Execution
Run workspace scripts in parallel:
```bash
pnpm -r --parallel run build
```
Control concurrency:
```yaml title="pnpm-workspace.yaml"
workspaceConcurrency: 8
```
### Stream Output
See output in real-time:
```bash
pnpm -r --stream run build
```
### Filter to Changed Packages
Only build what changed:
```bash
# Build packages changed since main branch
pnpm --filter "...[origin/main]" run build
```
### Topological Order
Build dependencies before dependents:
```bash
pnpm -r run build
# Automatically runs in topological order
```
For explicit sequential builds:
```bash
pnpm -r --workspace-concurrency=1 run build
```
## Network Optimizations
Network/registry settings are camelCase in `pnpm-workspace.yaml` (registry URLs may also go in `registries`):
```yaml title="pnpm-workspace.yaml"
registries:
default: https://registry.npmmirror.com/
fetchRetries: 3
fetchRetryMintimeout: 10000
fetchRetryMaxtimeout: 60000
networkConcurrency: 16 # auto: clamp(workers x 3, 16, 64)
httpProxy: http://proxy.company.com:8080
httpsProxy: http://proxy.company.com:8080
```
## Lockfile Optimization
### Single Lockfile (Monorepos)
Use shared lockfile for all packages (default):
```yaml title="pnpm-workspace.yaml"
sharedWorkspaceLockfile: true
```
Benefits:
- Single source of truth
- Faster resolution
- Consistent versions across workspace
### Lockfile-only Mode
Only update lockfile without installing:
```bash
pnpm install --lockfile-only
```
## Benchmarking
### Compare Install Times
```bash
# Clean install
rm -rf node_modules pnpm-lock.yaml
time pnpm install
# Cached install (with lockfile)
rm -rf node_modules
time pnpm install --frozen-lockfile
# With store cache
time pnpm install --frozen-lockfile --prefer-offline
```
### Profile Resolution
Debug slow installs:
```bash
# Verbose logging
pnpm install --reporter=append-only
# Debug mode
DEBUG=pnpm:* pnpm install
```
## Configuration Summary
Optimized `pnpm-workspace.yaml` for performance:
```yaml title="pnpm-workspace.yaml"
# Install behavior
autoInstallPeers: true
sideEffectsCache: true
optimisticRepeatInstall: true
# Build approval (only what's necessary)
allowBuilds:
esbuild: true
'@swc/core': true
# Network
fetchRetries: 3
networkConcurrency: 16
# Workspace
workspaceConcurrency: 4
# Many checkouts of the same repo
enableGlobalVirtualStore: true
```
## Quick Reference
| Scenario | Command/Setting |
|----------|-----------------|
| CI installs | `pnpm ci` / `pnpm install --frozen-lockfile` |
| Offline development | `--prefer-offline` |
| Control native builds | `allowBuilds` map |
| Parallel workspace | `pnpm -r --parallel run build` |
| Build changed only | `pnpm --filter "...[origin/main]" build` |
| Clean store | `pnpm store prune` |
| Many worktrees/agents | `enableGlobalVirtualStore: true` |
<!--
Source references:
- https://pnpm.io/settings
- https://pnpm.io/cli/install
- https://pnpm.io/filtering
- https://pnpm.io/global-virtual-store
-->