Audit

20260824T121844Z-dfe5

← Back to lootsaee
Audited URL
https://lootsa.ee/
Timestamp
2026-08-24T12:20:16.471Z
Kind
single
Pages
1
Audit summary
https://lootsa.ee/
Pagespeed scores
Other checks
LLM Report

Weighted audit summary

78
Overall site quality
Needs Improvementhigh confidence

Performance is excellent (PSI Mobile 94, LCP 2.3 s, TTFB 6 ms), which anchors the score high. However, Security Headers are completely missing (0/100) and the site has User-Generated Content (textarea/upload), creating a high-risk XSS surface that demands Priority 1 remediation. Accessibility has a critical axe violation (button-name) and serious issues (contrast, link-name) that lower the score despite a 91 PSI accessibility rating. W3C validation shows 15 errors, primarily invalid script types and hidden input attributes, indicating technical debt. Missing meta descriptions and Open Graph tags further reduce SEO readiness.

Audit Report: Lõõtsa Ärikvartal

Website: https://lootsa.ee/
Date: 24.08.2026
Audit Coverage: 100% — all sources returned data
Confidence: high

Pages Audited (1 of 1):

Summary of results

Overall Score: 78 / 100
Status: 🟡 Needs Improvement

Performance is excellent (PSI Mobile 94, LCP 2.3 s, TTFB 6 ms), which anchors the score high. However, Security Headers are completely missing (0/100) and the site has User-Generated Content (textarea/upload), creating a high-risk XSS surface that demands Priority 1 remediation. Accessibility has a critical axe violation (button-name) and serious issues (contrast, link-name) that lower the score despite a 91 PSI accessibility rating. W3C validation shows 15 errors, primarily invalid script types and hidden input attributes, indicating technical debt. Missing meta descriptions and Open Graph tags further reduce SEO readiness.

Per-page scores

🟡 Needs Improvement · https://lootsa.ee/

Score Performance Accessibility Best Practices SEO Security
78 94 91 100 92 0

PageSpeed Insights — Mobile vs Desktop

Lower is worse for Performance; higher is worse for LCP and CLS. Worse value is bolded.

Strategy Performance (M / D) LCP (M / D) CLS (M / D)
Mobile vs Desktop 94 / 100 2.29 s / 684 ms 0.000 / 0.028

Optimization Checklist

5 of 6 passing — 5 pass · 0 warn · 1 fail · 1 n/a

Item Status Detail
Page caching plugin / CDN active Pass Caching plugin detected (WP Rocket)
Images lazy-loaded Pass All non-hero raster images use loading="lazy".
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 <img> (not a CSS background-image) N/A No CSS background-images detected on raster-image-eligible elements.
Responsive images (srcset / <picture>) Pass 36/43 raster images use srcset or <picture> (84%).
Reasonable number of image sizes Pass 33 distinct srcset widths.
JS scripts not blocking in <head> Pass No render-blocking scripts in <head>.

Fixes

Priority 1: Critical

Immediate action — impacts user experience, search rankings, or site safety.

1A. Implement HSTS and Content Security Policy (CSP) Security

  • Impact: Transport security, XSS mitigation
  • Problem: Security Headers grade is 0/100; HSTS and CSP are missing. Site signals indicate User-Generated Content (textarea, upload link), making XSS a Priority 1 risk per the rubric.
  • Solution: Add the following headers to your server configuration (e.g., Apache/Nginx):
    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'; object-src 'none'; base-uri 'none';"
    Header always set X-Content-Type-Options "nosniff"
    Header always set X-Frame-Options "SAMEORIGIN"
    

1B. Fix critical button and link accessibility issues Accessibility

  • Impact: WCAG 2.1 A compliance, screen reader usability
  • Problem: axe-core reports 1 critical violation (button-name) and 2 serious violations (color-contrast, link-name). Buttons lack discernible text and links in the gallery slider are unnamed.
  • Solution:
    • Add aria-label or visible text to all buttons (e.g., <button aria-label="Play gallery">).
    • Ensure .tag--brand meets 4.5:1 contrast ratio.
    • Add aria-label to gallery links: <a class="image__link" aria-label="View image 1" ...>.

