# Audit Report: Kodud **Website:** https://kodud.embach.ee/ **Date:** 2026-07-20 **Overall Score:** 74 / 100 **Status:** 🟔 **Needs Improvement** **Confidence:** high **Audit Coverage:** 100% — all sources returned data **Pages Audited (5 of 5):** - https://kodud.embach.ee/ - https://kodud.embach.ee/hello-world - https://kodud.embach.ee/sample-page - https://kodud.embach.ee/koik-arendused - https://kodud.embach.ee/kontakt ## Summary Site overall 74 is the mean of 5 pages. Scores range 72 (https://kodud.embach.ee/hello-world) → 78 (https://kodud.embach.ee/sample-page). Weakest page: Mobile performance (77) is dragged down by LCP 3.7 s and CLS 0.208, while desktop is excellent (99). Security headers are completely absent (0/100), which is critical given the inferred user-generated content signal. Accessibility is strong (94) but fails on the missing H1 heading structure. SEO metadata is missing (description, structured data). Confidence is high due to complete data coverage. ## Per-Page Scores | Page | Score | Status | Confidence | | --- | --- | --- | --- | | https://kodud.embach.ee/ | 74 | 🟔 **Needs Improvement** | high | | https://kodud.embach.ee/hello-world | 72 | 🟔 **Needs Improvement** | high | | https://kodud.embach.ee/sample-page | 78 | 🟔 **Needs Improvement** | high | | https://kodud.embach.ee/koik-arendused | 72 | 🟔 **Needs Improvement** | high | | https://kodud.embach.ee/kontakt | 72 | 🟔 **Needs Improvement** | high | ## PageSpeed Insights — Mobile vs Desktop _Lower is worse for Performance; higher is worse for LCP and CLS. Worse value is **bolded**._ | URL | Performance (M / D) | LCP (M / D) | CLS (M / D) | | --- | --- | --- | --- | | https://kodud.embach.ee/ | **76** / 77 | **3.35 s** / 1.01 s | 0.287 / **0.571** | | https://kodud.embach.ee/hello-world | **77** / 99 | **3.74 s** / 858 ms | **0.208** / 0.007 | | https://kodud.embach.ee/sample-page | **82** / 99 | **3.71 s** / 926 ms | 0.000 / **0.007** | | https://kodud.embach.ee/koik-arendused | **76** / 97 | **5.18 s** / 1.21 s | 0.000 / **0.000** | | https://kodud.embach.ee/kontakt | **82** / 99 | **4.50 s** / 915 ms | 0.000 / **0.000** | ## Optimization Checklist **1 of 3 passing** — 1 pass Ā· 1 warn Ā· 1 fail Ā· 4 n/a | Item | Status | Detail | | --- | --- | --- | | Page caching plugin / CDN active | **Pass** | Caching plugin detected (WP Rocket) | | Images lazy-loaded | N/A | No raster elements found. | | Hero image eagerly loaded | **Fail** | Hero image has loading="lazy", which delays LCP (inferred from DOM order/size — Lighthouse LCP element unavailable). Use loading="eager" (or omit loading) and add fetchpriority="high". | | Hero is a real (not a CSS background-image) | N/A | No CSS background-images detected on raster-image-eligible elements. | | Responsive images (srcset / ) | N/A | Only 0 raster images on the page — responsive-image rule does not apply. | | Reasonable number of image sizes | N/A | Too few raster images to evaluate srcset width variety. | | JS scripts not blocking in | **Warn** | 2 render-blocking scripts in . Move to footer or add defer/async. | ## Fixes ### Priority 1: Critical *Immediate action — impacts user experience, search rankings, or site safety.* **1A. Fix Cumulative Layout Shift (CLS) on Carousel** - **Impact:** Core Web Vitals, User Experience - **Problem:** CLS is 0.287 (mobile) and 0.571 (desktop), exceeding the 0.25 threshold. The shift source is identified as 'div.projects-carousel__slider'. - **Solution:** Reserve space for the carousel container using `min-height` or `aspect-ratio` in CSS to prevent layout shifts during image loading. ```css .projects-carousel__slider { min-height: 400px; /* Adjust to actual content height */ aspect-ratio: 16 / 9; } ``` **1B. Implement Missing Security Headers** - **Impact:** Security, Transport Integrity - **Problem:** Security Headers grade is 0/100. HSTS, X-Frame-Options, X-Content-Type-Options, and CSP are all missing. UGC signal is 'yes', elevating CSP to Priority 1. - **Solution:** Add the following headers to the server response (Apache example): ```apache Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" Header always set X-Content-Type-Options "nosniff" Header always set X-Frame-Options "SAMEORIGIN" Header always set Content-Security-Policy "default-src 'self'; script-src 'nonce-{random}' 'strict-dynamic';" ``` **1C. Optimize Largest Contentful Paint (LCP)** - **Impact:** Performance, LCP Metric - **Problem:** LCP is 3.3 s on mobile, exceeding the 2.5 s good threshold. 6 render-blocking scripts and 109 KB unused JS contribute to delay. - **Solution:** 1. Defer non-critical scripts (add `defer` or `async` to 6 render-blocking scripts). 2. Preload the hero image resource. 3. Remove or tree-shake the 109 KB unused JavaScript (`global.04cbabbf7670bc75.js`). ```html ``` **1D. Add a single H1 heading to the page** - **Impact:** SEO, Accessibility (WCAG 1.3.1) - **Problem:** HTML Inventory reports 0 H1 elements; axe-core flags 'page-has-heading-one' as a moderate violation. - **Solution:** Ensure the main title of the post/page is wrapped in a single `

