20260626T125823Z-ce59
- Audited URL
- https://play.ee/
- Timestamp
- 2026-06-26T13:05:25.355Z
- Kind
- single
- Pages
- 1
Weighted audit summary
Mobile performance is excellent at 94, but security configuration is critically weak with a 20/100 header grade and missing HTTP-to-HTTPS redirect. W3C validation reports 7 errors including malformed noscript tags, and accessibility has 2 moderate violations regarding landmarks and link text. The site is a web development agency with no auth or payment flows, lowering CSP priority but not baseline header requirements. Overall quality is dragged down by security and structural HTML issues despite strong Core Web Vitals.
Audit Report: Perfectly formed web development team - gotoAndPlay
Website: https://play.ee/
Date: 2026-06-26
Overall Score: 76 / 100
Status: 🟡 Needs Improvement
Confidence: high
Audit Coverage: 100% — all sources returned data
Summary
Mobile performance is excellent at 94, but security configuration is critically weak with a 20/100 header grade and missing HTTP-to-HTTPS redirect. W3C validation reports 7 errors including malformed noscript tags, and accessibility has 2 moderate violations regarding landmarks and link text. The site is a web development agency with no auth or payment flows, lowering CSP priority but not baseline header requirements. Overall quality is dragged down by security and structural HTML issues despite strong Core Web Vitals.
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.52 s / 598 ms | 0.000 / 0.008 |
Optimization Checklist
2 of 2 passing — 2 pass · 0 warn · 0 fail · 5 n/a
| Item | Status | Detail |
|---|---|---|
| Page caching plugin / CDN active | Pass | Caching plugin detected (WP Rocket) |
| Images lazy-loaded | N/A | No raster <img> elements found (39 SVGs, 13 placeholders excluded). |
| Hero image eagerly loaded | N/A | No raster <img> elements found (39 SVGs, 13 placeholders excluded). |
| 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>) | N/A | Only 0 raster images on the page (39 SVGs, 13 placeholders excluded) — 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 <head> | Pass | No render-blocking scripts in <head>. |
Fixes
Priority 1: Critical
Immediate action — impacts user experience, search rankings, or site safety.
1A. Enforce HTTPS Redirect
- Impact: Transport security, downgrade attacks
- Problem: http://play.ee/ does not redirect to HTTPS, allowing unencrypted connections despite HTTPS being available.
- Solution:
Configure the web server (Apache/Nginx) to return a 301 redirect for all HTTP requests to HTTPS:
RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Priority 2: Important
Essential for compliance, user reach, and search visibility.
2A. Add HSTS and X-Content-Type-Options
- Impact: Security Headers grade, MIME sniffing protection
- Problem: Security Headers grade is 20/100; HSTS and X-Content-Type-Options are missing.
- Solution:
Add these headers to the server response:
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" Header always set X-Content-Type-Options "nosniff"
2B. Fix W3C Validation Errors
- Impact: HTML structure, rendering consistency
- Problem: 7 validation errors found, including 'Bad start tag in iframe in noscript in head' and stray end tags.
- Solution:
Move the Google Tag Manager
noscriptiframe outside the<head>section. It must be placed immediately after the opening<body>tag:<body> <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-K3P64XMJ" ...></iframe></noscript> <!-- rest of body --> </body>
2C. Improve Accessibility Landmarks and Links
- Impact: Screen reader navigation, WCAG 2.4.1
- Problem: Missing
mainlandmark, no skip-to-content link, and 9 vague 'read more' links. - Solution:
- Add
<main id="main-content">around primary content. - Add a skip link at the top:
<a href="#main-content" class="skip-link">Skip to content</a>. - Disambiguate link text: change 'read more' to 'read more about [topic]'.
- Add
Priority 3: Best Practice
Recommended for long-term maintainability.
3A. Add Image Dimensions and Lazy Loading
- Impact: CLS prevention, bandwidth usage
- Problem: 52 images lack explicit width/height attributes and loading="lazy".
- Solution:
Add
widthandheightattributes to all<img>tags to reserve space. Addloading="lazy"to images below the fold:<img src="image.svg" alt="..." width="300" height="200" loading="lazy">
▸Raw Markdown sent to the LLM
# Audit — https://play.ee/
Run: 2026-06-26T12:58:23.877Z
## 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: no
- E-commerce: no
## PageSpeed Insights
_Captured in 17508 ms (mobile + desktop in parallel)._
**Lighthouse scores (mobile vs desktop; worse value bolded):**
| Category | Mobile | Desktop |
| --- | --- | --- |
| Performance | **94** | 100 |
| Accessibility | 100 | 100 |
| Best Practices | 100 | 100 |
| SEO | 92 | 92 |
**Core Web Vitals — lab (Lighthouse) / field (CrUX p75); worse lab value bolded:**
| Metric | Mobile | Desktop |
| --- | --- | --- |
| LCP | **2.5 s** | 0.6 s |
| CLS | 0.000 | **0.008** |
| TBT | 0 ms | 0 ms |
| FCP | **1.98 s** | 485 ms |
| Speed Index | **4.10 s** | 485 ms |
| TTFB | **43 ms** | 10 ms |
### Priority fixes
1. **largest-contentful-paint** (low) — 2.5 s
2. **speed-index** (low) — 4.1 s
3. **first-contentful-paint** (low) — 2.0 s
4. **network-dependency-tree-insight** (high)
5. **render-blocking-insight** (high) — Est savings of 1,320 ms
### Findings (mobile)
#### Unused JavaScript
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/jquery.bfe1bb19d13b3c17b682.min.js — 23 KB wasted
#### DOM size
- Total nodes: 0
#### Failing modeled audits
- SEO: `tapTargets`
- SEO: `structuredData`
#### All failing PSI audits (sorted by weight × failure margin)
- `largest-contentful-paint` (performance, score 0.89, weight 25) — Largest Contentful Paint — 2.5 s
- `speed-index` (performance, score 0.79, weight 10) — Speed Index — 4.1 s
- `first-contentful-paint` (performance, score 0.85, weight 10) — First Contentful Paint — 2.0 s
- `network-dependency-tree-insight` (performance, score 0.00, weight 0) — Network dependency tree
- `link-text` (seo, score 0.00, weight 1) — Links do not have descriptive text — 9 links found
### 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 111 ms._
**Transport:**
- Final URL: https://play.ee/
- Status: 200
- Redirected: false
- HTTPS redirect: ✗ http://play.ee/ does not redirect to HTTPS (target: none)
**Caching:**
- cache-control: `max-age=0`
- etag: n/a
- last-modified: Tue, 19 May 2026 08:45:53 GMT
- expires: Fri, 26 Jun 2026 12:58:23 GMT
- pragma: n/a
- vary: Accept-Encoding
**Compression:**
- content-encoding: gzip
- content-length: 35692
- Decoded body: 220.6 KB
- Compression ratio: 0.158
### Priority fixes
1. **HTTP does not redirect to HTTPS** (high) — http://play.ee/ does not redirect to HTTPS
2. **strict-transport-security missing** (high) — Add HSTS with max-age >= 1 year, includeSubDomains, and preload
3. **content-security-policy weak** (high) — missing default-src; missing object-src 'none'; only frame-ancestors set — no script/resource restrictions
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
### Findings
#### Tracked headers
- **strict-transport-security** (missing, high)
- **content-security-policy** (weak, high) `frame-ancestors 'self';` — missing default-src; missing object-src 'none'; only frame-ancestors set — no script/resource restrictions
- **x-frame-options** (present, medium) `SAMEORIGIN`
- **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`
- X-Powered-By: `PHP/8.3.31`
#### All response headers
```
accept-ranges: none
cache-control: max-age=0
connection: Upgrade, Keep-Alive
content-encoding: gzip
content-length: 35692
content-security-policy: frame-ancestors 'self';
content-type: text/html; charset=UTF-8
date: Fri, 26 Jun 2026 12:58:23 GMT
expires: Fri, 26 Jun 2026 12:58:23 GMT
keep-alive: timeout=5, max=100
last-modified: Tue, 19 May 2026 08:45:53 GMT
server: Apache
upgrade: h2,h2c
vary: Accept-Encoding
x-frame-options: SAMEORIGIN
x-powered-by: PHP/8.3.31
```
### 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 853 ms._
**Scoring:** 7 errors · 0 warnings · 26 cosmetic (suppressed)
> **Validator truncated at line 100** — the Nu validator stopped after hitting its internal error budget; score against the errors above, NOT as a fatal parse failure: Cannot recover after last error. Any further errors will be ignored.
### Priority fixes
1. **Parser recovery at line 100** (high) — Cannot recover after last error. Any further errors will be ignored.
2. **Bad start tag in “iframe” in “noscript” in “head”.** (medium) — x1, first at line 97
3. **Stray end tag “noscript”.** (medium) — x1, first at line 97
4. **Attribute “name” not allowed on element “meta” at this point.** (medium) — x1, first at line 99
5. **Element “meta” is missing one or more of the following attributes: “itemprop”, “property”.** (medium) — x1, first at line 99
### Issue groups
- (×1) [error] Bad start tag in “iframe” in “noscript” in “head”. — first at line 97 `<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-K3P64XMJ"`
- (×1) [error] Stray end tag “noscript”. — first at line 97 `></iframe></noscript><!-- E`
- (×1) [error] Attribute “name” not allowed on element “meta” at this point. — first at line 99 `<meta name="generator" content="WP Rocket 3.21.3" data-wpr-features="wpr_delay_j`
- (×1) [error] Element “meta” is missing one or more of the following attributes: “itemprop”, “property”. — first at line 99 `<meta name="generator" content="WP Rocket 3.21.3" data-wpr-features="wpr_delay_j`
- (×1) [error] Stray end tag “head”. — first at line 99 `esktop" /></head>
<body`
- (×1) [error] Start tag “body” seen but an element of the same type was already open. — first at line 100 `/></head>
<body class="home wp-singular page-template page-template-template-dyn`
- (×1) [error] Cannot recover after last error. Any further errors will be ignored. — first at line 100 `/></head>
<body class="home wp-singular page-template page-template-template-dyn`
### 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 1941 ms._
**Scoring:** 2 violations · 32 passes · critical 0 · serious 0 · moderate 2 · minor 0
### Priority fixes
1. **landmark-unique** (medium) — Landmarks should have a unique role or role/label/title (i.e. accessible name) combination
2. **region** (medium) — All page content should be contained by landmarks
### Findings
#### `landmark-unique` (moderate)
[Landmarks should have a unique role or role/label/title (i.e. accessible name) combination](https://dequeuniversity.com/rules/axe/4.11/landmark-unique?application=playwright)
- `.header__nav`
#### `region` (moderate)
[All page content should be contained by landmarks](https://dequeuniversity.com/rules/axe/4.11/region?application=playwright)
- `.home-hero__main`
- `.home-hero__bottom`
- `canvas`
- `.keywords__mouse`
- `.keywords__intro`
- … and 31 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) — 37 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 1956 ms._
**Capture summary:** 1 console events · 0 mixed-content requests · 13 network requests · 178.3 KB total
**Network bytes by resource type:**
| Type | Count | Bytes |
| --- | --- | --- |
| font | 3 | 57.6 KB |
| script | 4 | 45.6 KB |
| document | 1 | 34.9 KB |
| stylesheet | 2 | 34.2 KB |
| other | 1 | 5.5 KB |
| image | 1 | 576 B |
| xhr | 1 | 0 B |
**Third-party origins (by bytes):**
- https://cdn.jsdelivr.net — 2 requests, 13.2 KB
- https://fast.fonts.net — 2 requests, 0 B
**Slowest requests (top 5):**
- https://fast.fonts.net/t/1.css?apiType=css&projectid=d924b670-8ecc-46fd-9fff-80fd9989d037 (stylesheet) — 55 ms, 0 B
- https://play.ee/ (document) — 35 ms, 34.9 KB
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/jquery.bfe1bb19d13b3c17b682.min.js (script) — 35 ms, 31.5 KB
- https://cdn.jsdelivr.net/gh/orestbida/cookieconsent@3.0.1/dist/cookieconsent.umd.js (script) — 35 ms, 10.1 KB
- https://cdn.jsdelivr.net/gh/orestbida/iframemanager@1.3.0/dist/iframemanager.js (script) — 35 ms, 3.0 KB
### Findings
#### Console events
- [warning] Couldn't load preload assets:
### 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 1955 ms._
**Document:**
- Lang: en
- Title: Perfectly formed web development team - gotoAndPlay
- Canonical: https://play.ee/
- Viewport: width=device-width, initial-scale=1
- Charset: UTF-8
- HTML bytes: 221760
**Meta tags:**
- Description: Small, agile web development team working on big ideas in close collaboration with our clients. Result driven from day one!
- Robots: follow, index, max-snippet:-1, max-video-preview:-1, max-image-preview:large
- Theme color: #ffffff
- Open Graph tags: 7 (og:locale, og:type, og:title, og:description, og:url, og:site_name, og:updated_time)
- Twitter tags: 3
- hreflang:
- en → http://play.ee/
- et → http://play.ee/et/
- x-default → http://play.ee/
- JSON-LD: 1 blocks (1 valid) — types: Unknown
**Heading outline:**
- Counts: h1 ×1, h2 ×6, h3 ×5, h4 ×0, h5 ×0, h6 ×0
- Sequence (first 20):
- h1: we create memorable experiences with
web technologi
- h2: Your result
- h2: we offer
more than expected
- h2: Üks
- h2: meet the team of
uncommon talent
- h2: proof to our approach are
happy clients
- h3: Deliverables with high quality standards
- h3: Working with gotoAndPlay is a great experience
- h3: Speed, attitude, skills!
- h3: Hardworking, fun & ready to adopt new technologies
- h3: The sky is the limit
- h2: ready when you are
<span style="unicode-bidi:bidi-overr
**Landmarks:**
- nav: present
- main: **missing**
- header: present
- footer: present
- Skip-to-content link: **missing**
**Scripts:** 24 total — 3 defer, 0 async, 1 render-blocking. Speculation rules: yes.
External scripts (first 15):
- https://cdn.jsdelivr.net/gh/orestbida/iframemanager@1.3.0/dist/iframemanager.js (defer)
- https://cdn.jsdelivr.net/gh/orestbida/cookieconsent@3.0.1/dist/cookieconsent.umd.js (defer)
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/runtime.30d3b226dcf211e512b1.min.js
- https://play.ee/wp-content/themes/gotoandplay/inc/theme/js/jquery.bfe1bb19d13b3c17b682.min.js (defer)
**Stylesheets:** 1 external, 3 inline (9.1 KB)
**Images:** 52 total — **0 without alt**, **52 without width/height**, 52 without loading="lazy"
Image inventory (first 15):
| src | alt | w×h | loading | srcset |
| --- | --- | --- | --- | --- |
| ee/wp-content/themes/gotoandplay/inc/theme/img/landscape.svg | Please turn your device sideways | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
| %2Fsvg%22%20viewBox%3D%220%200%20360%20420%22%3E%3C%2Fsvg%3E | _(empty)_ | _n/a_ | _n/a_ | ✗ |
**Links:** 45 anchors — 33 external, 1 preconnect, 0 preload.
Vague repeated link text:
- "read more" ×9
- "view our instagram feed" ×3
- "visit our facebook page" ×3
- "visit our linkedin page" ×3
- "eng" ×3
- "est" ×3
- "styleguide" ×2
- "privacy policy" ×2
**Forms:**
Form 1:
- text — labeled
### Priority fixes
1. **Missing skip-to-content link** (medium) — No anchor link with "skip" / "otse sisu" text found
2. **52 images without explicit width/height** (medium) — Missing dimensions can cause layout shifts (CLS)
3. **Vague link text repeated** (medium) — "read more" ×9
### 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:** 2 pass · 0 warn · 0 fail · 5 n/a
**Checklist:**
| Item | Status | Detail |
| --- | --- | --- |
| Page caching plugin / CDN active | ✓ pass | Caching plugin detected (WP Rocket) |
| Images lazy-loaded | – n/a | No raster <img> elements found (39 SVGs, 13 placeholders excluded). |
| Hero image eagerly loaded | – n/a | No raster <img> elements found (39 SVGs, 13 placeholders excluded). |
| 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>) | – n/a | Only 0 raster images on the page (39 SVGs, 13 placeholders excluded) — 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 <head> | ✓ pass | No render-blocking scripts in <head>. |
**Evidence:**
- Page caching plugin / CDN active:
- `HTML markers: WP Rocket`
- `generator: WP Rocket 3.21.3`
### 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).