v1.2 - Performance release: −42% JS, smarter engine loading, hardened headers
Big performance release: every page ships ~42% less JavaScript (137 → 80 KB gzipped), compression engines load exactly when they're needed, and the first PDF compress starts seconds sooner. A full security + performance review of this release found no security issues.
⚡ Faster loading
- −42% initial JS on every page (137.4 → 79.6 KB gz) — the animation engine, settings panels, compression orchestration and per-page SEO content are now lazy chunks loaded on demand instead of weighing down first paint.
- Faster LCP — headings no longer hide behind a fade-in, removing up to 120 ms of self-inflicted render delay on every page.
- 6 MB of dead code dropped — the unused HEIC encoder wasm is gone from the build (HEIC input stays fully supported).
- ~8 MB lighter service-worker install — only the app shell is precached now; engines and pages cache on first use (and the offline claim in the copy now says exactly that).
🚀 Faster compressing
- No more dead progress bar on the first PDF compress — the 15 MB Ghostscript engine starts downloading the moment you drop a file, hidden behind your think time.
- …and only when it's actually needed — merge, split and PDF ↔ image conversions no longer pull Ghostscript at all (guarded by a new e2e test).
- Smooth EXIF batches — metadata stripping moved off the main thread into the image worker with zero-copy transfers, so the progress UI stays responsive.
- Fail fast — if an engine can't start (e.g. out of memory), you get an immediate error instead of a stuck progress bar.
- Safe drops during page load — a file dropped while the page is still hydrating no longer navigates the tab away.
🔒 Security
- The full security-header set (COOP/COEP, nosniff, X-Frame-Options, referrer & permissions policies) is now applied on every response path, including the markdown twins served to agents.
- Extracted archive filenames are sanitized against Unicode bidi-override extension spoofing before they become download names.
🧰 CI
- New bundle-size budget gate — any accidental static import that would weigh down all ~94 tool pages now fails CI loudly (budgets pinned to the new 79.6 KB gz baseline).