Web Quality Audit: Perfora (perforacare.com)

Website: https://perforacare.com/ | Date: 2026-09-07 | Platform: Shopify (OS 2.0, GoKwik checkout, Cloudflare) | Industry: D2C Oral Care (India)

Business context: Perfora is a Gurugram-based D2C oral-care brand (founded 2021; Shark Tank S2; ~₹70 Cr FY25 revenue). Audience is 96.1% phone / 3.9% desktop / 0% tablet (Aug 2026 CrUX) — an extreme mobile-first store where phone UX and speed are the entire game. Full context in business-analysis.md.

Executive Summary

Perfora's storefront is technically functional and SEO-literate but performance-heavy and accessibility-thin. The mobile Lighthouse Performance score is 31/100 (Poor) driven by a 6.7s LCP and 2,590ms Total Blocking Time on emulated mid-range mobile — yet real-world CrUX field data tells a better story (LCP ~2.2s Good, INP ~207–218ms Needs Improvement, CLS 0.03–0.05 Good). The gap means real users on decent devices are OK on loading, but interactivity (INP) is the one metric failing in the field, and the lab result shows how badly it degrades on slower hardware/network. SEO is strong (92), structured data is well-implemented on products/blogs, and security headers are solid. The biggest brand-risk finding is AI-generated product imagery (ChatGPT_Image_*) used on hero/conversion carousel tiles — acceptable for a science-led FMCG but worth a brand-authenticity review given Perfora's "clinically proven / design-led" positioning.

Score Card

CategoryMobile ScoreDesktop ScoreGrade
Performance31not captured (lab hung)🔴
Accessibility79not captured🟡
Best Practices73not captured🟡
SEO92not captured🟢
Overall (mobile)~69/100 (weighted)🟡
Lab desktop run did not complete in the headless browser (a known flake — the mobile run also took ~3 min). All desktop numbers below are therefore inferred from mobile lab + field data, not measured. Given the 24:1 mobile:desktop audience ratio, this is a minor gap.

Headline verdict: Fix INP (real-user interactivity failure) and the mobile LCP/lab gap first — those are the only metrics Google is actively down-ranking the site on. Then close the accessibility and schema-coverage gaps.


1. Performance Audit

1.1 CrUX Real-World Field Data

Core Web Vitals Assessment: Needs Improvement on mobile (the only platform with meaningful traffic). INP is the failing metric; LCP and CLS are Good. Desktop/tablet volumes are too small to assess meaningfully.

Source: CrUX via cruxvis.withgoogle.com, origin https://perforacare.com, "Core Web Vitals of this URL on phones," summary as of 2026-08-29.

MetricLatest field value (2026-08-29)Threshold (Good / Poor)Rating
LCP~2,244 ms (trend 2.2–3.4s over the year)≤2,500 / >4,000 ms🟢 Good (trending toward boundary)
INP~207–218 ms≤200 / >500 ms🟡 Needs Improvement
CLS0.03 (Cuxt summary 0.05)≤0.10 / >0.25🟢 Good but regressing

Field trend (phone), weekly LCP / INP / CLS:

  • Nov 2025: 3,358 ms / 257 ms / 0.08
  • Feb 2026: 3,035 ms / 187 ms / 0.03
  • May 2026: 2,974 ms / 195 ms / 0.03
  • Aug 2026: 2,244 ms / 207 ms / 0.03

Interpretation: Loading performance improved ~33% over the year (3.4s→2.2s LCP) — good engineering work. But INP climbed back above the 200ms Good threshold in mid-2026 (180ms Feb → 207ms Aug), i.e. the site got less responsive as features (GoKwik, Freshchat, Verifast chatbot, Netcore, Clarity) were added. CLS is Good-but-regressing (0.03→0.05), consistent with the 73 empty-alt images and lazy-loaded carousels causing late layout shifts.

1.2 Core Web Vitals (Lighthouse Lab Data — Mobile)

Source: PageSpeed Insights, report 2026-09-07 08:19 UTC, Lighthouse 13.4.1, emulated Moto G Power, Slow-4G throttling.

MetricMobile LabMobile ThresholdRating
FCP3.3 s≤1.8 / >3.0 s🔴 Poor
LCP6.7 s≤2.5 / >4.0 s🔴 Poor (2.7× Good)
TBT2,590 ms≤200 / >600 ms🔴 Poor (12.9× Good)
CLS0.065≤0.10 / >0.25🟢 Good
Speed Index13.2 s≤3.4 / >5.8 s🔴 Poor
Mobile vs Desktop gap: Not measured (desktop lab hung). The mobile lab result is materially worse than field because Lighthouse throttles to Slow-4G + Moto G Power; real Perfora users (urban India, 4G/5G, mid-range phones) land closer to the field numbers. The lab result is the worst-case and flags what breaks on low-end hardware.