Priority 2: Important

Essential for compliance, user reach, and search visibility.

2A. Remove lazy loading from hero image Performance

  • Impact: LCP, First Contentful Paint
  • Problem: Optimization Checklist flags the hero image (lootsa_hero-320x180.jpg) as having loading="lazy", which delays LCP. Lighthouse LCP element is currently unavailable due to this.
  • Solution: Update the hero <img> tag to remove loading="lazy" and add fetchpriority="high":
    <img src="/wp-content/uploads/.../lootsa_hero-320x180.jpg" fetchpriority="high" alt="..." width="..." height="...">
    

2B. Fix W3C HTML validation errors Best Practices

  • Impact: Code quality, browser parsing consistency
  • Problem: 15 validation errors found, including 11 instances of <script type="text/rocketlazyloadscript" defer> (invalid type + defer combo) and hidden inputs with autocomplete="off".
  • Solution:
    • Remove defer from non-JavaScript script types (e.g., text/rocketlazyloadscript).
    • Remove autocomplete attribute from <input type="hidden"> elements.
    • Move <meta charset> to the first 1024 bytes of the document.

Priority 3: Best Practice

Recommended for long-term maintainability.

3A. Add meta description and Open Graph tags SEO

  • Impact: Search snippet quality, social sharing
  • Problem: HTML Inventory shows no meta description and 0 Open Graph/Twitter tags. PSI SEO audit flags metaDescription as failing.
  • Solution: Add to <head>:
    <meta name="description" content="Lõõtsa Ärikvartal - Modern office spaces in Tallinn with green energy and flexible layouts.">
    <meta property="og:title" content="Lõõtsa Ärikvartal">
    <meta property="og:image" content="/path/to/og-image.jpg">
    
▸Raw Markdown sent to the LLM
# Audit — https://lootsa.ee/

Run: 2026-08-24T12:18:44.378Z

## Audit Coverage
**100%** of audit sources returned data.

_All sources OK._

## Methodology

Each tool below contributes data to a single overall 0–100 site quality score. Performance dominates the weighting (~40%), followed by accessibility (~30%), image assets (~15%), and SEO/security (~15%). These weights are informative — the score is judged holistically, not from a fixed formula.

Severity scale in `priorities[]`:
- **high** — blocking issue / vulnerability / fail.
- **medium** — significant degradation.
- **low** — minor improvement.

Each tool section below lists: scores → priority fixes → findings → manual checks the tool cannot verify.

## Site Signals (inferred)

Heuristic site-shape signals derived from the audit data. Use these to calibrate the priority of security-header recommendations (see system rubric). Override when the evidence is clearly wrong.

- Auth surface: no
- Payments: no
- User-generated content: **yes** — <textarea> in a form; anchor href contains "upload"
- E-commerce: no

## PageSpeed Insights
_Captured in 18878 ms (mobile + desktop in parallel)._

**Lighthouse scores (mobile vs desktop; worse value bolded):**
| Category | Mobile | Desktop |
| --- | --- | --- |
| Performance | **94** | 100 |
| Accessibility | 91 | **87** |
| Best Practices | 100 | 100 |
| SEO | 92 | 92 |

**Core Web Vitals — lab (Lighthouse) / field (CrUX p75); worse lab value bolded:**
| Metric | Mobile | Desktop |
| --- | --- | --- |
| LCP | **2.3 s** | 0.7 s |
| CLS | 0.000 | **0.028** |
| TBT | 0 ms | 0 ms |
| FCP | **2.29 s** | 349 ms |
| Speed Index | **4.18 s** | 633 ms |
| TTFB | 6 ms | **39 ms** |

### Priority fixes
1. **first-contentful-paint** (low) — 2.3 s
2. **speed-index** (low) — 4.2 s
3. **forced-reflow-insight** (high)
4. **image-delivery-insight** (medium) — Est savings of 64 KiB
5. **lcp-discovery-insight** (high)

