Bỏ qua, tới nội dung

Trang này chỉ có bản tiếng Anh.

The numbers, and how they were measured

Theme listings quote round numbers with no method attached. This page gives the method, and says plainly where a number is missing.

Everything below was measured on Hullara Apparel Pro 0.2.4, the largest of the four builds. The smaller ones ship less.

Every byte count on this page is read out of the build's own report — the same numbers, from the same buffers, that the build compared against its budgets a moment before it wrote them. Nobody types them, and nobody re-measures them with different gzip settings. KB means 1024 bytes throughout, including for the competitor figure below.

What a page downloads

Two files load on every page. Everything else is fetched only by a page that uses it.

rawgzip — what actually travels
core.css90.0 KB15.0 KB
core.js35.3 KB12.9 KB

That is 27.9 KB on every page, and the one-product build is smaller again at 26.4 KB.

The ceiling is not a target — the build throws when a stylesheet crosses it, so this figure is what the theme is living inside rather than what it is aiming at. The paragraph below says the same thing; the bar says it first.
The ceiling is not a target — the build throws when a stylesheet crosses it, so this figure is what the theme is living inside rather than what it is aiming at. The paragraph below says the same thing; the bar says it first.
core.css, gzipped15.0 KB16 KB
core.css, gzipped — headroom622 bytes left before the build refuses

The same measurement, on two other themes

Same method on all three, taken on 2026-08-14: every theme-owned stylesheet and script the layout requests with no condition above it, byte length and gzip at level 9.

Bars are the file count — the difference that is architectural rather than incremental. Gzipped weight is beside each label, and the full figures are in the table below.
Bars are the file count — the difference that is architectural rather than incremental. Gzipped weight is beside each label, and the full figures are in the table below.
ThemeFiles per pageGzipped
Hullara Apparel Pro2 files27.9 KB
Shopify Dawn 16.0.011 files33.2 KB
A commercial theme, unnamed6 files114.7 KB
files per pagerawgzip
Hullara Apparel Pro2125.2 KB27.9 KB
Shopify Dawn 16.0.011156.6 KB33.2 KB
A commercial theme, unnamed6653.7 KB114.7 KB

Read the Dawn row before the third one. Dawn is close: it is 1.19× our weight on the wire, and its stylesheet alone is smaller than ours. Dawn is a well-built free theme and the honest comparison with it is about shape rather than size — two requests against 11, because everything of ours that a page does not use is not requested at all.

This page previously said Dawn shipped around 140 KB, beside our own figure. That was wrong, and it was wrong in the way this whole page exists to prevent: the 140 was raw and ours was gzipped, so a unit produced a five-fold claim out of a twenty-per-cent difference. Nobody chose to exaggerate; nobody checked either.

The third row is the theme Hullara was actually built to replace, and that gap is real: 4.1× on the wire, most of it one 481.2 KB render-blocking stylesheet. It also loads a script from an origin that is neither yours nor Shopify's on every page. We do not name it: the number is fair, naming it is a fight, and the artefact it came from is a licensed export that is not ours to redistribute.

With the settings Dawn actually ships switched on — predictive search and scroll animations are both on by default — its figures become 14 files and 38.4 KB. Its cart drawer is off by default and would add five more stylesheets, and we have left those out.

Beyond those two files, 35 components exist as separate assets totalling 37.8 KB gzipped, and a page loads only the ones its own markup names. A product page does not download the filter code. A collection page does not download the countdown. The same is true of section stylesheets: 25 of them, 11.1 KB in total, each linked by the section that needs it.

This is enforced, not aspirational: core.css has a hard gzip budget of 16 KB and the build fails when it is exceeded. It currently has 622 bytes of headroom. That is the honest version of "we care about performance": not a number we like, a ceiling we are living underneath.

What is still missing, and it is the important part: bytes are not speed. None of the three was run through Lighthouse under identical conditions, and a real store's own images, fonts and apps move its numbers far more than the theme does. So this table says what each theme asks a browser to fetch before it does anything else. It does not say Hullara is faster than Dawn, and the comparison page still declines to, for the same reason.

Lighthouse

Measured on 2026-08-14, on apparel-pro, through the theme dev proxy — averaged over home, collection and product, on desktop and mobile, which is how Shopify states its own requirement.

RoutePerformance60Accessibility90SEO
home desktop88100100
home mobile71100100
collection desktop88100100
collection mobile70100100
product desktop97100100
product mobile66100100

Shopify's Theme Store floors are 60 for performance and 90 for accessibility, averaged across these routes. A cell below its floor is hatched and marked †.

Averages: performance 80, accessibility 100, SEO 100. Every route, not a summary of them — the accessibility column is what the average hides.