1.3 LCP Phase Breakdown (Mobile, Lighthouse)

LCP element: homepage-banner_mobile.jpg (1800×400, loading="eager" fetchpriority="high" — correctly prioritized).

PhaseDurationNote
Time to First Byte (TTFB)80 ms✅ Excellent (Cloudflare + Shopify edge)
Resource Load Delay910 ms⚠️ Render-blocking CSS/JS delaying discovery
Resource Load Duration130 ms✅ Fine
Element Render Delay670 ms⚠️ Post-load render work
Total LCP~6.7 sTTFB is great; the 1.8s of pre-resource delay (910+670) is the killer

The LCP is discovered late because render-blocking requests (theme CSS, GoKwik merchant JS, Google Fonts) sit on the critical path. TTFB is 80ms, so this is 100% front-end bloat, not server.

1.4 Performance Issues by Impact

🔴 Critical (lab est. savings >1s)

  1. Render-blocking requests — est. 990 ms savings.
    • Evidence: custom-css.css (46.4 KiB, 1,440 ms), custom-css-simran.css (6.8 KiB, 640 ms), GoKwik merchant.integration.js (9.5 KiB, 920 ms), Google Fonts CSS (1.8 KiB, 750 ms). (PSI "Render-blocking requests" insight + URL transfer table.)
    • Fix: inline critical CSS, defer/async non-critical theme JS, self-host or preload Google Fonts with font-display: swap, load GoKwik after interaction.
  1. Main-thread blocking / INP — TBT 2,590 ms.
    • Evidence: theme.js 15,410 ms total CPU, clarity-extended.js (scripts.clarity.ms) top forced-reflow 2,500 ms, Freshchat 673 ms main-thread, GoKwik side-cart 735 KiB. Forced reflow 0.8s+. (PSI "Main-thread work" + "Forced reflow" insights.)
    • Fix: defer Microsoft Clarity + Freshchat + Verifast chatbot init until idle (requestIdleCallback), remove synchronous reflow loops, code-split theme.js.

🟡 High (200 ms–1 s)

  1. Image delivery — est. 1,943 KiB savings. Evidence: hero/product images served at 832×832 (134 KiB) for 395×702 display slots; "Improve image delivery" insight lists 2,335 KiB total with 1,927 KiB savings. Fix: responsive srcset/AVIF-WebP, right-size hero banner.
  1. Third-party script bloat. GoKwik (508 KiB, 382 KiB savable), Freshchat (629 KiB), Netcore Smartech (9.7 KiB), farziengineer wallet widget (13.3 KiB), Clarity, Verifast iframe. 7,915 DOM elements (Lighthouse "Diagnostics"). Fix: audit and lazy-init; consolidate.
  1. Inefficient cache lifetimes — est. 904 KiB. GoKwik assets None/10m TTL. Fix: set long Cache-Control on static vendor assets (theme/build control limited, but raise Shopify CDN max-age).

🟢 Medium/Low

  1. >4 preconnect connections (warning in PSI). Preconnects to cdn.shopify.com (×2), pdp.gokwik.co, fonts.googleapis.com — plus preloads. Trim to the 2–3 most critical origins.
  2. DOM size 7,915 elements (>1,500 warning) — heavy homepage with duplicated marquee/press logos. Lazy-render below-fold sections.

1.5 Resource Transfer Summary (Mobile Lab)

CategoryTransferNotable
1st-party (Shopify)~53 KiB critical CSS/JS + 2.3 MiB imagesImages dominate
GoKwik508 KiBCheckout/cart SDK — high main-thread cost
Freshchat629 KiBChat widget — lazy-load
Netcore / farziengineer / Clarity / Verifast~650 KiB combinedAnalytics + chatbot iframes

2. Accessibility Audit

2.1 Critical Issues

  • None. <html lang="en"> present, <meta name="viewport"> present, 0 images missing alt entirely. Skip-to-content link present.