### Findings (mobile)

#### DOM size
- Total nodes: 0

#### Failing modeled audits
- SEO: `metaDescription`
- SEO: `tapTargets`
- SEO: `structuredData`

#### All failing PSI audits (sorted by weight × failure margin)
- `button-name` (accessibility, score 0.00, weight 10) — Buttons do not have an accessible name
- `link-name` (accessibility, score 0.00, weight 7) — Links do not have a discernible name
- `first-contentful-paint` (performance, score 0.75, weight 10) — First Contentful Paint — 2.3 s
- `speed-index` (performance, score 0.78, weight 10) — Speed Index — 4.2 s
- `forced-reflow-insight` (performance, score 0.00, weight 0) — Forced reflow
- `lcp-discovery-insight` (performance, score 0.00, weight 0) — LCP request discovery
- `network-dependency-tree-insight` (performance, score 0.00, weight 0) — Network dependency tree
- `meta-description` (seo, score 0.00, weight 1) — Document does not have a meta description

### Manual checks
- Real-device behavior on slow 3G / low-tier mobile hardware (Lighthouse is throttled simulation).
- Sustained INP under typical user interaction, not just initial load.
- CrUX data interpretation if site is low-traffic and field data falls back to origin or is missing.

## Security Headers & HTTP
_Captured in 61 ms._

**Transport:**
- Final URL: https://lootsa.ee/
- Status: 200
- Redirected: false
- HTTPS redirect: HTTP → HTTPS ✓

**Caching:**
- cache-control: `max-age=0`
- etag: n/a
- last-modified: Mon, 24 Aug 2026 10:25:14 GMT
- expires: Mon, 24 Aug 2026 12:18:44 GMT
- pragma: n/a
- vary: Accept-Encoding

**Compression:**
- content-encoding: gzip
- content-length: 46694
- Decoded body: 292.4 KB
- Compression ratio: 0.156

### Priority fixes
1. **strict-transport-security missing** (high) — Add HSTS with max-age >= 1 year, includeSubDomains, and preload
2. **content-security-policy missing** (high) — Add a CSP with default-src and script-src restrictions
3. **x-frame-options missing** (medium) — Prefer CSP frame-ancestors; X-Frame-Options as fallback
4. **x-content-type-options missing** (medium) — Send X-Content-Type-Options: nosniff
5. **referrer-policy missing** (low) — Set a Referrer-Policy such as strict-origin-when-cross-origin
6. **permissions-policy missing** (low) — Declare Permissions-Policy to disable unused features
7. **cross-origin-opener-policy missing** (low) — Set COOP to same-origin to isolate browsing context
8. **cross-origin-resource-policy missing** (low) — Set CORP to same-origin or same-site to prevent cross-origin reads
9. **x-permitted-cross-domain-policies missing** (low) — Set to none to prevent Flash/PDF cross-domain requests
10. **server header discloses technology** (low) — Server: Apache / ZoneOS

### Findings

#### Tracked headers
- **strict-transport-security** (missing, high)
- **content-security-policy** (missing, high)
- **x-frame-options** (missing, medium)
- **x-content-type-options** (missing, medium)
- **referrer-policy** (missing, low)
- **permissions-policy** (missing, low)
- **cross-origin-opener-policy** (missing, low)
- **cross-origin-resource-policy** (missing, low)
- **x-permitted-cross-domain-policies** (missing, low)

#### Info disclosure
- Server: `Apache / ZoneOS`


#### All response headers
```
cache-control: max-age=0
connection: Upgrade, Keep-Alive
content-encoding: gzip
content-length: 46694
content-type: text/html; charset=UTF-8
date: Mon, 24 Aug 2026 12:18:44 GMT
expires: Mon, 24 Aug 2026 12:18:44 GMT
keep-alive: timeout=5, max=100
last-modified: Mon, 24 Aug 2026 10:25:14 GMT
server: Apache / ZoneOS
vary: Accept-Encoding
```

