92 lines
5.0 KiB
Markdown
92 lines
5.0 KiB
Markdown
# Performance and resource observations
|
||
|
||
ffmpeg.wasm runs native media code compiled to WebAssembly. It is normally much
|
||
slower than desktop FFmpeg and may hold source, decoded frames, filters and
|
||
output at once. No hardware encoder is used.
|
||
|
||
## Fixed download footprint
|
||
|
||
Uncompressed self-hosted core assets for
|
||
`0.12.10-reviewed-stack5m.1`:
|
||
|
||
| Mode | JavaScript/worker | WASM | Total |
|
||
| ------------- | ------------------: | -----------: | -----------: |
|
||
| single-thread | 111,804 B | 32,232,580 B | 32,344,384 B |
|
||
| multithread | 128,953 B + 2,115 B | 32,718,455 B | 32,849,523 B |
|
||
|
||
Only the selected mode is loaded. HTTP compression may reduce JavaScript
|
||
transfer but not necessarily WASM to the same degree; report transfer and
|
||
decoded sizes separately. Versioned core assets may be cached immutably.
|
||
|
||
## Benchmark record
|
||
|
||
One opt-in pinned-core baseline was recorded on 2026-07-24 with Chrome for
|
||
Testing 149.0.7827.55 (Playwright 1.61.1), Linux 7.0.0-28 on Ubuntu 24.04,
|
||
Intel Core i7-8700 (6 cores/12 threads) and 31 GiB RAM.
|
||
`navigator.hardwareConcurrency` reported 12 and every sample was
|
||
cross-origin-isolated. Each row used a fresh browser context; the first core
|
||
fetch may populate the browser HTTP cache, so later rows are explicitly
|
||
potentially warm-cache observations.
|
||
|
||
Preset: MP4, H.264/libx264 CRF 23 medium, AAC. Times are milliseconds.
|
||
“Export end-to-end” spans the Convert click through result construction,
|
||
cleanup, verification re-probe and visible result. The three narrower engine
|
||
columns come from the export validation report.
|
||
|
||
| Source | Input bytes | Mode | Init | Probe | FFmpeg exec | Output read | Cleanup | Export end-to-end | Output bytes | Observed JS heap |
|
||
| --------------------------------------- | ----------: | ----------------- | ----: | ----: | ----------: | ----------: | ------: | ----------------: | -----------: | ---------------: |
|
||
| 2 s, 160×90 H.264/AAC synthetic pattern | 34,057 | ST | 294.4 | 131.4 | 315.6 | 1.0 | 1.2 | 422.4 | 68,700 | 10,000,000 B |
|
||
| same | 34,057 | MT (`-threads 2`) | 914.5 | 126.4 | 294.3 | 1.3 | 1.9 | 416.8 | 68,753 | 10,000,000 B |
|
||
| 6 s, 640×360 H.264/AAC synthetic loop | 526,632 | ST | 270.2 | 163.6 | 6,854.1 | 1.3 | 0.8 | 7,030.9 | 585,981 | 15,200,000 B |
|
||
| same | 526,632 | MT (`-threads 2`) | 946.3 | 121.6 | 4,053.1 | 1.6 | 0.5 | 4,497.5 | 585,884 | 11,200,000 B |
|
||
|
||
Command:
|
||
|
||
```sh
|
||
npm run benchmark:browser
|
||
```
|
||
|
||
Result: **1 passed (18.2 s)**; test body 17.6 s. Chromium exposed
|
||
`performance.memory.usedJSHeapSize`, but this coarse post-operation value is
|
||
not a peak-WASM-memory measurement. One run is not a statistical distribution;
|
||
cold-cache repetitions, median/range, mobile and other-browser measurements
|
||
remain release-quality evidence gaps. Never present this workstation as a
|
||
universal promise.
|
||
|
||
## Measurement boundaries
|
||
|
||
- initialization: wrapper construction through successful capability query;
|
||
- probe: input mount/write through parsed ffprobe JSON;
|
||
- conversion: accepted command through exit code;
|
||
- output read: exit through Blob/result construction;
|
||
- cleanup: final result read through job directory unmount/delete;
|
||
- cancellation: cancel request through worker termination and recoverable idle
|
||
state (fresh-engine load is a separate measure).
|
||
|
||
Progress events are experimental estimates and not a timer. Use monotonic
|
||
browser timing around lifecycle boundaries.
|
||
|
||
## Product limits
|
||
|
||
Default soft input warning is 256 MiB; hard single/total input is 1.5 GiB.
|
||
Estimated output warns at 512 MiB and is blocked at 1 GiB. FFmpeg jobs are
|
||
serial; the application retains at most eight scheduled operations in its
|
||
in-memory queue. Timeline clips are capped at 100, streams per input at 64,
|
||
images at 8192×8192/67,108,864 pixels, generated output files at 255,
|
||
contact-sheet cells at 500, scene-change results at 100, crossfades at 10
|
||
seconds and runtime at four hours. Scene selection is a bounded two-step
|
||
workflow but its analysis step can still decode the complete source when few
|
||
frames meet the threshold. The documented ffmpeg.wasm input ceiling is 2 GiB,
|
||
but real limits can be substantially lower on mobile or memory-constrained
|
||
browsers.
|
||
|
||
Source inspection has a bounded, size-aware watchdog: 30 seconds for small
|
||
files, a two-MiB-per-second scan budget for larger files, and a five-minute
|
||
ceiling. Recognized local audio/video can begin browser playback from its
|
||
temporary object URL while that worker inspection continues; completed probe
|
||
metadata remains authoritative for editing and export.
|
||
|
||
Lowering resolution, duration, frame rate, passes and output count reduces
|
||
work. MT can be faster but consumes more memory/CPU and requires isolation; ST
|
||
is not inherently a low-memory guarantee.
|