2.2 High Priority Issues

  1. 4 <h1> elements on the homepage (logo, section heading, "Explore Oral Care" + a hidden one). WCAG wants a single descriptive H1. Product page has 2 H1s; collection page is cleaner. Fix: one H1 per page (brand/keyword), demote the rest to H2. Evidence: document.querySelectorAll('h1').length = 4 (home), 2 (product).
  1. 0 ARIA attributes on the homepage ([aria-] count = 0) despite interactive tabs, carousels, comboboxes, and a chatbot. Tablist/"Shop by Concern" combobox and swiper pagination bullets rely on ARIA that isn't wired. Evidence: PSI "Failing Elements" flags empty aria-label="" on collection CTA links and tab links. Fix: add aria-label to icon-only links (e.g. the announcement-bar CTAs, swiper bullets already have labels — add to CTA overlay <a aria-label=""> which currently has empty label).
  1. 73 images with alt="" on the homepage — many are content images (category tiles electric-toothbrush-category.webp, combos-category.webp, product-group graphics Group_25.webp) that are decorative-only because they sit inside linked cards with adjacent visible text. This is acceptable IF the card text is the label, but 30 on the product page (alt="" product thumbnails) should be reviewed — decorative is fine there. Evidence: img[alt=""] = 73 (home), 30 (product).
  1. Empty aria-label on collection banner CTA<a class="d-block p-absolute ..." aria-label=""> wrapping a full-bleed collection link (PSI "Failing Elements"). Fix: add descriptive aria-label ("Shop Teeth Whitening").
  1. Aggregate contrast — Lighthouse a11y = 79 (not 100) implies contrast/label issues on low-contrast text (e.g. color-light subtext on sale prices, announcement bar). Verify the announcement bar and strikethrough contrast.

2.3 Positive Findings

  • Skip-to-content link ✅, logical heading hierarchy (mostly) ✅, viewport + lang ✅, no missing-alt images ✅, form inputs have labels ✅, keyboard-reachable nav ✅, breadcrumbs on product/blog/collection ✅.

3. SEO Audit

3.1 Technical SEO

CheckStatusEvidence
robots.txt✅ ComprehensiveBlocks cart/checkout/account, allows catalog; Sitemap: directive present; even Shopify-agentic UCP/MCP documented
XML Sitemap✅ Present & structuredsitemap.xml → products/pages/collections/blogs sub-sitemaps + sitemap_agentic_discovery.xml
Canonical URLs✅ Self-referencingHome, product, collection all self-canonical (verified via DOM)
Indexation✅ No noindex on key pagesProduct/collection/blog all indexable
HTTPS✅ EnforcedCloudflare, HSTS present, upgrade-insecure-requests CSP
URL structure✅ Clean, hyphenated/products/..., /collections/..., /blogs/...
Mobile-friendly✅ Responsiveviewport set; 96% mobile audience confirms
hreflang⚠️ NoneNo alternate hreflang links (only .atom feed + self). Single-locale (en-IN) site, so not required — see §4

3.2 On-Page SEO

  • Title tags: ✅ Strong. Home: "Perfora: Clinically Proven Teeth Whitening. High Quality Oral Care – Perfora - Oral Care Solutions" (keyword-led). Product: "Buy Perfora's Automatic Electric Toothbrush Online At Best Prices". Collection: "Teeth Whitening: Get Brighter Teeth At Home!". All ≤60 chars, keyword-near-front.
  • Meta descriptions: ✅ Present on home, product, collection, blog. Unique, compelling, keyworded. (This is a common Shopify gap Perfora has avoided.)
  • Headings: ⚠️ Multiple H1s (see §2.2).
  • OG + Twitter Card: ✅ Complete on home/product/collection/blog (og:title/description/image/url/type/site_name, twitter:card=summary_large_image). Minor bug: twitter:site=@https://x.com/Perforaofficial — the value should be a handle (@Perforaofficial), not a URL. Fix the theme Liquid variable.
  • Images: 0 missing-alt (good), but 73 empty-alt (review §2.2). Filenames are descriptive (homepage-banner_mobile.jpg, electric-toothbrush-category.webp) ✅.

3.3 Schema Markup (JSON-LD)

PagePresent schemaGaps
HomeOrganization, WebSiteNo BreadcrumbList, no FAQPage, no WebSite+SearchAction (sitelinks search box missed)
ProductOrganization, Product (+ 2nd Product with AggregateRating 4.55/1168)No BreadcrumbList on product (visual breadcrumb exists but no schema); brand.name should match Organization name exactly ("Perfora - Oral Care Solutions" vs "Perfora")
CollectionOrganization, Product (hero only)No ItemList for the product grid — missed rich-result opportunity; no BreadcrumbList
Blog postOrganization, Article (headline, author "Simran Arora", date)No BreadcrumbList; Article articleBody/image present

