140 lines
6.6 KiB
Markdown
140 lines
6.6 KiB
Markdown
# Metatroncube Lighthouse & SEO Optimization — Full Change Log
|
|
|
|
**Completed:** April 2026
|
|
**Target:** 100/100 on all Lighthouse categories (Performance, Accessibility, Best Practices, SEO)
|
|
**Starting scores:** Performance 75 | Accessibility 88 | Best Practices 77 | SEO 100
|
|
|
|
---
|
|
|
|
## ✅ Performance Fixes
|
|
|
|
### CSS Render-Blocking Eliminated
|
|
- **bootstrap.min.css, main.css, spacing.css** → kept as critical (required for initial paint)
|
|
- **fontawesome-pro.css, animate.css, swiper.min.css, slick.css, magnific-popup.css, meanmenu.min.css** → deferred using `media="print" onLoad="this.media='all'"` pattern (~820ms savings)
|
|
- **Google Fonts (Inter)** → moved from `@import` in `main.css` to async `<link>` in layout.tsx with preconnect hints
|
|
- Added `<noscript>` fallbacks for all deferred CSS
|
|
|
|
### Font Display
|
|
- **fontawesome-pro.css** → changed `font-display:block` → `font-display:swap` in all 15 @font-face rules
|
|
- **Google Fonts URL** → includes `&display=swap` parameter
|
|
|
|
### LCP (Largest Contentful Paint)
|
|
- **BannerSection.tsx** → First slide hero image: `loading="eager"` + `fetchPriority="high"`
|
|
- All other slide images: `loading="lazy"` + `fetchPriority="low"`
|
|
- Added DNS prefetch for `fonts.googleapis.com` + `fonts.gstatic.com`
|
|
- Added preconnect for Google Fonts servers
|
|
|
|
### Image CLS (Cumulative Layout Shift) — 25+ images fixed
|
|
- **Header1.tsx** logo → `width="260" height="78"`
|
|
- **Footer1.tsx** logo → `width="200" height="60"`
|
|
- **BannerSection.tsx** → all 4 hero images + service slider thumbnails
|
|
- **AboutSection.tsx** → main image + 3 icon images
|
|
- **TestimonialsSection.tsx** → left panel image + reviewer profile images
|
|
- **BrandSection.tsx** → brand logos
|
|
- **ChooseSection.tsx** → main image + small image
|
|
- **WhyChooseUs.tsx** → 2 images
|
|
- **Results.tsx** → 3 images
|
|
- **AboutService.tsx** → 3 images
|
|
- **ServiceDetails.tsx** → 3 images
|
|
- **PortfolioSection.tsx** → 6 images
|
|
- **MemberCard.tsx** → team photo + share icon
|
|
|
|
### JavaScript Optimizations
|
|
- **next.config.ts** → `reactStrictMode: true`, removed unused `headers()`, removed `domains` array
|
|
- Removed duplicate GA script (GTM handles GA)
|
|
- `counterup.js` removed (counter now uses React IntersectionObserver)
|
|
|
|
---
|
|
|
|
## ✅ Accessibility Fixes (WCAG 2.1 AA)
|
|
|
|
### Heading Order (heading-order audit)
|
|
- All `<h6 className="sec-title__tagline">` → `<p className="sec-title__tagline">` across ~25 components
|
|
- **AboutSection.tsx** `<h3>Let's Work Together</h3>` → `<h2>` (proper section heading)
|
|
- **AboutSection.tsx** `<h4>10+ Years</h4>` → `<p className="h4">` (purely visual, not semantic)
|
|
- **ChooseSection.tsx** fixed mismatched heading tags after bulk replacement
|
|
|
|
### Button & Link Names (button-name, link-name audits)
|
|
- **BannerSection.tsx** slider arrows → `aria-label="Previous/Next service"`, icons → `aria-hidden="true"`
|
|
- **Header1.tsx** hamburger → `aria-label`, `aria-expanded`, `aria-controls`
|
|
- **BackToTop.tsx** → `div` → `<button>` with `aria-label="Back to top"`
|
|
- **SearchOverlay.tsx** → close button, search input, submit button all labeled
|
|
- **Offcanvas.tsx** → all 5 social links labeled
|
|
- **Footer1.tsx** → all 5 social links labeled + newsletter input `aria-label`
|
|
- **Footer (mobile-app service)** → all 5 social links labeled
|
|
- **Footer (web-dev service)** → all 5 social links labeled
|
|
- **MemberCard.tsx** → all 4 social links + share link labeled
|
|
- **BlogSidebar.tsx** → search input + submit button labeled
|
|
- **ContactPopup.tsx** → 4 inputs + textarea labeled
|
|
- **HomeContactOne.tsx** → inputs labeled
|
|
- **ContactSection.tsx (contact page)** → inputs labeled
|
|
- **ContactSection.tsx (careers)** → inputs labeled
|
|
- **FaqVideoSection.tsx** → inputs labeled
|
|
- **CareersContactPopup.tsx** → inputs labeled
|
|
|
|
### Color Contrast (WCAG AA 4.5:1 minimum)
|
|
- **globals.css** `#89868d` (3.32:1) → `#595959` (7.9:1)
|
|
- **globals.css** `#7F7D86` (4.21:1) → `#595959` (7.9:1)
|
|
- **globals.css** `--pelocis-text-dark: #636363` → `#4a4a4a`
|
|
|
|
### Navigation & Skip Links
|
|
- **globals.css** → `.skip-to-content-link` added (keyboard accessibility)
|
|
- **layout.tsx** → `<a href="#main-content" className="skip-to-content-link">Skip to main content</a>`
|
|
- **All 13 page.tsx + BlogDetailsClient.tsx** → `<main id="main-content">`
|
|
- **mobile-app-service MainLayout** → `<main id="main-content">`
|
|
- **web-dev-service MainLayout** → `<main id="main-content">`
|
|
- **Header1.tsx** → `<nav aria-label="Main navigation">`
|
|
|
|
### Image Alt Text
|
|
- Decorative images → `alt=""` + `aria-hidden="true"`
|
|
- Informative images → descriptive alt text added
|
|
- **Footer logos** → meaningful alt text
|
|
|
|
---
|
|
|
|
## ✅ SEO Fixes (maintained 100/100)
|
|
|
|
### Structured Data (JSON-LD)
|
|
- **layout.tsx** → `LocalBusiness` + `ProfessionalService` + `Organization` schema
|
|
- **layout.tsx** → `WebSite` schema with `SearchAction`
|
|
- **faq/page.tsx** → `FAQPage` schema with 19 Q&As
|
|
- **service/[slug]/page.tsx** → `BreadcrumbList` schema per service page
|
|
|
|
### GEO (Generative Engine Optimization)
|
|
- **public/llms.txt** → complete entity data for AI crawlers (address, services, socials, ratings)
|
|
- **public/robots.txt** → AI crawlers allowed: GPTBot, ClaudeBot, PerplexityBot, ChatGPT-User, anthropic-ai, YouBot, Bingbot
|
|
- **robots.txt** → removed Disallow rules blocking service pages
|
|
|
|
### AEO (Answer Engine Optimization)
|
|
- FAQPage schema with answer text covering all major questions visible on the /faq page
|
|
|
|
---
|
|
|
|
## ⚠️ Known Limitations (Cannot Fix in Code)
|
|
|
|
### Best Practices (77 → expected ~85 on production)
|
|
- **Third-party cookies (24)** — from GTM, reCAPTCHA v2, Microsoft Clarity. These are by design. Consider: reCAPTCHA v3 (invisible) to reduce footprint.
|
|
- **Back/Forward cache (bf-cache)** — blocked by Clarity.js + reCAPTCHA
|
|
- Score will improve on production HTTPS vs localhost HTTP
|
|
|
|
### Performance (75 → expected 90+ on production)
|
|
- **Unused CSS/JS** — shows as 1,212 KiB / 1,343 KiB on dev server. Production `npm run build` minifies and tree-shakes automatically. These numbers drop dramatically.
|
|
- **Total Blocking Time** — heavy JS bundles from jQuery + Swiper + Slick. Consider lazy-loading components that are below fold.
|
|
|
|
---
|
|
|
|
## 🚀 Deployment Checklist
|
|
|
|
1. `npm run build` → verify TypeScript compiles cleanly
|
|
2. Set nginx cache headers:
|
|
```nginx
|
|
location ~* \.(js|css|woff2|webp|png|jpg|svg)$ {
|
|
expires 1y;
|
|
add_header Cache-Control "public, immutable";
|
|
}
|
|
```
|
|
3. Run Lighthouse on production URL (not localhost) for accurate scores
|
|
4. Add Google Search Console verification token in layout.tsx metadata
|
|
5. Submit sitemap: `https://metatroncubesolutions.com/sitemap.xml`
|
|
|