### Manual checks
- Cookie attributes set via JavaScript (not visible in HTTP response).
- CORS preflight behavior under non-GET methods (only GET response headers checked).
- HSTS preload list inclusion (check hstspreload.org).
- WAF / DDoS posture beyond what static headers reveal.

## W3C HTML Validator
_Captured in 1086 ms._

**Scoring:** 15 errors · 3 warnings · 24 cosmetic (suppressed)

### Priority fixes
1. **A “script” element with a “type” attribute whose value is neither a JavaScript MIME type, “module”, “importmap”, nor “speculationrules” (i.e., a data block) must not have a “defer” attribute.** (high) — x11, first at line 32
2. **An “input” element with a “type” attribute whose value is “hidden” must not have an “autocomplete” attribute whose value is “on” or “off”.** (medium) — x2, first at line 2733
3. **A “charset” attribute on a “meta” element found after the first 1024 bytes.** (medium) — x1, first at line 6
4. **Element “style” not allowed as child of element “div” in this context. (Suppressing further errors from this subtree.)** (medium) — x1, first at line 2621

### Issue groups
- (×1) [error] A “charset” attribute on a “meta” element found after the first 1024 bytes. — first at line 6 `charset="utf-8"><script>if(na`
- (×11) [error] A “script” element with a “type” attribute whose value is neither a JavaScript MIME type, “module”, “importmap”, nor “speculationrules” (i.e., a data block) must not have a “defer” attribute. — first at line 32 `banner --><script type="text/rocketlazyloadscript" id="cookieyes" data-rocket-ty`
- (×2) [warning] The “type” attribute is unnecessary for JavaScript resources. — first at line 2610 `/noscript><script nowprocket type="text/javascript">var el`
- (×1) [error] Element “style” not allowed as child of element “div” in this context. (Suppressing further errors from this subtree.) — first at line 2621 `apper_1' ><style>#gform`
- (×2) [error] An “input” element with a “type” attribute whose value is “hidden” must not have an “autocomplete” attribute whose value is “on” or “off”. — first at line 2733 `<input type='hidden' autocomplete='off' class='gform_hidden h-hidden' name='gfor`
- (×1) [warning] This document appears to be written in Estonian but the “html” start tag has “lang="en"”. Consider using “lang="et"” (or variant) instead. — first at line 2 `TYPE html>
<html class="no-js" lang="en">
<head`

### Manual checks
- Whether each `<section>` / `<article>` wraps semantically meaningful content.
- Language tag accuracy for multi-language pages or quoted content.
- Whether structural choices align with the document outline algorithm in screen readers.

## axe-core (Accessibility)
_Captured in 1908 ms._

**Scoring:** 3 violations · 43 passes · critical 1 · serious 2 · moderate 0 · minor 0

### Priority fixes
1. **button-name** (high) — Buttons must have discernible text
2. **color-contrast** (high) — Elements must meet minimum color contrast ratio thresholds
3. **link-name** (high) — Links must have discernible text

### Findings