Accessibility is 100 on every route in the run, not just on average. The two performance numbers that belong to the theme rather than to the network are also held per route, and both are drawn below rather than described: layout shift against a 0.05 ceiling, and main-thread blocking against 200ms. Those three fail the run; the composite scores above do not gate anything.

Layout shift is the theme's own doing — an image with no intrinsic size, a font swap, a banner inserted above the fold. It is one of the two performance numbers a page can be blamed for.
Layout shift is the theme's own doing — an image with no intrinsic size, a font swap, a banner inserted above the fold. It is one of the two performance numbers a page can be blamed for.
Layout shift, worst route0.00070.05
Layout shift, worst route — headroom99% of the ceiling unused
Blocking time is this theme's own JavaScript. The network round trip does not enter it, which is why it is gated and the composite score is not.
Blocking time is this theme's own JavaScript. The network round trip does not enter it, which is why it is gated and the composite score is not.
Main-thread blocking, worst route56 ms200 ms
Main-thread blocking, worst route — headroom72% of the ceiling unused

Why the composite is not gated. It moves for reasons that are not the theme's. Two runs minutes apart in the same session scored the product page 88 and then 97. Lighthouse 12 added weight to a third-party-cookie audit and took 22 points off "best practices" for cookies Shopify sets, with nothing here changing. A gate nobody can act on gets switched off, and a switched-off gate is worse than none.

The target is the pessimistic one. The theme dev proxy renders every request locally and serves assets uncompressed; a merchant's storefront comes off Shopify's CDN and measures better. We publish the lower number.

What is still missing: this is a manual run, not continuous integration, so the date above is doing real work — it is the honest expiry on the figure rather than a decoration. The numbers reach this page from the run's own output now instead of being copied by hand, which is why accessibility says 100 here: it was reading 99 long after every route had reached 100.

Accessibility

  • axe at WCAG 2.1 AA, zero serious or critical violations, across home, collection, cart and product.
  • The whole purchase path is reachable and operable by keyboard alone — asserted by a test that tabs to the add-to-cart button and presses Enter.
  • Every focusable control has a visible focus indicator, checked in three different ways because there are three different ways to draw one.
  • prefers-reduced-motion collapses every transition to zero. It is not a merchant setting and cannot be overridden.
  • Content is readable and navigation works with JavaScript disabled.

What is missing: automated tooling catches roughly a third of real accessibility problems. No screen-reader user has tested this theme. The EU Accessibility Act has applied to e-commerce since 28 June 2025 and WCAG 2.1 AA is the practical benchmark; clearing axe is necessary and is not sufficient.

How it is checked

Every release runs, and must pass clean:

  • Fifteen verification layers across all four builds, at zero errors and zero warnings — and hullara release refuses on the warnings too, not only the errors. Among them: a var() must resolve to a declared token, every merchant-facing string must be translatable, no colour scheme may fail contrast at 4.5:1, no Pro file may reach a Core zip, and a translation may not lose a plural branch or an interpolated value. The last layer is Shopify's own theme check, pinned to an exact version.
  • A unit suite over the compiler, the tokens, the edition boundary and the runtime, and a browser suite across five viewport widths on a real Shopify store: every route, variant switching, add-to-cart, faceted filtering surviving the Back button, predictive search, and the keyboard path.

What is missing: the two suites above have no count beside them, and that is deliberate rather than coy. This page carried "329 unit tests" and "204 browser assertions"; the project's own status table said 275 and 64, and the comparison page said 64. Three files, three answers, none of them generated — so all three were somebody's count on some afternoon. A number that cannot be produced by the thing it describes does not belong on this page, and the fix is to have the test run emit it, not to count again.

Editions, and why the boundary is real

Hullara Core and Hullara Pro are not one theme with features switched off. The Pro files are not in the Core zip. There is no runtime flag, no licence check gating a feature, and nothing to unlock — a file that is not there cannot be turned on. The build fails if any section or block is claimed by both editions or by neither.

What is not measured yet

Stated because a page like this is worth nothing if it only lists wins:

  • Lighthouse is not gated in CI. Manual runs only.
  • No screen-reader testing, only automated scanning.
  • Core Web Vitals from real visitors — field data needs live stores, and there are none yet.
  • The translations have not been read by native speakers. 5 storefront languages ship (en, de, es, fr, it) and their structure is checked mechanically — a missing plural branch and a lost {"{{ }}"} value are both build errors. Register and idiom are not checked by anything.
  • German has never been rendered. Overflow was measured by injecting German strings into a rendered page at three widths — no overflow — which is not the same as looking at a German storefront.

The refusal to fabricate reviews, stock and deadlines is explained separately.