Reference

Performance notes

What the TreStack Bundles storefront code weighs, what loads on which page and when, one dated measurement on one theme, and how to measure your own store so the numbers compare.

Applies to: TreStack Bundles, every plan
Updated: 11 October 2026

At a glance
  • 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:

PartSizeLoads on
Loader and its helper1,030 bytesEvery page with the embed on
Controller9,477 bytesEvery page with the embed on
deal-core43,651 bytesPages that show a deal
TotalAbout 54 KBA 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

Every page with the embed on
Loader and controller, about 10.5 KB gzipped, as a module script that runs after the HTML is parsed.
Page with a deal
Plus deal-core, about 44 KB. About 54 KB in total in the build of 11 October 2026.
Parts loaded when used
Sticky bar, gallery, A/B, cart extras, translations, subscriptions: 0.5 to 1.2 KB each.
Budget
Loader 1.5 KB, controller 10.5 KB, deal-core 46 KB, gzipped. Checked by a test in the app's code.
Deal data
Written into the product page by the app embed. The /apps/bndl address is asked only for products the page did not print.
Measured LCP and TBT
No measurable change, 10 October 2026, Horizon, mobile profile, one product page.
Layout shift
0.038 in the same measurement, from the widget appearing after first paint.
Badge ring
Pauses off screen and in a hidden tab; stops for reduced motion.
Opt-out for testing
?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.

Copyright © 2026