` tag. ```html

Hello world!

``` **1E. Implement baseline security headers (HSTS, CSP, X-Frame-Options)** - **Impact:** Transport security, XSS defense, Clickjacking - **Problem:** Security Headers grade is 0/100; HSTS and CSP are missing despite UGC signal (yes) increasing XSS risk. - **Solution:** Add to server config (Apache example): ```apache Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" Header always set X-Frame-Options "SAMEORIGIN" Header always set X-Content-Type-Options "nosniff" Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-{random}' 'strict-dynamic';" ``` **1F. Implement Critical Security Headers (HSTS, CSP)** - **Impact:** Security, XSS protection, Clickjacking - **Problem:** Security Headers grade is 0/100; HSTS and CSP are missing. Site signals indicate user-generated content (UGC), elevating XSS risk. - **Solution:** Add the following headers to your server configuration (e.g., Apache .htaccess or Nginx): ```apache Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" Header always set X-Content-Type-Options "nosniff" Header always set X-Frame-Options "SAMEORIGIN" Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-{random}' 'strict-dynamic'; object-src 'none'; base-uri 'none';" ``` Ensure CSP uses nonces/hashes for scripts rather than a permissive allowlist. **1G. Fix Hero Image Loading for LCP** - **Impact:** LCP, FCP, Performance Score - **Problem:** LCP is 5.2 s on mobile; checklist confirms hero image has loading='lazy' which delays rendering. - **Solution:** Remove `loading="lazy"` from the hero image and add `fetchpriority="high"`: ```html ... ``` **1H. Implement HSTS and CSP Headers** - **Impact:** Security Headers Grade, XSS/Clickjacking Defense - **Problem:** Security grade is 0/100; HSTS and CSP are missing. UGC signal is 'yes', raising CSP priority per rubric. - **Solution:** Add HSTS and a strict CSP (nonce-based) to server config: ```apache Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" Header always set Content-Security-Policy "default-src 'self'; script-src 'nonce-{random}' 'strict-dynamic';" ``` **1I. Implement Baseline Security Headers** - **Impact:** Security, Transport Integrity - **Problem:** Security Headers grade is 0/100; HSTS, X-Frame-Options, and X-Content-Type-Options are missing. - **Solution:** Add these headers via server config (Apache example): ```apache Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains" Header always set X-Frame-Options "SAMEORIGIN" Header always set X-Content-Type-Options "nosniff" ``` **1J. Add Content-Security-Policy (CSP)** - **Impact:** XSS Defense - **Problem:** CSP is missing and Site Signals infer User-Generated Content (anchor href contains "post"), elevating XSS risk. - **Solution:** Deploy a strict CSP with nonces rather than a flat allowlist: ```apache Header always set Content-Security-Policy "default-src 'self'; script-src 'nonce-{random}' 'strict-dynamic';" ``` ### Priority 2: Important *Essential for compliance, user reach, and search visibility.* **2A. Add Meta Description and Structured Data** - **Impact:** SEO, Search Visibility - **Problem:** PSI SEO audit fails on `metaDescription` and `structuredData`. HTML inventory confirms no meta description or JSON-LD present. - **Solution:** Add a unique meta description (150-160 chars) and relevant JSON-LD (e.g., `RealEstateAgent` or `LocalBusiness`). ```html ``` **2B. Reduce Cumulative Layout Shift (CLS) caused by footer** - **Impact:** Core Web Vitals (CLS), User Experience - **Problem:** CLS is 0.208 (warning zone); PSI identifies footer div as the primary shift source (0.197). - **Solution:** Reserve space for dynamic footer content or ensure footer elements have explicit dimensions. ```css footer.footer { min-height: 200px; /* Reserve space */ } ``` **2C. Defer non-critical render-blocking scripts** - **Impact:** LCP, FCP, Performance Score - **Problem:** 6 render-blocking scripts detected; 117 KB unused JS identified in global.js. - **Solution:** Add `defer` or `async` to script tags in `` unless they are critical for initial render. ```html ``` **2D. Defer Render-Blocking Scripts** - **Impact:** LCP, FCP, Performance Score - **Problem:** 6 render-blocking scripts identified in PSI and HTML Inventory; LCP is 3.7 s and FCP is 3.23 s on mobile. - **Solution:** Move non-critical scripts to the footer or add `defer`/`async` attributes. For WordPress, use a plugin like WP Rocket (already detected) to delay JS execution or minify/combine scripts. ```html ``` **2E. Remove Unused JavaScript** - **Impact:** Page Weight, TBT, Performance Score - **Problem:** 117 KB of unused JavaScript detected in `global.04cbabbf7670bc75.js`. - **Solution:** Audit `global.js` and `core.js` for unused functions. Use code splitting or tree-shaking in your build process. If using WordPress, disable unused theme/plugin scripts via a performance plugin. **2F. Add H1 Heading Element** - **Impact:** Accessibility (Axe), SEO (W3C) - **Problem:** W3C warns no H1; Axe reports 'page-has-heading-one' violation. Page uses H2s for main titles. - **Solution:** Ensure the primary page title is wrapped in `

