Performance notes
Applies to: TreStack Bundles, every plan
Updated: 11 October 2026
- Page with a deal: About 54 KB gzipped
- Other pages, embed on: About 10.5 KB gzipped
- Measured: 10 October 2026, Horizon, one page
What loads, and when
The app embed Bundle deals adds one small script to every page of your store while it is on. It loads as a module script, which the browser runs only after the page's HTML is parsed, so it does not hold up the first render. That script, the loader, then starts the controller. Together they are about 1 KB plus about 10 KB, and they load on every page with the embed on, including pages without a deal and while no deal is published.
The controller looks for a deal for the product on the page. Only when there is one does it load deal-core, the widget itself, at about 44 KB. A few small parts load only when the page needs them:
- Sticky add to cart bar: about 0.8 KB
- Gallery switching for featured images: about 0.6 KB
- A/B test variant choice: about 0.5 KB
- Cart extras, such as Skip cart and go to checkout directly: about 1.2 KB
- Translated widget texts: about 1.0 KB
- Subscription choice kept in step with the theme: about 0.5 KB
On a product page, the embed writes the deal's settings and the product into the page's HTML, so the widget needs no request to our server to appear. The widget asks our server, through your store's own address (/apps/bndl), only when it shows a product the page did not print, such as an app block set to another product on the home page, or when a deal targets a collection hidden from the online store. Details of other products in a bundle or a picker come from Shopify.
The widget loads no web fonts, no third-party scripts and no chat. Images you upload are served from your store's own Shopify Files.
The analytics pixel is separate. Shopify loads it in its own sandbox, only for shoppers who allowed analytics, and it sends deal views, add to carts and checkout starts to bndl-px.trestack.app. It is not part of the sizes on this page.
The numbers
Sizes of today's build, measured on 11 October 2026, gzipped:
| Part | Size | Loads on |
|---|---|---|
| Loader and its helper | 1,030 bytes | Every page with the embed on |
| Controller | 9,477 bytes | Every page with the embed on |
| deal-core | 43,651 bytes | Pages that show a deal |
| Total | About 54 KB | A product page with a deal |
Each part has a size budget: 1.5 KB for the loader, 10.5 KB for the controller and 46 KB for deal-core. A test in the app's code fails when a part grows past its budget, so a heavier widget cannot ship by accident.
On 10 October 2026 we measured the build of that day, which was about 51 KB on a page with a deal, because deal-core was then about 41 KB. The test ran in a real Chrome with a mobile profile (CPU slowed 4 times, slow 4G network, empty cache) on a product page of a test store on Shopify's Horizon theme. With the widget, Largest Contentful Paint and Total Blocking Time showed no measurable change. Taps were handled in 16 ms or less. Layout shift was 0.038, caused by the widget appearing after the first paint.
That is one measurement on one theme. It is not a guarantee for every store, which is why the next section exists.
Two changes came out of that test. The moving text ring of a Border badge now pauses when it is off screen or the tab is hidden, which brought its cost down from 85 to 96 ms of main thread work per second to 12 to 13 ms, and it stops for shoppers who ask for reduced motion. A preload of the script in the page head was tried and removed, because it made Largest Contentful Paint slower.
Measuring your own store
Measure the page the deal is on, logged out, in a private window with no browser extensions. Lighthouse on a live store is noisy: two runs on an unchanged page often differ by several points. Run each version at least three times and compare medians, with the same device setting each time.
You do not need to change your theme to get a page without the widget. Add ?bndl=off to the product URL (or &bndl=off when the URL already has a question mark) and the loader stops there: the controller, deal-core and the widget do not load. The page still carries the loader, about 1 KB, and the deal data in its HTML, so the comparison shows the widget's cost, not the embed's. Compare that page with the normal URL.
Compare Largest Contentful Paint, Total Blocking Time and Cumulative Layout Shift, not only the headline score. If the medians move by more than a couple of points, send us both sets of reports and the page URL through the live chat in the app or at support@trestack.app.
Measuring the cost, in four steps.
Pick one product page with a deal
Log out, open a private window and turn off browser extensions.
Run three reports with ?bndl=off
Same device and throttling each time. Note the medians.
Run three reports on the normal URL
Change nothing else on the theme in the same session, or the comparison means little.
Compare the medians
Largest Contentful Paint, Total Blocking Time and layout shift, side by side.
Settings reference
/apps/bndl address is asked only for products the page did not print.?bndl=off on a storefront URL turns the widget off for that page view.If this does not work
The failures most likely on this procedure, with the check that resolves each one.
?bndl=off, and send us both reports if the difference is larger.?bndl=off on the same page, with nothing else changed on the theme. If the median really moved, send both sets of reports and the URL./apps/bndl on your own domain and to bndl-px.trestack.app are the app's. Anything else belongs to your theme or another app.When a deal does not show or prices look wrong
The store widget is off, deals are paused, a deal is not reaching one product, or the cart and checkout price surprise you. What to check, in order, and how to reach us.
Theme compatibility and placement
Where the widget places itself, the app block for a custom position, which themes the widget knows and which are verified, page builders, quick view, cart drawers, other bundle apps, and what to redo when you switch themes.