Verified working: Product AggregateRating + reviewCount render star-rich eligibility; Organization sameAs links socials. Note: one JSON-LD block serializes schema.org as http://***schema.org/ in the source — this is a console-redaction artifact, the live block parses fine (AggregateRating confirmed present).

3.4 Internal Linking & Keyword Targeting

  • Strong: blog posts link to product collections; homepage "Explore Oral Care" + "Shop by Concern" cross-link; footer quick-links.
  • No broken internal collection links observed; no ?variant= pollution on collection pages (0 variant links of 26 product links — PLP audit sibling found the price sort broken, but variant dup-content is clean).
  • Keyword targeting aligned (whitening/toothbrush/concern pages).

3.5 E-E-A-T Signals

  • Experience/Expertise: Founder story, "clinically proven," dentist-formulated copy, author bylines on blog (Simran Arora). ✅
  • Authoritativeness: Press logos (BW Disrupt, Elle, Outlook, Times of India) on homepage marquee. ✅
  • Trustworthiness: Phone +91 9999289288, email hello@perforacare.com, full policy set (shipping/return/refund/warranty/privacy/terms), loyalty, track-order. ✅ Strong for D2C.

4. International SEO

Not applicable — single locale. The site is en-IN only (CrUX form factors + content-language: en-IN + IN localization cookie). No hreflang is expected or required. No evidence of /fr/, /de/ or other locale prefixes. Shopify's agentic-discovery sitemap is a bonus for AI crawlers, not a locale concern.


5. Best Practices & Security

5.1 Security Headers (from curl -sI)

HeaderValueAssessment
Strict-Transport-Securitymax-age=7889238 (~91 days)🟡 Weak — no includeSubDomains, no preload. Bump to max-age=31536000; includeSubDomains; preload
X-Frame-OptionsDENY
X-Content-Type-Optionsnosniff
Content-Security-Policyblock-all-mixed-content; frame-ancestors 'none'; upgrade-insecure-requests🟡 Present but no script-src/object-src directive — doesn't mitigate XSS injection; add a script-src allowlist (hard with GoKwik/Shopify inline, but nonce/strict-dynamic feasible)
X-XSS-Protection1; mode=block✅ (legacy, harmless)
Referrer-Policynot set🟢 Low — add strict-origin-when-cross-origin
Permissions-Policynot set🟢 Low — restrict camera/microphone (Verifast chatbot requests them)
COOP/COEPnot set🟢 Low

5.2 Modern Standards

  • No document.write, valid HTML5 doctype, UTF-8 declared, no mixed content (CSP enforces). ✅
  • Cloudflare + Shopify managed infra; x-download-options: noopen present. ✅
  • Verifast chatbot iframe requests allow="microphone; camera" — justify or scope down (Privacy/Permissions-Policy gap). ⚠️

6. Content Quality Assessment

6.1 Image Quality & Authenticity

🔴 Brand-risk finding: 4 ChatGPT_Image_* files on the homepage.

  • ChatGPT_Image_Jul_15_2026_02_51_22_PM.png (used as "Purple Magic Whitening Mouthwash" hero tile)
  • ChatGPT_Image_Jul_15_2026_02_28_27_PM.png (used as "Purple Magic Whitening Toothpaste" hero tile)
  • ChatGPT_Image_Aug_4_2026_04_30_13_PM.png (alt = filename itself — unlabeled, 591×455)
  • ChatGPT_Image_Aug_14_2026_10_49_04_AM.png (used as "Granite Black Power Flosser + Purple Serum" tile)

