Inside the widget speed program: cutting our embed JS by two thirds
A UGC widget lives on someone else’s storefront, so every kilobyte is borrowed. Here is exactly what we cut, what we measured, and the new performance dashboard that shows what your shoppers’ browsers actually experienced.
The fastest third-party script is the one that never loads. The second fastest is the one that loads only what this exact visitor, on this exact page, on this exact device actually needs. We spent a sprint holding our own widget to that standard, and this is the honest ledger of what we found and what we changed.
In this article
An embedded widget is a guest. It runs on a storefront that already carries a theme, an analytics stack, a consent manager and a dozen other scripts, and the merchant’s Core Web Vitals pay for all of it. We have always engineered against that budget (it is why the widget code-splits every gallery layout), but a deep audit this month found real waste left on the table. This piece walks through the ledger: every line item, the measured saving, and the two changes that matter even more than the kilobytes.
The ledger: what we cut
| Change | Before | After |
|---|---|---|
| Icon library replaced with generated inline SVGs | 13.9 KB + 1 request | tree-shaken, ~0 |
| React runtime swapped for a compatible 4 KB core | 45.1 KB | 9.7 KB |
| Product modal loads only this session’s variants | 27.9 KB | 22.6 KB |
| Chunk files on the CDN | 148 files | 136 files |
| Critical chunks discovered late (extra round trip) | 4 chunks | 0 |
Two items deserve a word. The icon change sounds trivial and is not: 87 icons pulled in a 40 KB vendor bundle where the actual path data was about 3 KB, so we generated our own components once and deleted the dependency. The modal change is about fairness across devices. A desktop shopper was downloading the mobile bottom-sheet, a Shopify store was downloading the WooCommerce panel, and everyone was downloading one customer’s demo dataset. Each variant now loads only where it can actually render.
The bigger win: loading nothing
Bundle size is the second-order problem. The first-order problem is loading code on pages that will never show content. A product page whose product has no tagged posts used to download the entire widget, mount it, discover the empty response, and hide. The loader now remembers which galleries came back empty, races first visits against the data response, and skips the bundle when there is nothing to paint. Galleries embedded deep below the fold wait for an intersection observer instead of taxing initial page load.
For merchants who want to go further, an experimental lite mode paints the grid from the data response alone, with the interactive app arriving lazily afterwards. It is a flag on the embed div, it fails open in every path we could think of, and it exists because the honest end state of a widget speed program is first pixels that cost almost nothing.
Mobile apps: a supported path, not a shrug
Customers kept asking whether the widget works inside their native apps. The truthful answer was “usually, with sharp edges”: WebViews silently drop window.open, so product taps did nothing, and some ship with storage disabled. Both edges are now handled. Every outbound tap goes through a single exit point that can deliver a structured event to React Native, WKWebView or Android instead of opening a popup, storage degrades gracefully, and a diagnostic panel (add idk_appcheck=1 to any URL inside the app) tells support exactly what that WebView allows. None of this changes anything for regular web embeds; the bridge is strictly opt-in.
Proof over promises: the Performance page
Lab benchmarks flatter everyone. The number that matters is what your shoppers’ browsers measured on your pages, so the widget now reports a small sampled beacon (time to first tile, data latency, LCP, layout shift) to a new Performance page in the dashboard. You see your own percentiles, the trend over time, mobile against desktop, and how you compare with the fleet-wide benchmark across all Idukki widgets. When we say the widget got faster, you should be able to check.
Continue reading
1 piece in this clusterThese long-form pieces on the Idukki blog link back to this article, go deeper on the cluster.
More from Rohin Aggarwal
- Embedding
How to Embed a LinkedIn Feed on Your Website (2026 Guide)
LinkedIn has no native feed widget. This guide covers single-post embeds, the locked-down LinkedIn API, and how B2B brands run moderated LinkedIn walls for social proof.
- Embedding
How to Embed a Facebook Feed on Your Website (2026 Guide)
The official Page Plugin, the App Review process behind the Graph API, and when a moderated Facebook wall is the better answer for shoppable, multi-platform UGC.
- Embedding
How to Embed a Pinterest Feed on Your Website (2026 Guide)
Pinterest's official widgets, the API v5 tier that unlocks a custom feed, and why Pinterest content earns a shoppable, moderated wall more than most platforms.