> ## Documentation Index
> Fetch the complete documentation index at: https://varaahi.vritservicespro.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Performance

> The engineering behind VARAHI's speed — the budgets, the techniques, and how not to undo them.

# Performance

VARAHI is built to a performance budget, and this page documents it so you do not
unintentionally break it.

![Lighthouse mobile result](https://mintlify.s3.us-west-1.amazonaws.com/vr-it-services-pro-c6bfa2fc/images/placeholder/performance-lighthouse.png)

Lighthouse mobile — 88 performance

***

## The numbers

Measured against a published store, Lighthouse mobile emulation, clean profile.

| Metric | VARAHI | Target |
| - | - | - |
| **Performance score** | **88** | 75+ |
| **Accessibility** | **97** | 90+ |
| **Best practices** | **77** | — |
| **SEO** | **92** | 90+ |
| Largest Contentful Paint | \~3.0 s | under 2.5 s |
| Total Blocking Time | \~20 ms | under 200 ms |
| Cumulative Layout Shift | \~0.008 | under 0.1 |
| Total page weight | \~640 KB | under 1 MB |

> [!NOTE]
>
> Scores on the **theme dev server** are always lower, sometimes dramatically. The dev
> server compiles Liquid on every request, serves assets uncompressed, and injects
> roughly 3 MB of Shopify development tooling that does not exist on a published
> store. Always audit the published store.

***

## The seven techniques

### 1. Mobile has no motion

Below 1024px, the entire motion bundle is **never requested**.

```js theme={"system"}
if (window.matchMedia('(max-width: 1023px)').matches) return;
```

This is the single largest performance decision in the theme. GSAP and ScrollTrigger
together are 113 KB and roughly 1.2 seconds of scripting on a throttled phone CPU.
Mobile does not download them at all.

> [!TIP]
>
> This is also why the mobile experience feels instant rather than merely fast. There
> is no animation queue to fight with while a shopper is tapping.

### 2. The LCP element is never hidden

The hero image is the Largest Contentful Paint element. A common performance mistake
is to fade the hero in with JavaScript — which means the browser cannot paint it
until the script has run.

VARAHI does the opposite. The hero image is **visible in the first paint**, and the
motion system only animates its scale, never its opacity.

> [!WARNING]
>
> If you customise the hero, do not add `opacity: 0` to the hero image and fade it in
> from JavaScript. You will lose 1–2 seconds of LCP for no visible benefit.

### 3. CSS is one minified stylesheet

The theme's base stylesheet (`base.css`) is loaded as a single stylesheet request and section styles are inlined alongside it. There is no third-party CSS on the critical path.

| Asset | Size |
| - | - |
| `base.css` | \~7 KB |

### 4. JavaScript is bundled

Instead of five or six separate script requests, VARAHI ships two bundles.

| Bundle | Contents | Size |
| - | - | - |
| `app.js` | Store API, cart API, scroll reveal, header, drawer | \~21 KB |
| `motion.js` | GSAP, ScrollTrigger, VARAHI choreography | \~134 KB |

The motion bundle is additionally loaded via `requestIdleCallback`, so it never
competes with the critical path even on desktop.

### 5. Fonts are self-hosted, subset, and staged

* **No third-party request.** No Google Fonts, no extra DNS lookup, no connection to
  a third party on your customer's critical path.
* **Latin-only subsets.** Roughly two thirds smaller than the full family.
* **`font-display: swap`.** Text renders immediately; no invisible text, no layout
  shift.
* **Staged by viewport.** Below 768px, only Inter 400 and the icon font are
  declared. JetBrains Mono and Inter 500 live inside a `min-width: 768px` media
  query, so phones never download them.
* **The icon font is 5 KB** and covers all 44 glyphs the theme uses.

### 6. No layout shift, by construction

Layout shift is the metric that is hardest to fix after the fact, so VARAHI prevents
it at the source.

| Technique | What it prevents |
| - | - |
| `scrollbar-gutter: stable` | The page reflowing when the scrollbar appears |
| Explicit `width` and `height` on every image | Images reserving their space before load |
| `aspect-ratio` on the hero podium | The hero from growing as the image loads |
| Decorative glows fading in after `fonts.ready` | Background orbs jumping when fonts swap |
| No opacity-based entrance on the LCP image | The hero painting late |

The decorative background glows in the hero are `opacity: 0` until fonts have loaded,
then they fade in. An element *appearing* is not a layout shift; an element *moving*
is. That distinction is the whole trick.

### 7. Heavy sections are viewport-gated

The architecture sequence, the companion app and the PDP choreography only initialise
when they come within 600px of the viewport. On a page where the shopper never
scrolls that far, that JavaScript never runs and those frames never download.

***

## Your performance budget

When you add content, keep these in mind.

| Asset | Budget | Why |
| - | - | - |
| Hero image | under 150 KB | It is the LCP element |
| Product images | under 200 KB | Most numerous asset on a collection page |
| Total page weight | under 1 MB | Keeps the score comfortably above 75 |
| Collection page images | 6–12 products | More products, more images, lower score |
| Video | host externally | A 10 MB video destroys the budget |

> [!TIP]
>
> Upload images at the size they will be displayed. Shopify's `image_url` filter
> handles this — the theme requests `width: 900` for the hero and `width: 120` for
> thumbnails. If you upload a 4000px image and reference it raw, you ship 4 MB.

***

## Auditing your own store

**1. Publish to a live or preview URL**

The theme dev server is not representative.

**2. Use a clean browser profile**

Extensions block requests and corrupt the results. Incognito is fine.

**3. Run Lighthouse in mobile mode**

That is the mode that matters for the score.

**4. Run it twice**

The first run includes cold-cache effects. Take the second run's numbers.

> [!WARNING]
>
> **Password protection makes a published store unmeasurable.** A password page is
> what Lighthouse will audit. Turn password protection off before auditing, and turn
> it back on afterwards.

***

## Common regressions

> **I added a big background image to a section**
>
> Background images are not lazy-loaded and are not sized. Use a `background-image`
> on a container with an explicit `aspect-ratio`, or use an `<img>` with
> `loading="lazy"`.

> **I added a video section to the homepage**
>
> Host the video on a CDN (Shopify's own video hosting, Cloudflare Stream, or
> Mux), not as a 20 MB upload. Always set a poster image.

> **I added a third-party script**
>
> Every third-party script is a main-thread cost on a phone. Load it after
> `load`, or gate it behind a consent banner, or reconsider it.

> **My collection page got slower**
>
> Twenty products with four images each is eighty image requests. Reduce the
> products per page, or reduce the images per card.

> **I installed an app and the score dropped**
>
> Almost always a third-party script. Check the Lighthouse network tab and find
> what arrived. You can often lazy-load it or move it to a template you do not use.

***

> **[Accessibility](https://varaahi.vritservicespro.com/going-further/accessibility.md)**
>
> The second half of the quality bar.

> **[SEO](https://varaahi.vritservicespro.com/going-further/seo.md)**
>
> Technical SEO the theme handles for you.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.