Two of these carry a product-name alt (so they're standing in for product photography), and one has no alt at all (alt literally equals the filename). For a "clinically proven / design-led" premium brand, AI-generated product imagery on above-the-fold conversion tiles is an authenticity mismatch — customers expect real product shots. Severity: Medium for general e-com, but flagged Critical-to-brand here given Perfora's positioning. Recommendation: replace with real studio product photography; at minimum rename alt text and move AI assets below the fold.

Other image notes: 73 alt="" images are mostly decorative (category icons, press logos, product group graphics) — acceptable. Homepage banner and product images are real photography. No other AI patterns (Gemini_, Picsart, unnamed_) found.

6.2 Trust Signals

Strong: phone/email visible in header + footer, 8 policy pages, loyalty program, "30k customers / 4.77 (6105 reviews)" social proof on hero, press logos, shark-tank badge in meta. ✅

6.3 Breadcrumb Navigation

Visual breadcrumbs present on product, collection, blog (✅). BreadcrumbList schema missing on all (only visual) — add JSON-LD for SERP breadcrumb rich results.

6.4 Review / Social Proof

Judge.me-style ratings render on cards + product pages with AggregateRating schema. ✅ Rich-result eligible.


7. Priority Recommendations

🔴 Immediate (This Week)

#IssueImpactEffort
1Fix INP (interactivity) — defer Clarity, Freshchat, Verifast, Netcore init via requestIdleCallback; remove forced-reflow loopsReal-user CWV fail → ranking/UXMed
2Inline critical CSS + defer/async theme + GoKwik JS (render-blocking, 990ms savable)Mobile LCP + FCPMed
3Replace ChatGPT_Image_* hero tiles with real product photography (or move below fold + fix alt)Brand authenticity / conversionLow

🟡 Short-Term (This Month)

#IssueImpactEffort
4Single H1 per page (home has 4, product has 2)Heading/SEO clarityLow
5Add BreadcrumbList schema to product/collection/blogSERP breadcrumb rich resultsLow
6Add ItemList schema to collection pagesProduct carousel rich resultsLow
7Fix twitter:site value (@https://x.com/...@Perforaofficial)Social preview correctnessLow
8Add ARIA labels to icon/CTAs with empty aria-label (collection banner, tabs)A11y (79→90+)Low
9Responsive image srcset/AVIF for hero + product (1,943 KiB savable)Mobile LCPMed
10Add script-src CSP + includeSubDomains; preload HSTS + Referrer/Permissions-PolicySecurity hardeningLow

🟢 Long-Term (This Quarter)

#IssueImpactEffort
11Audit & consolidate third-party scripts (GoKwik 508KiB, Freshchat 629KiB, farziengineer, Verifast iframe)Main-thread/TBTMed
12Reduce DOM to <1,500 (7,915 now) via lazy below-fold sectionsPerformanceMed
13Add WebSite+SearchAction schema (sitelinks search box)SERP featureLow
14Trim preconnects to 2–3 originsPerf (low)Low
15Long cache TTL on static vendor assets (GoKwik 904 KiB savable)PerfLow

Summary Score Card

CategoryScoreGrade
Performance (Mobile)31/100🔴
Accessibility79/100🟡
Best Practices73/100🟡
SEO92/100🟢
Content Quality~75/100 (AI-image brand risk)🟡
Security~78/100 (CSP/HSTS gaps)🟡
UX / Trust~88/100🟢
International SEON/A (single locale)
Overall (mobile-weighted)~69/100🟡

Sources & Citations

  1. CrUX field data — https://cruxvis.withgoogle.com/#/ (origin https://perforacare.com, phone, summary 2026-08-29; weekly LCP/INP/CLS time series Nov 2025–Aug 2026). PSI field panel cross-confirmed (Mobile CWV "Failed" = INP Needs Improvement; LCP 2.3s, CLS 0.05).
  2. Lighthouse lab (Mobile) — https://pagespeed.web.dev/ (report 2026-09-07 08:19 UTC, Lighthouse 13.4.1, Moto G Power / Slow-4G). Scores: Perf 31, A11y 79, BP 73, SEO 92. Metrics FCP 3.3s, LCP 6.7s, TBT 2,590ms, CLS 0.065, SI 13.2s. Desktop lab run did not complete (headless flake).
  3. Security headers / robots.txt / sitemapcurl -sI https://perforacare.com/, curl -sL .../robots.txt, curl -sL .../sitemap.xml (+ products/pages/collections/blogs sub-sitemaps). 2026-09-07.
  4. JS-rendered DOM inspectionbrowser_console on homepage, product (/products/electric-toothbrush-model001), collection (/collections/teeth-whitening-products), blog post (/blogs/gum-health/6-ways-to-whiten-your-teeth-at-home-backed-by-science). Schema types, OG/Twitter, H1 counts, ARIA counts, alt-text audit, AI-image filename scan (4 ChatGPT_Image_* hits), variant-link count (0/26). 2026-09-07.
  5. Business contextbusiness-analysis.md (this workspace): 96.1% phone audience, Shopify+GoKwik stack, ~₹70 Cr FY25, Shark Tank S2.
Caveat: Desktop Lighthouse lab metrics were not captured (the PSI desktop analysis hung in the headless browser). Desktop performance should be re-tested in a standard browser before drawing desktop-specific conclusions; given the 24:1 mobile audience ratio this does not change prioritization.