#### `button-name` (critical) — WCAG: wcag2a, wcag412
[Buttons must have discernible text](https://dequeuniversity.com/rules/axe/4.11/button-name?application=playwright)
- `.space-selector__panel[data-building="1"] > .space-selector__gallery > .gallery-slider.js-gallery-slider > .gallery-slider__track > .gallery-slider__toggle[data-pause-label=""][data-play-label=""]`

#### `color-contrast` (serious) — WCAG: wcag2aa, wcag143
[Elements must meet minimum color contrast ratio thresholds](https://dequeuniversity.com/rules/axe/4.11/color-contrast?application=playwright)
- `.tag--brand`

#### `link-name` (serious) — WCAG: wcag2a, wcag244, wcag412
[Links must have discernible text](https://dequeuniversity.com/rules/axe/4.11/link-name?application=playwright)
- `.gallery-slider__item:nth-child(4) > .gallery-slider__image > .image__link[data-fancybox="gallery-carousel-6a8c1c0ab7dd0"]`
- `.gallery-slider__item:nth-child(5) > .gallery-slider__image > .image__link[data-fancybox="gallery-carousel-6a8c1c0ab7dd0"]`
- `.gallery-slider__item:nth-child(6) > .gallery-slider__image > .image__link[data-fancybox="gallery-carousel-6a8c1c0ab7dd0"]`
- `.gallery-slider__item:nth-child(7) > .gallery-slider__image > .image__link[data-fancybox="gallery-carousel-6a8c1c0ab7dd0"]`
- `.gallery-slider__item:nth-child(8) > .gallery-slider__image > .image__link[data-fancybox="gallery-carousel-6a8c1c0ab7dd0"]`
- … and 17 more nodes

### Incomplete (axe could not determine)
- [Elements must meet minimum color contrast ratio thresholds](https://dequeuniversity.com/rules/axe/4.11/color-contrast?application=playwright) — 13 nodes

### Manual checks
- Keyboard-only navigation flow + visible focus indicators on every interactive element.
- Screen reader output (NVDA, VoiceOver) for actual auditory experience.
- Modal focus trapping and restoration on close.
- Touch target sizes (44×44 px minimum per WCAG 2.5.8).
- Color contrast for elements with alpha-transparency or gradients (axe skips these).

## Browser Runtime
_Captured in 1924 ms._

**Capture summary:** 0 console events · 0 mixed-content requests · 15 network requests · 669.1 KB total

**Network bytes by resource type:**
| Type | Count | Bytes |
| --- | --- | --- |
| image | 6 | 548.3 KB |
| document | 1 | 45.6 KB |
| font | 3 | 32.5 KB |
| stylesheet | 2 | 27.7 KB |
| script | 2 | 10.5 KB |
| other | 1 | 4.5 KB |

**Slowest requests (top 5):**
- https://lootsa.ee/wp-content/themes/lootsa-arikvartal/inc/theme/fonts/Raleway-Variable.woff2 (font) — 30 ms, 0 B
- https://lootsa.ee/ (document) — 22 ms, 45.6 KB
- https://lootsa.ee/wp-content/themes/lootsa-arikvartal/inc/theme/fonts/ClashDisplay-Regular.woff2 (font) — 20 ms, 16.2 KB
- https://lootsa.ee/wp-content/themes/lootsa-arikvartal/inc/theme/fonts/ClashDisplay-Medium.woff2 (font) — 20 ms, 16.3 KB
- https://lootsa.ee/wp-content/themes/lootsa-arikvartal/inc/theme/js/core.e77acb129c76c92a.js (script) — 18 ms, 2.6 KB

### Manual checks
- Console output during user interaction (load-only capture).
- Behavior on slow networks and constrained devices.
- WebGL / canvas FPS profiling via DevTools Layers panel.
- Service worker / cache behavior on repeat visits.

## HTML Inventory
_Captured in 1924 ms._

**Document:**
- Lang: en
- Title: Lõõtsa Ärikvartal
- Canonical: https://lootsa.ee/
- Viewport: width=device-width, initial-scale=1
- Charset: UTF-8
- HTML bytes: 288741

**Meta tags:**
- Description: not set
- Robots: max-image-preview:large
- Theme color: #ffffff
- Open Graph tags: 0 (none)
- Twitter tags: 0
- hreflang:
  - en → https://lootsa.ee
- JSON-LD: none

**Heading outline:**
- Counts: h1 ×1, h2 ×4, h3 ×12, h4 ×8, h5 ×0, h6 ×0
- Sequence (first 20):
  - h1: Lõõtsa ärikvartal
                                                    Aadress, m
  - h2: Miks valida
                            Lõõtsa ärikvartal?
  - h3: Roheline energia
  - h3: Parim sisekliima
  - h3: Turvaline keskkond
  - h3: Mugav ligipääs ja parkimine
  - h3: Elav ärikogukond
  - h2: Hooned ja vabad äripinnad
  - h3: Lõõtsa 4
  - h4: 1. korrus
  - h4: Sellel korrusel vabu pindu hetkel pole
  - h3: Lõõtsa 5
  - h4: 2. korrus
  - h4: Sellel korrusel vabu pindu hetkel pole
  - h3: Lõõtsa 6
  - h4: 1. korrus
  - h4: 2. korrus
  - h4: 3. korrus
  - h4: Sellel korrusel vabu pindu hetkel pole
  - h2: Korduma kippuvad
                            küsimused

**Landmarks:**
- nav: present
- main: present
- header: present
- footer: present
- Skip-to-content link: **missing**

**Scripts:** 34 total — 0 defer, 1 async, 1 render-blocking. Speculation rules: yes.

External scripts (first 15):
- https://lootsa.ee/wp-content/themes/lootsa-arikvartal/inc/theme/js/core.e77acb129c76c92a.js
- https://lootsa.ee/wp-content/plugins/wp-rocket/assets/js/wpr-beacon.min.js (async)

**Stylesheets:** 2 external, 4 inline (14.2 KB)

**Images:** 43 total — **0 without alt**, **7 without width/height**, 0 without loading="lazy"

Image inventory (first 15):
| src | alt | w×h | loading | srcset |
| --- | --- | --- | --- | --- |
| lootsa.ee/wp-content/uploads/2026/08/lootsa_hero-320x180.jpg | _(empty)_ | 320×180 | lazy | ✓ |
| //lootsa.ee/wp-content/uploads/2026/07/galerii-1-360x240.jpg | Lõõtsa ärikvartali hoone välisvaade | 360×240 | lazy | ✓ |
| //lootsa.ee/wp-content/uploads/2026/07/galerii-2-360x240.jpg | Lõõtsa ärikvartali klaasfassaad | 360×240 | lazy | ✓ |
| otsa.ee/wp-content/uploads/2026/07/galerii-brand-360x240.jpg | Lõõtsa ärikvartali ärihoone | 360×240 | lazy | ✓ |
| s://lootsa.ee/wp-content/uploads/2026/08/23a0249-360x240.jpg | _(empty)_ | 360×240 | lazy | ✓ |
| s://lootsa.ee/wp-content/uploads/2026/08/23a0238-360x240.jpg | _(empty)_ | 360×240 | lazy | ✓ |
| ent/uploads/2026/08/lootsa-arikvartal-gallerii-1-360x203.jpg | _(empty)_ | 360×203 | lazy | ✓ |
| ent/uploads/2026/08/lootsa-arikvartal-gallerii-2-360x203.jpg | _(empty)_ | 360×203 | lazy | ✓ |
| ent/uploads/2026/08/lootsa-arikvartal-gallerii-3-360x203.jpg | _(empty)_ | 360×203 | lazy | ✓ |
| ent/uploads/2026/08/lootsa-arikvartal-gallerii-4-360x203.jpg | _(empty)_ | 360×203 | lazy | ✓ |
| ent/uploads/2026/08/lootsa-arikvartal-gallerii-5-360x203.jpg | _(empty)_ | 360×203 | lazy | ✓ |
| ent/uploads/2026/08/lootsa-arikvartal-gallerii-6-360x203.jpg | _(empty)_ | 360×203 | lazy | ✓ |
| ent/uploads/2026/08/lootsa-arikvartal-gallerii-7-360x203.jpg | _(empty)_ | 360×203 | lazy | ✓ |
| ent/uploads/2026/08/lootsa-arikvartal-gallerii-8-360x203.jpg | _(empty)_ | 360×203 | lazy | ✓ |
| ent/uploads/2026/08/lootsa-arikvartal-gallerii-9-360x203.jpg | _(empty)_ | 360×203 | lazy | ✓ |

**Links:** 71 anchors — 5 external, 1 preconnect, 0 preload.

Vague repeated link text:
- "ava korruseplaan suurelt" ×7
- "tutvu pindadega" ×3
- "anna mulle teada" ×3
- "küsi pakkumist" ×3
- "lõõtsa 4" ×2
- "lõõtsa 6" ×2
- "lõõtsa 5" ×2
- "lootsa@giga.ee" ×2

**Forms:**
Form 1:
- email — labeled
- tel — labeled
- text — labeled
- textarea — labeled
- hidden — **no label**
- hidden — **no label**
- hidden — **no label**
- hidden — **no label**
- hidden — **no label**
- hidden — **no label**
- hidden — **no label**
- hidden — **no label**
- hidden — **no label**
- hidden — **no label**
- hidden — **no label**
- hidden — **no label**

### Priority fixes
1. **Missing skip-to-content link** (medium) — No anchor link with "skip" / "otse sisu" text found
2. **7 images without explicit width/height** (medium) — Missing dimensions can cause layout shifts (CLS)
3. **Vague link text repeated** (medium) — "tutvu pindadega" ×3

### Manual checks
- Visual rendering of detected mojibake (browser may auto-correct for display).
- Whether decorative images correctly use empty `alt=""` (vs. content images missing it).
- Whether headings reflect actual document hierarchy semantically.
- Whether vague link text is disambiguated by `aria-label` or surrounding context.

## Optimized-Web Checklist
_Captured in 0 ms._

**Summary:** 5 pass · 0 warn · 1 fail · 1 n/a

**Checklist:**
| Item | Status | Detail |
| --- | --- | --- |
| Page caching plugin / CDN active | ✓ pass | Caching plugin detected (WP Rocket) |
| Images lazy-loaded | ✓ pass | All non-hero raster images use loading="lazy". |
| 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 <img> (not a CSS background-image) | – n/a | No CSS background-images detected on raster-image-eligible elements. |
| Responsive images (srcset / <picture>) | ✓ pass | 36/43 raster images use srcset or <picture> (84%). |
| Reasonable number of image sizes | ✓ pass | 33 distinct srcset widths. |
| JS scripts not blocking in <head> | ✓ pass | No render-blocking scripts in <head>. |

**Evidence:**
- Page caching plugin / CDN active:
  - `HTML markers: WP Rocket`
  - `generator: WP Rocket 3.23.2.1`
- Hero image eagerly loaded:
  - `hero: https://lootsa.ee/wp-content/uploads/2026/08/lootsa_hero-320x180.jpg`
  - `loading: lazy`
  - `fetchpriority: (not set)`
- Responsive images (srcset / <picture>):
  - `…a.ee/wp-content/themes/lootsa-arikvartal/inc/theme/img/lootsa4-plaan.jpg?v=59`
  - `…ee/wp-content/themes/lootsa-arikvartal/inc/theme/img/lootsa5-korrus1.jpg?v=59`
  - `…ee/wp-content/themes/lootsa-arikvartal/inc/theme/img/lootsa5-korrus2.jpg?v=59`
  - `…ee/wp-content/themes/lootsa-arikvartal/inc/theme/img/lootsa5-korrus3.jpg?v=59`
  - `…ee/wp-content/themes/lootsa-arikvartal/inc/theme/img/lootsa6-korrus1.jpg?v=59`
- Reasonable number of image sizes:
  - `widths: 233, 276, 278, 280, 300, 320, 360, 420, 465, 498, 533, 551, 555, 560, 640, 720, 768, 840, 841, 996, 1003, 1024, 1066, 1080, 1360, 1536, 1600, 1920, 2048, 2161, 2162, 2560, 3200`

### Priority fixes
1. **Hero image eagerly loaded** (high) — 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".

### Manual checks
- Cart / checkout / logged-in pages must bypass the page cache or load dynamic regions via AJAX.
- Verify the cache is warmed for the canonical URL on initial deploy (first visitor should not pay the cold-start cost).
- Inspect "hero" image visually — heuristic above picks the first/largest <img>, which may not match the actual LCP element on JS-heavy pages.
- Confirm scripts marked as defer/async actually tolerate deferred execution (some legacy snippets break when reordered).