`: ```html

KƵik arendused

``` **2G. Add Meta Description** - **Impact:** SEO (PSI Score 0) - **Problem:** PSI SEO audit fails 'metaDescription'; HTML inventory confirms description is not set. - **Solution:** Add a unique description tag in ``: ```html ``` **2H. Fix Accessibility Violations** - **Impact:** WCAG 2.4.4, 2.5.8 - **Problem:** PSI flags `button-name` and `target-size` with 0.00 scores; touch targets are too small and buttons lack accessible names. - **Solution:** - Ensure all buttons have visible text or `aria-label`. - Increase touch target padding to at least 44Ɨ44 px per WCAG 2.5.8. **2I. Defer Render-Blocking JavaScript** - **Impact:** FCP, TBT, Performance - **Problem:** 6 render-blocking scripts detected; 117 KB unused JS contributes to long tasks. - **Solution:** Add `defer` or `async` to non-critical scripts in ``: ```html ``` ### Priority 3: Best Practice *Recommended for long-term maintainability.* **3A. Ensure Lazy Loading on All Below-Fold Images** - **Impact:** Page Weight, Load Time - **Problem:** HTML inventory shows 1 image missing `loading="lazy"` despite being below the fold. Total page weight is 795.5 KB. - **Solution:** Audit all images below the fold and add `loading="lazy"` attribute. Ensure hero images remain `eager` or `fetchpriority="high"`. ```html Description ``` **3B. Add meta description and structured data** - **Impact:** SEO (Search Appearance) - **Problem:** PSI SEO audit fails on `metaDescription` and `structuredData`; HTML Inventory confirms 0 Open Graph/Twitter tags. - **Solution:** Add meta description and JSON-LD schema to the ``: ```html ``` **3C. Verify Button Accessibility Names** - **Impact:** Accessibility, WCAG 2.4.4 - **Problem:** PSI reports `button-name` failure (score 0.00) despite axe-core showing 0 violations; manual check needed. - **Solution:** Inspect all ` ``` **3D. Add Meta Description and Open Graph Tags** - **Impact:** SEO, Social Sharing - **Problem:** SEO audit fails `metaDescription`; no Open Graph or Twitter tags present. - **Solution:** Add to ``: ```html ``` **3E. Fix W3C HTML Validation Errors** - **Impact:** Maintainability, Rendering Consistency - **Problem:** 2 errors found: `srcset` missing width specification and stray `

` end tag. - **Solution:** - Update `srcset` to include width descriptors (e.g., `image.jpg 400w`). - Remove the extra `

` tag at line 538.