IdukkiIdukki
Embedding

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

ChangeBeforeAfter
Icon library replaced with generated inline SVGs13.9 KB + 1 requesttree-shaken, ~0
React runtime swapped for a compatible 4 KB core45.1 KB9.7 KB
Product modal loads only this session’s variants27.9 KB22.6 KB
Chunk files on the CDN148 files136 files
Critical chunks discovered late (extra round trip)4 chunks0
Measured on production builds, gzipped sizes. Items ship independently through August 2026.

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.

~0.0 KBJavaScript needed to paint a grid in the new opt-in lite modeLoader plus a self-contained renderer; the full app hydrates on first interaction or browser idle.

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.

#performance#widget#core web vitals#engineering

More from Rohin Aggarwal

We use cookies

We use essential cookies to run this site and optional analytics cookies to understand how it’s used. You can change your choice anytime in our privacy policy.