Web Quality Audit: Wanderlooms
Website: https://www.wanderlooms.com | Date: 2026-08-13 | Platform: Shopify (Dawn-class custom theme, Cloudflare CDN) | Industry: Adventure / motorcycle-lifestyle D2C apparel (India)
Business context (from business-analysis.md): Indian Shopify D2C brand, ~90% mobile traffic (CrUX phone 89.1% / desktop 10.9%), 199 SKUs, median price ₹799, 4,410 Judge.me reviews (4.4/5), Shark Tank S4 halo. Audience is phone-first, impulse/lifestyle buyers. That makes mobile Core Web Vitals, thumb-friendly UI, and social/a11y hygiene the highest-leverage fixes — which is exactly where this audit finds the worst gaps.
Executive Summary
Wanderlooms is a fundamentally healthy, crawlable Shopify store with strong baseline SEO hygiene (valid HTML, self-canonical, full OG/Twitter tags, Organization + WebSite + Product JSON-LD, robots.txt and sitemaps wired correctly, Cloudflare security headers). The damage is concentrated in two areas that directly hit revenue: (1) catastrophic mobile performance — the homepage never settles on a phone (LCP 25.8s in lab, TBT unmeasurable), and (2) accessibility regressions from theme/markup choices — 52 <h1> elements on every page, 17 images missing alt, low-contrast prices, and a notification-permission prompt on load.
Because ~90% of traffic is mobile and the brand runs an always-on Meta/Google ad program (~₹2.25–8L/month), the performance + accessibility failures are not cosmetic: they depress Quality Score, waste paid clicks, and block conversions on the exact device the customer uses.
| Category | Mobile Score | Desktop Score | Grade |
|---|---|---|---|
| Performance | n/a (page never idles) | 33 | 🔴 |
| Accessibility | 81 | 81 | 🟡 |
| Best Practices | 46 | 50 | 🔴 |
| SEO | 85 | 85 | 🟢 |
| Overall | ~55 | ~62 | 🟡 |
Mobile Performance score is not a number — it is "could not complete." Lighthouse mobile runs hung on the page (largest-contentful-paint 25.8s, total-blocking-time and time-to-interactive never reached). That itself is the headline: a phone user's first paint of meaningful content takes ~26 seconds of lab render. Treat mobile performance as Critical, not "needs improvement."
1. Performance Audit
1.1 CrUX Real-World Field Data
Core Web Vitals Assessment (field, from business-analysis.md §5a, CrUX Vis, origin https://www.wanderlooms.com, period 2026-07-12 → 2026-08-08): Needs Improvement on mobile. CrUX flags Loading Performance "needs improvement" with LCP ≈ 2.2–3.1s — already near/over the 2.5s "Good" threshold for a meaningful share of real users. INP and CLS were within Good bands. CrUX device split: phone 89.1% / desktop 10.9% / tablet 0%.
Lab data (below) is far worse than this field snapshot, which means real-world users on slower Indian 4G devices are experiencing LCP well above 3–4s. The field number is a floor, not a comfort.
Note: the PageSpeed Insights API and CrUX API were both rate-limited/unkeyed in this environment (PSI quota = 0/day; CrUX API key invalid). Field CWV figures are taken from the parent business-analysis CrUX capture, which is consistent with the live CrUX Vis dashboard. Lab data below is from a local Lighthouse 13.4.1 run against chromium-headless.
1.2 Core Web Vitals (Lighthouse Lab Data)
| Metric | Mobile (lab) | Desktop (lab) | Threshold Good | Mobile Rating | Desktop Rating |
|---|---|---|---|---|---|
| FCP | 1.6s | 1.2s | ≤ 1.8s | 🟢 Good | 🟢 Good |
| LCP | 25.8s | 10.6s | ≤ 2.5s | 🔴 Poor | 🔴 Poor |
| TBT | unmeasurable* | 5,610ms | ≤ 200ms | 🔴 Poor | 🔴 Poor |
| CLS | 0.034 | 0.007 | ≤ 0.10 | 🟢 Good | 🟢 Good |
| Speed Index | 5.9s | 11.3s | ≤ 3.4s | 🟡 NI | 🔴 Poor |
| Max Potential FID | 1,650ms | 780ms | ≤ 100ms | 🔴 Poor | 🔴 Poor |
| Time to Interactive | unmeasurable* | 16.1s | ≤ 3.4s | 🔴 Poor | 🔴 Poor |
\* Mobile run could not reach idle — main-thread work measured at 44.2s and bootup 19.5s; TTI/TBT are undefined because the page never stops executing JS.
Mobile:Desktop gap is >2.4× on LCP (25.8s vs 10.6s) and the desktop TTI (16.1s) is already 4.7× the "Good" threshold. This is a JS-render-bound store, not a network-bound one — exactly the Shopify pattern called out in the skill (pre-resource render-blocking).
1.3 LCP Phase Breakdown (Mobile)
The homepage hero is a slideshow (div.image__hero__pane … img.block, served at 1920×700 over sizes="100vw"), and the LCP element is one of these hero slides. Two compounding problems:
- LCP image is oversized & not format-optimized. Desktop hero
Desktop-Blue-Adv-Shirt.jpgships at 1920×700 / 216 KB and Lighthouse flags ~109 KB wasted; the GIF hero (Desktop-himalayan-banner.gif) is 174 KB and is a GIF (no WebP/AVIF). These load over mobile 4G at full desktop resolution with no responsivesrcsettruly matching the viewport. - The LCP element is not preloaded and competes with ~2 MB of JS + 9.2 MB of video for the main thread. With 44s of main-thread work on mobile, the browser cannot even discover and paint the hero until JS settles.
1.4 Performance Issues by Impact
Critical (>1s estimated savings / revenue-blocking):
| Issue | Evidence | Savings | Recommendation |
|---|---|---|---|
| Hero/above-fold images oversized + wrong format | Lighthouse image-delivery-insight: 3 hero images waste 109/88/83 KB; GIF hero un-WebP'd; served 1920px wide on a phone | ~291 KB + LCP risk | Serve AVIF/WebP, add <link rel="preload" as="image" fetchpriority="high"> on the first slide only, drop GIF→MP4/WebP |
| JavaScript bloat / never-idle | unused-javascript 1,999 KB (mobile) / 2,243 KB (desktop) wasted; bootup-time 19.5s mobile / 10.9s desktop; main-thread 44.2s mobile | TBT/CWV | Defer/code-split third-party widgets (see 1.5); remove the notification prompt on load |
| 9.2 MB of hero video auto-downloaded | total-byte-weight: 3 × .mp4 home-hero videos total 9.6 MB (9612 KB) on the homepage alone | ~9.6 MB | Lazy-load hero video (preload="none"), use a poster image as LCP, only play on Wi-Fi/scroll; this single item is ~87% of the 10.9 MB homepage payload |
High (200ms–1s):
| Issue | Evidence | Savings | Recommendation |
|---|---|---|---|
| Third-party script load | GoKwik KwikPass iframe+JS (~9.7 MB across 5 assets), Google Tag Manager (×2, 361 KB), yourtoken loyalty widget (460 KB), Wigzo engage, Clarity, Bing | large | Load GoKwik after interaction; consolidate GTM; defer loyalty/notification widgets |
| Unused CSS | unused-css-rules 32 KB (theme bundles unused section CSS) | 32 KB | Use Shopify section-specific CSS or purge |
| Render-blocking requests | render-blocking-insight (mobile 220ms) | 220 ms | Inline critical CSS; media/defer non-critical |
Medium/Low: unminified-css (5 KB), unminified-javascript (35–42 KB), cache-insight 859 KB of static assets with short cache TTL, font-display not swap on some faces (40–50 ms), legacy-javascript 46 KB (transpile target too old), duplicated-javascript 12 KB.
1.5 Resource Transfer Summary (homepage, desktop lab)
- Total transfer: 10.9 MB across the homepage — an e-commerce homepage should be < 2–3 MB.
- Video: 9.2 MB (3 hero .mp4 files) — by far the largest line item.
- Top hosts by bytes:
pdp.gokwik.co9.8 MB (KwikPass login/OTP iframe + plugin JS),cdn.shopify.com(images/video),www.googletagmanager.com361 KB,yourtoken-widget.pages.dev460 KB. - Third-party cookies / privacy: 21 third-party cookies set (Clarity, DoubleClick, Bing, GoKwik) — flagged by Lighthouse; will degrade under Chrome's Privacy Sandbox / ITP.
notification-on-startrequests notification permission on page load (Wigzoengage_360.js) — intrusive UX + a Best-Practices fail.
2. Accessibility Audit
2.1 Critical Issues
- 52
<h1>elements on the homepage, product page, and collection pages (verified via full chromium--dump-dom). Four promo-bar strings (SHOP FOR ₹1999 GET FLAT 10% OFF,SHOP FOR ₹2999 GET FLAT 15% OFF,FREE SHIPPING Above ₹499/-,EXTRA 5% DISCOUNT ON PREPAID ORDERS) are duplicated as<h1>multiple times; the real product/collection<h1>is buried among them. This destroys document outline for screen readers and weakens the keyword-bearing H1 signal. Fix: promo bars should be<div>/<p>(or visually-hidden aria-live), never H1. - 17 images missing
altentirely on the homepage (Lighthouseimage-alt, desktop). Includes the logo image (div.header__logo > img, no alt) and Judge.me "verified" badge SVGs. Logo missing alt is a basic, high-visibility failure.
2.2 High Priority Issues
- Color contrast: 13 failures. Compare-at "MRP" prices render at
#868282on white = 3.79:1 (needs 4.5:1). The strikethrough MRP is a core discount cue for this discount-driven brand — low contrast hurts both WCAG AA and the discount read. - Links not crawlable: 2 — Cart header links use
href="javascript:void(0)"withdata-drawer-toggle. Bots and keyboard users get a dead anchor. - Links without discernible name: 4 (icon-only links need aria-label).
- Touch targets insufficient: 8 — mobile tap targets too small/spaced (relevant given ~90% mobile).
<iframe>without title: 1 — the GoKwik KwikPassiframe-kphas an empty title.- Notification permission requested on load (Wigzo) — an a11y/UX anti-pattern (prompt fatigue, auto-dismiss friction).
- Heading structure: collection pages have 52 H1, 0 H2 — no hierarchy at all.
2.3 Positive Findings
html lang="en"present;<meta name="viewport">present (mobile-friendly).- CLS is excellent (0.034 mobile / 0.007 desktop) — layout is stable.
- Contrast on primary body text passes; the fails are confined to MRP prices and a few chrome elements.
- Judge.me review widgets are generally accessible; product schema carries
aggregateRating.
3. SEO Audit
3.1 Technical SEO
| Check | Status | Evidence |
|---|---|---|
| HTTPS / HSTS | ✅ | strict-transport-security: max-age=7889238 (Cloudflare); block-all-mixed-content CSP |
| robots.txt | ✅ | Sensible: disallows /admin, /cart, /checkout, /orders, filters; Sitemap: declared; allows product/collection/page/blog |
| XML Sitemap | ✅ | sitemap.xml index present → products/pages/collections/blogs + sitemap_agentic_discovery.xml |
| Canonical (home/product/collection/pages) | ✅ | Self-referencing on every tested template |
| Meta viewport / lang | ✅ | Present |
| Indexation / noindex | ✅ | No noindex on important pages; 404 template correct |
| Duplicate content (variant params) | ⚠️ | robots.txt blocks ?variant=/filter/sort traps — good. But see 3.2 collection duplication |
| Security headers | ✅ mostly | x-frame-options: DENY, x-content-type-options: nosniff, CSP present. No CSP script-src allowlist / object-src 'none' (CSP is only block-all-mixed-content; frame-ancestors 'none'; upgrade-insecure-requests) — see §5 |
3.2 On-Page SEO Issues
- Duplicate / overlapping collections (crawl bloat + internal competition). 52 collections include obvious duplicates:
t-shirts/t-shirts_1/all-t-shirts/all-t-shirts(×2),crew-neck-t-shirt/crew-neck-t-shirt-1,oversized-t-shirt/oversized-t-shirts,lanyard-keytags/lanyard-keytags-1,jersey/all-jerseys. These create near-identical PLPs competing for the same queries and split link equity. Consolidate to one canonical collection per product_type. - One empty collection (
collections-bandana-combo-1, 0 products) — thin page; 301 or noindex it. - Blog index missing meta description (
/blogs/news→ none). About page and product pages have good descriptions; the blog landing and collection landing pages should get hand-written meta + keyword titles. - Title tag strength: Homepage title "Wanderlooms - Adventure Inspired Apparel & Merchandise" (58 chars) is good. Product titles are keyword-rich ("Wanderlooms Racing Primo Riding Jersey | Bike Jersey"). Collection titles are weak (just the collection name) — add category keywords (e.g., "Riding Jerseys for Men & Women | Wanderlooms").
- Internal linking: nav uses real
/collections/…paths (good, crawlable). Thejavascript:void(0)cart links are the only broken anchors. - Hreflang: none detected (single-locale
enstore, worldwide shipping). Acceptable for now — but if an IN/US/UK locale split is planned, add hreflang. Not a current defect.
3.3 Schema Markup
| Type | Present | Notes |
|---|---|---|
| Organization | ✅ (all pages) | name Wanderlooms, has sameAs? verify social URLs populated |
| WebSite + SearchAction | ✅ (homepage) | sitelinks search box eligible |
| Product | ✅ (product pages) | full: name, sku, brand, aggregateRating (4.92/25), offers (6 variants, InStock, INR) — strong |
| BreadcrumbList | ❌ | Missing on product + collection pages (no breadcrumb nav rendered, breadcrumb not in DOM). Fix for SERP nav + a11y |
| LocalBusiness (JewelryStore) | ❌ | Brand has a Pune registered address + phone — add for local pack |
| Article | ❌ | Blog posts lack Article schema (Google Discover eligibility missed) |
| FAQPage | ❌ | High-ROI for a Shark-Tank/FAQ-heavy brand — add to key pages |
Product schema is a genuine strength (rich results eligible: star ratings, price, availability). The gaps are BreadcrumbList, LocalBusiness, Article, FAQPage.
3.4 Content Quality (E-E-A-T)
- Experience/Expertise: About page + homepage "Featured In" press wall (Business Insider, YourStory, etc.) + founder story present — good E-E-A-T.
- Trust signals visible: phone (+91 9993201711), email, address on About; return policy via Return Prime; 4.4/5 review corpus. ✅
- AI-generated images: none detected in filenames (no
Gemini_/ChatGPT_/Picsart-AiImageEnhancer/ai0_patterns). Real photography + graphic-led merch — consistent with the "rider-born" brand. ✅ (Good — a common Critical for lifestyle brands; not an issue here.)
4. International SEO
Not applicable / low priority. Single en locale, lang="en", worldwide shipping but no localized storefronts. No hreflang needed today. If IN/Global splits are added later, implement hreflang + self-canonical per locale (see skill §4 pitfalls — Shopify "shell translations" risk).
5. Best Practices & Security
5.1 Security Headers
| Header | Value | Verdict |
|---|---|---|
| HSTS | max-age=7889238 | ✅ (subdomains/preload not set — minor) |
| X-Frame-Options | DENY | ✅ |
| X-Content-Type-Options | nosniff | ✅ |
| CSP | block-all-mixed-content; frame-ancestors 'none'; upgrade-insecure-requests | ⚠️ No script-src allowlist — consider adding to lock XSS surface |
| X-XSS-Protection | 1; mode=block | ✅ (legacy, harmless) |
| COOP/COEP | not set | ⚠️ missing (low impact) |
5.2 Modern Standards
- ✅ Valid HTML5, UTF-8 declared, no
document.write, no mixed content. - ⚠️ Console errors on load:
ERR_CERT_AUTHORITY_INVALIDonlevo-ingest.wanderlooms.com(a broken analytics beacon), a401on yourtoken coupon API, and a Shopify GA4 pixel-migration warning. The cert error on a first-party subdomain is a real Best-Practices fail (and suggests an orphaned/overspent integration —levo/Levo "site-agent"). - ⚠️ Deprecated API used (
Attribution Reporting, Shopifyshop_events_listener). - ⚠️ Notification permission on page load (Wigzo) — intrusive.
- ⚠️ 21 third-party cookies — future-proofing risk under Privacy Sandbox.
6. Content Quality Assessment
6.1 Image Quality & Authenticity
Real product/lifestyle photography; graphic-led merch. No AI-image signatures. Hero uses a mix of JPG + one GIF (should be WebP/MP4). Product grid images are largely CDN Shopify (jpg/png) — convert to WebP/AVIF.
6.2 UX Issues
- 52 H1s / promo bars as headings (see §2) — also a visual/semantic mess.
- Hero video auto-download (9.2 MB) on a phone-first site is the single biggest UX/perf killer.
- Notification prompt on load — friction before the user even sees the catalog.
- Out-of-stock depth: 42/199 SKUs OOS (from business-analysis) — lost mobile conversions; surface "low stock" / back-in-stock capture.
7. Priority Recommendations
🔴 Immediate (This Week) — revenue-blocking
| # | Issue | Impact | Effort |
|---|---|---|---|
| 1 | Lazy-load / poster-the-hero video (9.2 MB auto-download); only stream on Wi-Fi or interaction | Removes ~87% of homepage payload; directly cuts mobile LCP | Low–Med |
| 2 | Preload + AVIF/WebP the first hero slide; drop GIF hero | LCP mobile 25.8s → target < 3s | Low–Med |
| 3 | Defer third-party widgets (GoKwik, GTM ×2, Wigzo, yourtoken) — load post-interaction | Kills 44s main-thread work; TBT/CWV recovery | Med |
| 4 | Remove notification permission on page load (Wigzo) | Best-Practices + UX + ad-Quality-Score | Low |
| 5 | Fix 52 <h1> — promo bars → <div>/<p>; one real keyword H1 per page | Accessibility + SEO H1 signal | Low (theme) |
| 6 | Add alt to logo + 17 missing images (incl. Judge.me badges) | A11y + image search | Low |
🟡 Short-Term (This Month)
| # | Issue | Impact | Effort |
|---|---|---|---|
| 7 | Fix MRP price contrast (#868282 → ≥4.5:1) | WCAG AA + discount legibility | Low (CSS) |
| 8 | Add BreadcrumbList schema + visible breadcrumbs on PDP/PLP | SERP nav + a11y | Med |
| 9 | Consolidate duplicate collections (t-shirts_1, all-t-shirts×2, crew-neck ×2, etc.); noindex empty bandana-combo-1 | Crawl budget + ranking focus | Med |
| 10 | Add meta descriptions + keyword titles to collection & blog landing pages | SERP CTR | Low (bulk) |
| 11 | Add LocalBusiness + FAQPage + Article schema | Rich results / Discover | Med |
| 12 | Fix javascript:void(0) cart links → real/aria-labelled buttons | Crawlable + keyboard a11y | Low |
🟢 Long-Term (This Quarter)
| # | Issue | Impact | Effort |
|---|---|---|---|
| 13 | Harden CSP (script-src allowlist), set HSTS includeSubDomains; preload, add COOP/COEP | Security posture | Med |
| 14 | Remove orphaned levo-ingest cert-error beacon; consolidate analytics | Best-Practices + privacy | Low |
| 15 | Purge unused CSS/JS; minify; raise cache TTL on static assets | Marginal perf | Low |
| 16 | Plan hreflang only if multi-locale launched (avoid Shopify shell-translation trap) | i18n readiness | Med |
Summary Score Card
| Category | Score | Grade |
|---|---|---|
| Performance (Mobile) | n/a — page never idles (LCP 25.8s) | 🔴 Critical |
| Performance (Desktop) | 33/100 | 🔴 |
| Accessibility | 81/100 | 🟡 |
| Best Practices | 46–50/100 | 🔴 |
| SEO | 85/100 | 🟢 |
| Content Quality | 78/100 (real photos, no AI; weak schema coverage) | 🟡 |
| Mobile UX | 55/100 (video bloat, notification prompt, tap targets) | 🟡 |
| Overall | ~58/100 | 🟡 |
Verdict: Structurally sound store with excellent SEO plumbing, undermined by a heavy, JS-and-video-bloated mobile experience and basic accessibility regressions. The four Immediate-week fixes (video lazy-load, hero image preload/format, third-party deferral, H1 cleanup) address the majority of the revenue risk for a 90%-mobile, ad-funded D2C brand.
Sources & Evidence
- Lighthouse 13.4.1 (local, chromium-headless) — mobile + desktop lab runs:
lh_mobile3.json,lh_desktop2.json(workspace). Metrics: LCP 25.8s/10.6s, TBT unmeasurable/5,610ms, CLS 0.034/0.007, Speed Index 5.9s/11.3s, bootup 19.5s/10.9s, total-byte-weight 21.8 MB/18.1 MB (desktop homepage payload 10.9 MB incl. 9.2 MB video). - HTTP headers (
curl -sI https://www.wanderlooms.com/): HSTS, X-Frame-Options DENY, CSP, X-Content-Type-Options nosniff, Cloudflare. - robots.txt / sitemap.xml (
curl): valid, Sitemap declared. - Server-rendered DOM + chromium
--dump-dom: title/description/canonical/OG/Twitter per template; JSON-LD types (Organization/WebSite/Product); 52<h1>s, 17 missing-alt images, 13 contrast fails, duplicate collections — verified againsthttps://www.wanderlooms.com/,/products/racing-primo-jersey,/collections/all-jerseys,/collections/jersey,/pages/about-us,/blogs/news. - Shopify
products.json/collections.json: 199 products, 52 collections, duplicate + empty collection handles confirmed. - CrUX field CWV (mobile "needs improvement", LCP ~2.2–3.1s, phone 89.1%) — from parent task
business-analysis.md§5a (CrUX Vis capture, period 2026-07-12→2026-08-08). - PageSpeed Insights API / CrUX API: unavailable in this environment (PSI quota exhausted; CrUX API key invalid) — noted transparently; field CWV sourced from the CrUX Vis dashboard capture instead.
Note: product/collection handles guessed in initial probing (/collections/jerseys, /products/racing-primo-riding-jersey) 404'd; the real handles (/collections/jersey, /products/racing-primo-jersey) were taken from Shopify data and verified — the 404s were audit-input errors, not site defects.