Measured, not claimed
Every number here has a date and a command.
The bytes the embed script fetches, how it gates video, and the PageSpeed report for a live gallery. Measured on 27 Sep 2026 against the production CDN, reproducible from the commands at the bottom of the page.
81.5 KB
compressed, loader to first paint
128.0 KB with the shared chunks it preloads; 417.8 KB uncompressed. Measured 27 Sep 2026.
≤ 3
videos on preload="auto" at load
Active slide and neighbours only; everything off-screen is "none". Enforced by a Playwright smoke test on every release.
99 / 100
PageSpeed Insights, performance
Desktop run on a live production gallery, 12 Jun 2026. Full report and screenshots below.
1 KB = 1,024 bytes. Compressed figures are gzip -9; the CDN also serves Brotli, which is smaller.
What the embed actually downloads.
One tag, one stylesheet, a small module graph. Layouts, the post modal and the carousel engine stay on the shelf until a shopper asks for them.
idukki-ext 62cf6876 · 27 Sep 2026
| File | Role | Raw | gzip |
|---|---|---|---|
| The tag on your page | 17.0 KB | 6.0 KB | |
| version/script_0 | loader | 17,398 | 6,115 |
| Core, before first paint | 272.3 KB | 75.5 KB | |
| main-DI1xnZiP.css | stylesheet | 45,939 | 8,712 |
| main-Cj_C066f.js | entry | 70,243 | 21,478 |
| vendor-react-CtP5nHl6.js | preact alias | 338 | 256 |
| App-CRNLgcZV.js | app shell | 162,356 | 46,847 |
| Shared chunks, preloaded at load | 128.4 KB | 46.6 KB | |
| icons-DF7sgRFE.js | inline SVG icons | 45,130 | 15,532 |
| chunk-upload-u5PGKBcu.js | upload flow | 42,352 | 15,430 |
| common-ui-DMDbzNgP.js | shared UI leaves | 31,953 | 11,413 |
| utils-BVmchPQZ.js | utils | 4,569 | 1,842 |
| modal-sKcbjXa6.js | modal frame | 4,110 | 1,822 |
| api-K3jRA8Uc.js | api client | 1,818 | 636 |
| rolldown-runtime-DwynqlJ6.js | module runtime | 711 | 457 |
| ErrorScreen-CnPLefHW.js | error screen | 533 | 357 |
| safeStorage-DynI-6rA.js | storage guard | 343 | 202 |
| Everything fetched at load | 417.8 KB | 128.0 KB | |
| modal-CfFCHmMe.js | post modal, on open, not counted | 103,791 | 25,073 |
How it stays that size on a real store.
Each of these is a line of code in the open widget repository, not a policy. The loader you can read in your own DevTools does most of the work.
Below the fold means not yet
When every embed on the page sits more than two viewports down, the loader waits for an IntersectionObserver (150% root margin) before fetching a single byte of the bundle.
Data first, code second
The loader requests the gallery feed before the bundle. An empty gallery, or a product with no content, skips the bundle entirely; nothing renders, nothing downloads.
Cards mount when you scroll near them
Each card sits behind LazyMount, an IntersectionObserver with a 300px margin. A 50-post gallery keeps roughly the visible dozen in the DOM, and the placeholder reserves the aspect ratio so nothing shifts.
Video fetches only where it plays
The active slide and its neighbours get preload="auto"; every off-screen slide gets "none". A Playwright smoke test fails the build if more than 3 videos are on "auto" at load.
Preact, per-layout chunks
Preact is aliased in as React, and each gallery layout is its own lazy chunk (Swiper only ships with carousel layouts), so the core stays the size above whatever you enable.
No fonts, no inline scripts
The runtime ships no font of its own; a webfont is fetched only when your Brand Kit names one. It never uses eval() or inline scripts, so it runs under a strict nonce-based CSP.
Zero site-speed impact
99/100 on a live production widget.
- Performance
- Accessibility
- Best Practices
- SEO
Values are estimated and may vary. Measured 12 Jun 2026 on the live widget.
- 0.4 sFCP
- 0.9 sLCP
- 0 msTBT
- 0CLS
- 1.0 sSpeed Index


A production Idukki gallery on widget.idukki.io: a lazy-loaded runtime with 0 ms blocking time and CLS 0 that does not move your Core Web Vitals. The widget earns the score, not this page; the runtime's measured byte sizes are on the performance page.
Run it yourself on PageSpeedRun it yourself.
The same four things we ran. If a number on this page drifts from what you get, tell us and we will re-measure and update the date.
01 · Raw size of the embed script
curl -sL -o /tmp/w.js -w '%{size_download}\n' https://idukki-cdn.com/version/script_002 · Transfer size, as the CDN compresses it
curl -sL --compressed -H 'Accept-Encoding: gzip, br' -o /dev/null -w '%{size_download}\n' https://idukki-cdn.com/version/script_003 · Rebuild the bundle from source
git clone https://github.com/Idukkidev/idukki-ext && cd idukki-ext && npm ci && npm run build04 · Run the preload smoke test
WIDGET_URL='https://widgetugc.feefo.com/?guid=58d0cd14-db24-4e1b-a397-09b4a808cb7c&bguid=14380bc6-45c9-4c27-95dd-0d5b6e4efdcd' npx playwright test --project="Desktop Chrome" --grep "@smoke"
The reference page for the smoke test is a live Feefo Social gallery, which runs the same widget code. The PageSpeed run above uses this exact widget URL, so your score should land within Google's usual run-to-run variance.
Performance
See it on your own product page before you decide.
Same runtime, same gating, your catalogue. A 14-day trial installs the one tag and you can run PageSpeed on it yourself.
- No credit card
- Cancel anytime
- GDPR + SOC 2 (in audit)