{"id":13514,"date":"2026-09-02T09:48:21","date_gmt":"2026-09-02T07:48:21","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/toolbox\/wordpress-site-health-analyzer\/"},"modified":"2026-09-02T09:48:21","modified_gmt":"2026-09-02T07:48:21","slug":"wordpress-site-health-analyzer","status":"publish","type":"page","link":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/wordpress-site-health-analyzer\/","title":{"rendered":"WordPress Site Health Analyzer"},"content":{"rendered":"<div class=\"gtm-analyser-container\" style=\"background: var(--bg-panel, #1e1e24); padding: 25px; border-radius: 8px; border: 1px solid var(--border, #2a2a35);\">\n<p style=\"color: var(--text-secondary, #a0a0b0); margin-bottom: 20px;\">One address is enough. The server fetches the start page, picks up to three inner pages (a product, a category, a post) and runs a handful of probes: robots.txt, xmlrpc.php, the REST user list, ?author=1, readme.html, the upload directory, the http redirect and one CSS and one JS file. From that it derives what a WordPress or WooCommerce site could do better, scored and sorted by weight. The report is stored for 24 hours; after changes to the site, the button below the report runs it again and shows the difference.<\/p>\n<div style=\"margin-bottom: 14px;\">\n        <label for=\"wh-url\" style=\"color: var(--text-secondary, #a0a0b0); display: block; font-size: 0.85rem; margin-bottom: 5px;\">Address of the WordPress site<\/label><br \/>\n        <input id=\"wh-url\" type=\"text\" value=\"https:\/\/example.com\/\" class=\"form-control\" style=\"width: 100%; padding: 10px; background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); color: var(--text-primary, #e8e8ee); border-radius: 6px; box-sizing: border-box; font-family: monospace;\">\n    <\/div>\n<p style=\"color: var(--text-secondary, #a0a0b0); font-size: 0.82rem; margin-bottom: 16px;\">Up to fourteen requests go from this server to the address entered, with a plain GET and no cookies. Requests to private networks, loopback and link-local addresses are refused, including through redirects. The query is protected by reCAPTCHA v3; the calling IP address and the target are stored for one hour to limit the rate (six fresh runs per hour). The report itself, containing only public facts about the site, is kept for 24 hours under a hash of the address.<\/p>\n<p>    <button id=\"wh-btn\" class=\"button\" style=\"background: var(--accent, #7ee787); color: var(--on-accent, #0b1114); border: none; padding: 12px 24px; border-radius: 6px; font-weight: 700; cursor: pointer;\">Analyse the site<\/button><\/p>\n<div id=\"wh-ausgabe\" style=\"margin-top: 22px;\"><\/div>\n<p style=\"color: var(--text-secondary, #a0a0b0); font-size: 0.8rem; margin: 24px 0 0;\">Limit worth knowing: this reads the delivered HTML and headers and executes nothing. Images that a script inserts later, tags that load after consent and everything the browser measures at runtime (Largest Contentful Paint, layout shift) stay invisible. The report says where to look, not how fast the page feels.<\/p>\n<\/div>\n<p><script>\n(function () {\n    'use strict';<\/p>\n<p>    const T = {\"einleitung\":\"One address is enough. The server fetches the start page, picks up to three inner pages (a product, a category, a post) and runs a handful of probes: robots.txt, xmlrpc.php, the REST user list, ?author=1, readme.html, the upload directory, the http redirect and one CSS and one JS file. From that it derives what a WordPress or WooCommerce site could do better, scored and sorted by weight. The report is stored for 24 hours; after changes to the site, the button below the report runs it again and shows the difference.\",\"label_url\":\"Address of the WordPress site\",\"datenschutz\":\"Up to fourteen requests go from this server to the address entered, with a plain GET and no cookies. Requests to private networks, loopback and link-local addresses are refused, including through redirects. The query is protected by reCAPTCHA v3; the calling IP address and the target are stored for one hour to limit the rate (six fresh runs per hour). The report itself, containing only public facts about the site, is kept for 24 hours under a hash of the address.\",\"knopf\":\"Analyse the site\",\"knopf_erneut\":\"Changes made, check again\",\"laeuft\":\"Fetching the start page, inner pages and probes...\",\"laeuft_lang\":\"Still running. A slow site takes up to a minute, because every page is waited for.\",\"grenze\":\"Limit worth knowing: this reads the delivered HTML and headers and executes nothing. Images that a script inserts later, tags that load after consent and everything the browser measures at runtime (Largest Contentful Paint, layout shift) stay invisible. The report says where to look, not how fast the page feels.\",\"h_uebersicht\":\"Overview\",\"zeile_endziel\":\"Landed at\",\"zeile_wordpress\":\"WordPress\",\"zeile_woocommerce\":\"WooCommerce\",\"zeile_theme\":\"Theme\",\"zeile_plugins\":\"Plugins visible in the HTML\",\"zeile_server\":\"Server\",\"zeile_http\":\"Protocol\",\"zeile_seiten\":\"Pages checked\",\"zeile_limit\":\"Fresh runs left this hour\",\"punkte_label\":\"of 100\",\"aus_cache_hinweis\":\"This report is {alter} old and comes from the store. The button below runs a fresh check.\",\"frisch_hinweis\":\"Fresh report, produced in {sekunden} s.\",\"vorher_hinweis\":\"Previous run: {vorher} points. Now: {jetzt} ({diff}).\",\"budget_hinweis\":\"{n} inner page(s) were skipped because the time budget ran out. The site answers slowly; the report is based on fewer pages than usual.\",\"bereich_leistung\":\"Delivery\",\"bereich_assets\":\"Scripts and styles\",\"bereich_bilder\":\"Images\",\"bereich_dokument\":\"Document\",\"bereich_woocommerce\":\"WooCommerce\",\"bereich_hygiene\":\"Hygiene\",\"h_befunde\":\"Findings\",\"stufe_hoch\":\"High\",\"stufe_mittel\":\"Medium\",\"stufe_niedrig\":\"Low\",\"stufe_info\":\"Information\",\"stufe_gut\":\"In order\",\"keine_befunde\":\"Nothing to report.\",\"h_seiten\":\"Pages\",\"spalte_seite\":\"Page\",\"spalte_typ\":\"Type\",\"spalte_ttfb\":\"Time to first byte\",\"spalte_groesse\":\"HTML\",\"spalte_skripte\":\"Scripts (blocking)\",\"spalte_bilder\":\"Images\",\"spalte_cache\":\"Cache\",\"typ_start\":\"start page\",\"typ_seite\":\"page\",\"typ_beitrag\":\"post\",\"typ_produkt\":\"product\",\"typ_shop\":\"shop \\\/ category\",\"typ_warenkorb\":\"cart\",\"typ_kasse\":\"checkout\",\"typ_konto\":\"account\",\"typ_archiv\":\"archive\",\"h_sonden\":\"Probes\",\"sonde_http\":\"http:\\\/\\\/ redirect\",\"sonde_robots\":\"robots.txt\",\"sonde_xmlrpc\":\"xmlrpc.php\",\"sonde_rest_users\":\"REST user list\",\"sonde_author\":\"?author=1\",\"sonde_readme\":\"readme.html\",\"sonde_uploads\":\"Upload directory\",\"sonde_css\":\"One CSS file\",\"sonde_js\":\"One JS file\",\"sonde_budget\":\"skipped (time budget)\",\"sonde_fehler\":\"not reachable\",\"einheit_minuten\":\"min\",\"einheit_stunden\":\"h\",\"ja\":\"yes\",\"nein\":\"no\",\"wert_keine\":\"none visible\",\"fehler_kein_token\":\"The check could not be started because reCAPTCHA did not load.\",\"fehler_captcha\":\"reCAPTCHA classified the request as automated. Reloading the page normally helps.\",\"fehler_zu_viele\":\"The limit of {limit} fresh runs per hour for this address has been reached. Stored reports are still shown.\",\"fehler_adresse\":\"That address cannot be used.\",\"fehler_zaehler\":\"The rate counter is unavailable, so nothing was fetched.\",\"fehler_pruefdienst\":\"The reCAPTCHA service could not be reached.\",\"fehler_aufbau\":\"The service is not configured correctly. The fault is on this side.\",\"fehler_eingabe\":\"The request could not be read.\",\"fehler_methode\":\"Wrong request method.\",\"fehler_netz\":\"The service could not be reached.\",\"fehler_antwort\":\"The answer could not be read.\",\"fehler_abruf\":\"The address could not be fetched.\",\"fehler_status\":\"The start page answered with status {status} instead of 200. Nothing was analysed.\",\"fehler_kein_html\":\"The address returned something other than HTML.\",\"fehler_unbekannt\":\"Something went wrong that has no message of its own.\",\"grund_leer\":\"Nothing was entered.\",\"grund_zu_lang\":\"The address is too long.\",\"grund_unlesbar\":\"It does not parse as a web address.\",\"grund_schema\":\"Only http and https are fetched.\",\"grund_benutzerinfo\":\"Addresses with credentials in them are refused.\",\"grund_kein_punkt\":\"The host name needs at least one dot.\",\"grund_hostform\":\"The host name has an unusable form.\",\"grund_port\":\"Only ports 80, 443, 8080 and 8443 are fetched.\",\"grund_gesperrter_bereich\":\"That address points into a private or reserved network. Those are never fetched, not even through a redirect.\",\"grund_kein_dns\":\"The host name does not resolve.\",\"grund_zu_viele_spruenge\":\"Too many redirects.\",\"grund_abruf\":\"The server did not answer in time or closed the connection.\",\"befund_wp_nicht_erkannt\":\"No WordPress detected || Neither \\\/wp-content\\\/, \\\/wp-includes\\\/ nor a WordPress generator tag appears in the HTML. The general checks still apply; the WordPress-specific probes are skipped.\",\"befund_wc_erkannt\":\"WooCommerce detected || The shop-specific checks below apply: cart fragments, checkout scripts, block styles and caching of non-cart pages.\",\"befund_ttfb_langsam\":\"Slow server response: {ms} ms median to the first byte (worst {max} ms) || Above 600 ms every page starts late, before a single asset loads. A page cache that serves finished HTML usually brings this below 200 ms; PHP 8.x, an object cache and fewer database queries per page help where a cache cannot be used.\",\"befund_ttfb_maessig\":\"Moderate server response: {ms} ms median to the first byte (worst {max} ms) || Under 300 ms is the target for a cached page. Check whether the cache actually hits on these pages and whether a plugin runs queries on every request.\",\"befund_ttfb_gut\":\"Fast server response: {ms} ms median to the first byte || The server side is not the bottleneck.\",\"befund_kein_seitencache\":\"No page cache detected || None of the checked pages carried a cache header (X-Cache, Age, CF-Cache-Status, X-LiteSpeed-Cache) or the footprint of a caching plugin. Every visit is rendered by PHP. A page cache (LiteSpeed Cache, WP Rocket, WP Super Cache, Cache Enabler, or the host\\u0027s own) is the single largest gain for a blog or shop.\",\"befund_seitencache_teilweise\":\"Page cache ({name}) on {n} of {von} cacheable pages || Some pages bypass the cache. Typical causes: a cookie set on the first visit, a plugin that marks pages as uncacheable, or query parameters that create new cache keys.\",\"befund_seitencache_erkannt\":\"Page cache in use ({name}) || Finished HTML is served without PHP on the checked pages.\",\"befund_html_nicht_komprimiert\":\"HTML is delivered uncompressed || Neither gzip nor Brotli in the response. Enabling compression on the web server (mod_deflate, mod_brotli, gzip in nginx) cuts HTML transfer by 70 to 80 percent without touching WordPress.\",\"befund_html_teils_komprimiert\":\"{n} page(s) delivered uncompressed || Compression is configured for some responses only, often because a cache serves stored files without the encoding rule.\",\"befund_html_komprimiert\":\"HTML is compressed ({art}) || Transfer size is reduced at the server.\",\"befund_http1\":\"Only HTTP\\\/1.1 || The server does not negotiate HTTP\\\/2. With dozens of scripts, styles and images per page, HTTP\\\/2 multiplexing shortens loading noticeably; on Apache it is mod_http2 with Protocols h2, on nginx the http2 flag on the listen line.\",\"befund_http2\":\"HTTP\\\/2 in use || Requests share one connection.\",\"befund_http3\":\"HTTP\\\/3 offered || The server advertises h3 via Alt-Svc; supporting browsers switch to QUIC.\",\"befund_html_no_store\":\"HTML marked as not cacheable ({wert}) || A Cache-Control with no-store or private prevents any CDN or proxy from keeping the page. For anonymous visitors of a blog or shop that is rarely intended.\",\"befund_cookies_erste_antwort\":\"Cookies set on the first anonymous response ({namen}) || Session and test cookies on every page make most page caches skip the response and every visit personal. Typical causes: a PHP session started by a plugin, or WooCommerce session cookies outside cart and checkout.\",\"befund_blockierende_skripte\":\"{n} render-blocking scripts in the head || Scripts without defer or async in the head stop the parser until they are downloaded and executed. Moving them to the footer or adding defer lets the page render first; the list shows the files concerned.\",\"befund_blockierende_skripte_wenige\":\"{n} render-blocking script(s) in the head || Small number, still worth a defer attribute unless the script has to run before the body.\",\"befund_viele_skripte\":\"{n} external scripts on the start page || More than 25 script files usually means several plugins loading their assets on every page. A dequeue rule per page type or an asset-optimisation plugin reduces requests and execution time.\",\"befund_viele_stylesheets\":\"{n} stylesheets || Each stylesheet is a blocking request. Merging what belongs to the theme and dropping plugin styles from pages that do not need them shortens the critical path.\",\"befund_jquery_migrate\":\"jQuery Migrate is loaded || The compatibility shim exists for old plugins only. If nothing in the browser console complains after removing it, it can be dequeued.\",\"befund_wp_emoji\":\"Emoji script is loaded || WordPress adds wp-emoji and a DNS prefetch to s.w.org on every page. Modern browsers render emoji natively; the script can be removed with two remove_action calls.\",\"befund_wp_embed\":\"wp-embed script is loaded || Only needed for embedding other WordPress posts. Removable if the site does not use that feature.\",\"befund_wp_polyfill\":\"wp-polyfill is loaded on the front end || The polyfill exists for old browsers and is usually pulled in by a block or plugin script that is not needed on the front end.\",\"befund_dashicons\":\"Dashicons loaded for visitors || The admin icon font is enqueued on the front end, usually by a plugin. Anonymous visitors do not need it; dequeue it unless the theme uses the icons.\",\"befund_block_library_css\":\"Block library CSS without block content || wp-block-library styles are loaded although no block classes appear in the HTML. Classic themes can dequeue them.\",\"befund_global_styles_gross\":\"Global styles inline CSS of {kb} KB || The theme.json output is placed inline on every page. A large value means many unused presets; trimming theme.json or removing unused variations helps.\",\"befund_inline_css_gross\":\"{kb} KB of inline CSS || Inline styles are repeated on every page and never cached by the browser. Page builders are the usual source; moving repeated rules to a stylesheet helps.\",\"befund_google_fonts_extern\":\"Fonts loaded from fonts.googleapis.com || A third-party connection before text can render, and within the EU a data-protection question. Self-hosted WOFF2 files with font-display: swap are faster and avoid the transfer.\",\"befund_fontawesome_cdn\":\"Font Awesome from a CDN || A full icon font for a handful of icons, from a third-party host. Inline SVG or a subset served from the own domain is smaller.\",\"befund_fremde_hosts\":\"{n} third-party hosts for scripts and styles || Each host costs a DNS lookup and a TLS handshake before the first byte. The list shows them; consolidating or self-hosting removes connections.\",\"befund_kein_preconnect\":\"No preconnect for third-party hosts || A preconnect link for the hosts that are needed early (fonts, tag manager) starts the connection before the browser discovers the resource.\",\"befund_admin_ajax_frontend\":\"admin-ajax.php used on the front end || Every call loads the full admin bootstrap. For public data the REST API is lighter and cacheable.\",\"befund_inline_js_gross\":\"{kb} KB of inline JavaScript || Inline scripts are re-parsed on every page and cannot be cached. Moving them to a file with defer helps.\",\"befund_assets_ohne_cache\":\"Static files without browser caching ({art}) || The checked file carries no usable max-age or Expires. Returning visitors download every script and stylesheet again; a month for versioned assets is the usual setting (mod_expires, or expires in nginx).\",\"befund_assets_kurz_gecacht\":\"Static files cached for {tage} day(s) only ({art}) || Versioned assets can be cached for months; the ?ver parameter changes when the file changes.\",\"befund_assets_gecacht\":\"Static files cached for {tage} days ({art}) || Returning visitors reuse scripts and styles.\",\"befund_assets_nicht_komprimiert\":\"Static files delivered uncompressed ({art}) || Text assets without gzip or Brotli. The same web-server setting that compresses HTML should cover CSS and JavaScript.\",\"befund_bilder_ohne_masse\":\"{n} of {von} images without width and height || Without dimensions the browser cannot reserve space and the layout jumps when the image arrives (Cumulative Layout Shift). WordPress adds the attributes for images inserted through the editor; themes and builders often drop them.\",\"befund_bilder_ohne_lazy\":\"{n} of {von} images below the fold without loading=\\u0022lazy\\u0022 || Images outside the first screen can wait. WordPress sets the attribute by default; a theme or plugin that outputs its own img tags skips it.\",\"befund_bilder_altformat\":\"No modern image formats ({von} images checked) || Neither WebP nor AVIF anywhere. Since WordPress 6.5 uploads can be converted automatically; an image plugin or the host does the same. Savings of 30 to 60 percent per image are typical.\",\"befund_bilder_modern\":\"Modern image formats in use ({n} of {von}) || WebP or AVIF are served for part of the images.\",\"befund_bilder_ohne_srcset\":\"{n} of {von} images without srcset || Without responsive sources every device downloads the same file. WordPress generates sizes for uploads; the theme has to output them.\",\"befund_erstes_bild_lazy\":\"The first image is lazy-loaded || The image above the fold is delayed by the very attribute that should protect it. It should be eager, ideally with fetchpriority=\\u0022high\\u0022.\",\"befund_iframes_ohne_lazy\":\"{n} iframe(s) without loading=\\u0022lazy\\u0022 || Embedded videos and maps load a whole page each. Lazy loading defers them until they scroll into view.\",\"befund_kein_fetchpriority\":\"No fetchpriority on the hero image || Marking the largest visible image with fetchpriority=\\u0022high\\u0022 moves it ahead of scripts and improves Largest Contentful Paint.\",\"befund_html_gross\":\"HTML document of {kb} KB || Large documents usually carry inline CSS, inline SVG or a builder\\u0027s markup. Above 300 KB the parser alone takes noticeable time on phones.\",\"befund_dom_gross\":\"About {n} DOM nodes || More than 2,500 nodes slow down style calculation and layout. Page builders and nested wrappers are the usual source.\",\"befund_viewport_fehlt\":\"No viewport meta tag || Without it phones render the page at desktop width and scale it down. Every theme should set width=device-width.\",\"befund_lang_fehlt\":\"No lang attribute on html || Screen readers and search engines cannot tell the language; WordPress sets it from the site language unless the theme overrides the html tag.\",\"befund_titel_fehlt\":\"No title || The document has no title element.\",\"befund_beschreibung_fehlt\":\"No meta description || Not a ranking factor, but the snippet that search engines show. An SEO plugin fills it per page.\",\"befund_kein_canonical\":\"No canonical link || Without it duplicates (with parameters, with and without trailing slash) compete with each other. Yoast, Rank Math and the core since 6.x add it; something removed it here.\",\"befund_noindex\":\"Page is set to noindex || The start page tells search engines not to index it. Intended on a staging site, a serious mistake on a live one.\",\"befund_kopf_ballast\":\"Head ballast: RSD link, wlwmanifest or shortlink || Leftovers from remote publishing tools. Harmless, but each is a link element and a hint to the platform; remove_action calls take them out.\",\"befund_pingback_offen\":\"Pingback endpoint advertised || The X-Pingback header or link points to xmlrpc.php. Pingbacks are used for spam and amplification; disabling XML-RPC removes both.\",\"befund_wc_fragments_ueberall\":\"Cart fragments loaded on {n} non-cart page(s) || wc-cart-fragments fires an admin-ajax request on every page load to refresh the mini cart, which also bypasses the page cache. Dequeue it outside cart and checkout, or use a theme setting that disables it.\",\"befund_wc_fragments_ok\":\"Cart fragments only where needed || No cart-fragments script on blog and content pages.\",\"befund_wc_checkout_skripte_ueberall\":\"Checkout scripts on {n} page(s) outside the checkout || Checkout and address scripts are heavy and needed on one page only. A conditional dequeue keeps them there.\",\"befund_wc_produktskripte_ueberall\":\"Product page scripts on {n} page(s) that are not products || Gallery, zoom and variation scripts loaded outside product pages.\",\"befund_wc_blocks_css_ueberall\":\"WooCommerce block styles on {n} content page(s) || wc-blocks CSS is loaded on pages without shop blocks. Dequeue it outside shop pages.\",\"befund_wc_layout_css_ueberall\":\"WooCommerce layout styles on {n} blog post(s) || The shop stylesheets are loaded on posts that contain no shop markup.\",\"befund_wc_nicht_gecacht\":\"{n} shop page(s) marked uncacheable || Cache-Control forbids caching on pages that are not cart, checkout or account. Usually a session started too early; check which plugin sets the header.\",\"befund_wc_select2_ueberall\":\"select2 \\\/ selectWoo loaded outside checkout and account || The dropdown library is needed on forms only.\",\"befund_wc_passwortmesser\":\"Password strength meter loaded on the front end || zxcvbn is about 800 KB and belongs to the registration form only.\",\"befund_wc_keine_shopseite_geprueft\":\"No product or category page found among the inner links || The shop-specific checks ran on the pages available. Entering the shop address directly gives a fuller picture.\",\"befund_generator_version\":\"WordPress version {version} in the generator tag || The exact version is public. Not a vulnerability by itself, but it makes an outdated installation easy to find; remove the generator tag and keep the core updated.\",\"befund_generator_meta\":\"Generator meta tag present || The platform is announced in the head. Removable with a one-line filter.\",\"befund_x_powered_by\":\"X-Powered-By header: {wert} || The server announces its stack. Remove it with expose_php = Off and a header rule.\",\"befund_php_alt\":\"PHP {version} in use || Below 8.1 the interpreter is out of security support and markedly slower. WordPress and WooCommerce run on 8.2 and 8.3; the host\\u0027s control panel usually offers the switch.\",\"befund_server_version\":\"Server header with version: {wert} || The exact web-server version is public. ServerTokens Prod on Apache, server_tokens off on nginx.\",\"befund_kein_hsts\":\"No Strict-Transport-Security || After the https redirect, HSTS keeps browsers on https and removes the first insecure request on later visits.\",\"befund_https_redirect_ok\":\"http redirects to https ({status}) || The plain address forwards to the secure one.\",\"befund_kein_https_redirect\":\"http answers with 200 instead of redirecting || The site is reachable unencrypted and search engines may index both. A permanent redirect to https belongs in the web-server configuration.\",\"befund_http_redirect_nicht_https\":\"http redirects, but not to https ({ort}) || The redirect target is another plain address; the chain should end on https.\",\"befund_xmlrpc_offen\":\"xmlrpc.php is enabled || The XML-RPC endpoint accepts requests. It is the preferred route for brute-force and pingback abuse and is needed only by the mobile app and Jetpack. Block it on the web server or disable it with a filter.\",\"befund_xmlrpc_gesperrt\":\"xmlrpc.php is blocked ({status}) || The endpoint refuses requests.\",\"befund_rest_users_offen\":\"User list readable via REST ({n} account(s): {liste}) || \\\/wp-json\\\/wp\\\/v2\\\/users returns the login names of authors to anyone. That is the first step of a password attack; restrict the endpoint to logged-in users.\",\"befund_rest_users_gesperrt\":\"REST user list not public ({status}) || The endpoint does not reveal accounts.\",\"befund_author_enum\":\"?author=1 reveals the login name ({name}) || The author archive redirect exposes the first account. A redirect rule or a plugin setting stops it.\",\"befund_readme_offen\":\"readme.html is public || The file names the WordPress version. Delete it after each update or block it on the web server.\",\"befund_uploads_listing\":\"Upload directory lists its contents || \\\/wp-content\\\/uploads\\\/ shows a directory index. Options -Indexes on Apache or autoindex off on nginx.\",\"befund_robots_fehlt\":\"No robots.txt || WordPress generates one dynamically unless a physical file or a rewrite rule prevents it. A missing file is not an error, but a sitemap line is worth having.\",\"befund_robots_ohne_sitemap\":\"robots.txt without a Sitemap line || Adding Sitemap: with the address of the XML sitemap helps crawlers find every page.\",\"befund_robots_sperrt_assets\":\"robots.txt blocks \\\/wp-content\\\/ or \\\/wp-includes\\\/ || Google renders pages and needs CSS and JavaScript. Blocking those directories degrades how the page is understood.\",\"befund_robots_sperrt_alles\":\"robots.txt blocks everything || Disallow: \\\/ keeps every crawler out. Intended on staging only.\",\"befund_wp_version_gelesen\":\"WordPress {version} || Read from the generator tag or asset version parameters.\"};<\/p>\n<p>    var ENDPUNKT = '\/lw-wphealth.php';\n    var SITEKEY = '6LcrPkEtAAAAAPo1QCOf-IIM2fCL0UfdJz4y2iSY';\n    var STUFEN = ['hoch', 'mittel', 'niedrig', 'info', 'gut'];\n    var BEREICHE = ['leistung', 'assets', 'bilder', 'dokument', 'woocommerce', 'hygiene'];<\/p>\n<p>    \/\/ =========================================================================\n    \/\/ Bewertung - rein\n    \/\/ =========================================================================<\/p>\n<p>    function liste(w) { return Array.isArray(w) ? w : []; }\n    function zahl(w) { return (typeof w === 'number' && isFinite(w)) ? w : null; }<\/p>\n<p>    \/** Platzhalter {x} aus den Befunddaten einsetzen. *\/\n    function text(schluessel, daten) {\n        var t = T[schluessel];\n        if (typeof t !== 'string') { return null; }\n        return t.replace(\/\\{([a-z_]+)\\}\/g, function (m, k) {\n            if (daten && daten[k] !== undefined && daten[k] !== null) {\n                return Array.isArray(daten[k]) ? daten[k].join(', ') : String(daten[k]);\n            }\n            return m;\n        });\n    }<\/p>\n<p>    function bewerten(antwort) {\n        var a = antwort || {};\n        if (a.fehler) {\n            return { fehler: a.fehler, grund: a.grund || null, status: zahl(a.status), limit: zahl(a.limit), kette: liste(a.kette) };\n        }\n        var p = (a.punkte && typeof a.punkte === 'object') ? a.punkte : {};\n        var bereiche = [];\n        BEREICHE.forEach(function (b) {\n            if (p.bereiche && zahl(p.bereiche[b]) !== null) { bereiche.push({ name: b, punkte: p.bereiche[b] }); }\n        });\n        var befunde = liste(a.befunde).map(function (f) {\n            return { key: String(f.key || ''), stufe: STUFEN.indexOf(f.stufe) === -1 ? 'info' : f.stufe,\n                     punkte: zahl(f.punkte) || 0, bereich: f.bereich || '', daten: (f.daten && typeof f.daten === 'object') ? f.daten : {} };\n        });\n        var gruppen = {};\n        STUFEN.forEach(function (s) { gruppen[s] = befunde.filter(function (f) { return f.stufe === s; }); });\n        var gesamt = zahl(p.gesamt);\n        var farbe = gesamt === null ? 'grau' : (gesamt >= 85 ? 'gut' : (gesamt >= 60 ? 'mittel' : 'schlecht'));\n        var vorher = (a.vorher && zahl(a.vorher.punkte) !== null) ? { punkte: a.vorher.punkte, erstellt: a.vorher.erstellt || null } : null;\n        return {\n            fehler: null,\n            url: a.url || '', endziel: a.endziel || a.url || '',\n            wordpress: !!a.wordpress, wpVersion: a.wp_version || null,\n            woocommerce: !!a.woocommerce, wcVersion: a.wc_version || null,\n            theme: a.theme || null, plugins: liste(a.plugins),\n            server: (a.server && typeof a.server === 'object') ? a.server : {},\n            seiten: liste(a.seiten),\n            sonden: (a.sonden && typeof a.sonden === 'object') ? a.sonden : {},\n            gesamt: gesamt, farbe: farbe, bereiche: bereiche,\n            befunde: befunde, gruppen: gruppen,\n            ausCache: !!a.aus_cache, alterS: zahl(a.alter_s) || 0,\n            erstellt: a.erstellt || null, dauer: zahl(a.dauer_ms),\n            limitRest: zahl(a.limit_rest), vorher: vorher,\n            uebersprungen: zahl(a.unterseiten_uebersprungen) || 0\n        };\n    }<\/p>\n<p>    \/\/ =========================================================================\n    \/\/ Abruf\n    \/\/ =========================================================================<\/p>\n<p>    function skriptLaden() {\n        return new Promise(function (auf) {\n            if (window.grecaptcha) { auf(true); return; }\n            var s = document.createElement('script');\n            s.src = 'https:\/\/www.google.com\/recaptcha\/api.js?render=' + SITEKEY;\n            s.onload = function () { auf(true); };\n            s.onerror = function () { auf(false); };\n            document.head.appendChild(s);\n            setTimeout(function () { auf(!!window.grecaptcha); }, 8000);\n        });\n    }\n    \/** grecaptcha.ready abwarten - execute ist bei onload noch nicht da. *\/\n    function tokenHolen() {\n        return skriptLaden().then(function (da) {\n            if (!da || !window.grecaptcha || !window.grecaptcha.ready) { return null; }\n            return new Promise(function (auf) {\n                var fertig = false;\n                function einmal(w) { if (!fertig) { fertig = true; auf(w); } }\n                setTimeout(function () { einmal(null); }, 12000);\n                try {\n                    window.grecaptcha.ready(function () {\n                        if (fertig) { return; }\n                        if (!window.grecaptcha.execute) { einmal(null); return; }\n                        window.grecaptcha.execute(SITEKEY, { action: 'wphealth' })\n                            .then(function (t) { einmal(t || null); }, function () { einmal(null); });\n                    });\n                } catch (e) { einmal(null); }\n            });\n        }, function () { return null; });\n    }\n    function abfragen(url, erneut) {\n        return tokenHolen().then(function (token) {\n            return fetch(ENDPUNKT, {\n                method: 'POST', headers: { 'Content-Type': 'application\/json' },\n                body: JSON.stringify({ url: url, token: token || '', erneut: !!erneut })\n            }).then(function (r) {\n                return r.json().then(function (j) { return j; }, function () { return { fehler: 'antwort' }; });\n            }, function () { return { fehler: 'netz' }; });\n        });\n    }<\/p>\n<p>    window.LW_TEST = window.LW_TEST || {};\n    window.LW_TEST.WH = { bewerten: bewerten, darstellen: null, text: text, ENDPUNKT: ENDPUNKT, STUFEN: STUFEN, BEREICHE: BEREICHE, T: T };<\/p>\n<p>    \/\/ =========================================================================\n    \/\/ Oberflaeche\n    \/\/ =========================================================================<\/p>\n<p>    var btn = document.getElementById('wh-btn');\n    var out = document.getElementById('wh-ausgabe');\n    if (!btn || !out) { return; }<\/p>\n<p>    function el(tag, stil, txt) {\n        var e = document.createElement(tag);\n        if (stil) { e.setAttribute('style', stil); }\n        if (txt !== undefined && txt !== null) { e.textContent = txt; }\n        return e;\n    }\n    function wert(id) { var e = document.getElementById(id); return e ? e.value : ''; }<\/p>\n<p>    var UEBERSCHRIFT = 'font-family: \"Nunito Sans\", sans-serif; font-weight: 700; color: var(--text-primary, #e8e8ee); font-size: 0.95rem; margin: 22px 0 8px;';\n    var ZELLE = 'padding: 5px 12px 5px 0; color: var(--text-secondary, #a0a0b0); font-size: 0.87rem;';\n    var ZELLE_WERT = 'padding: 5px 12px 5px 0; color: var(--text-primary, #e8e8ee); font-size: 0.87rem; font-family: monospace; word-break: break-all;';\n    var KASTEN = 'background: var(--bg-body, #14141a); border: 1px solid var(--border, #2a2a35); border-radius: 8px; padding: 14px 16px; margin: 0 0 10px;';\n    var GUT = ' color: #7ee787;';\n    var WARN = ' color: #ffa94d;';\n    var ROT = ' color: #ff7b72;';\n    var GRAU = ' color: #8a8a99;';\n    var FARBEN = { hoch: '#ff7b72', mittel: '#ffa94d', niedrig: '#e3b341', info: '#8a8a99', gut: '#7ee787' };\n    var PUNKTFARBE = { gut: '#7ee787', mittel: '#ffa94d', schlecht: '#ff7b72', grau: '#8a8a99' };<\/p>\n<p>    function gitter(sp) { return el('div', 'display: grid; grid-template-columns: ' + sp + '; gap: 0 18px; align-items: baseline;'); }\n    function paar(g, n, w, stil) {\n        g.appendChild(el('div', ZELLE, n));\n        g.appendChild(el('div', ZELLE_WERT + (stil || ''), w));\n    }\n    function balken(ziel, beschriftung, punkte, breite) {\n        var z = el('div', 'display: grid; grid-template-columns: 160px 1fr 44px; gap: 10px; align-items: center; margin: 4px 0;');\n        z.appendChild(el('div', ZELLE + ' padding: 0;', beschriftung));\n        var hg = el('div', 'height: 10px; border-radius: 5px; background: var(--border, #2a2a35); overflow: hidden;');\n        var f = punkte >= 85 ? PUNKTFARBE.gut : (punkte >= 60 ? PUNKTFARBE.mittel : PUNKTFARBE.schlecht);\n        hg.appendChild(el('div', 'height: 100%; width: ' + Math.max(2, Math.min(100, punkte)) + '%; background: ' + f + '; border-radius: 5px;'));\n        z.appendChild(hg);\n        z.appendChild(el('div', ZELLE_WERT + ' padding: 0; text-align: right;', String(punkte)));\n        ziel.appendChild(z);\n    }\n    function dauerText(s) {\n        if (s < 3600) { return Math.max(1, Math.round(s \/ 60)) + ' ' + T.einheit_minuten; }\n        return Math.round(s \/ 3600) + ' ' + T.einheit_stunden;\n    }\n\n    function darstellen(b, ziel) {\n        ziel.innerHTML = '';\n        if (b.fehler) {\n            var txt = T['fehler_' + b.fehler] || T.fehler_unbekannt;\n            if (b.grund &#038;&#038; T['grund_' + b.grund]) { txt = txt + ' ' + T['grund_' + b.grund]; }\n            if (b.limit !== null) { txt = txt.replace('{limit}', String(b.limit)); }\n            if (b.status !== null) { txt = txt.replace('{status}', String(b.status)); }\n            ziel.appendChild(el('p', ZELLE + WARN + ' margin: 0;', txt));\n            return;\n        }\n\n        \/\/ --- Kopf: Punkte und Herkunft ---\n        var kopf = el('div', KASTEN + ' display: flex; flex-wrap: wrap; gap: 18px 28px; align-items: center;');\n        var pk = el('div', 'text-align: center; min-width: 110px;');\n        pk.appendChild(el('div', 'font-family: \"Nunito Sans\", sans-serif; font-weight: 800; font-size: 2.6rem; line-height: 1; color: ' + PUNKTFARBE[b.farbe] + ';', b.gesamt === null ? '-' : String(b.gesamt)));\n        pk.appendChild(el('div', ZELLE + ' padding: 4px 0 0; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.5px;', T.punkte_label));\n        kopf.appendChild(pk);\n        var bb = el('div', 'flex: 1 1 320px;');\n        b.bereiche.forEach(function (x) { balken(bb, T['bereich_' + x.name] || x.name, x.punkte); });\n        kopf.appendChild(bb);\n        ziel.appendChild(kopf);\n\n        var hinweise = el('div', 'margin: 0 0 6px;');\n        if (b.ausCache) {\n            hinweise.appendChild(el('p', ZELLE + GRAU + ' margin: 0 0 6px;', text('aus_cache_hinweis', { alter: dauerText(b.alterS) })));\n        } else if (b.dauer !== null) {\n            hinweise.appendChild(el('p', ZELLE + GRAU + ' margin: 0 0 6px;', text('frisch_hinweis', { sekunden: (b.dauer \/ 1000).toFixed(1) })));\n        }\n        if (b.vorher &#038;&#038; b.gesamt !== null) {\n            var diff = b.gesamt - b.vorher.punkte;\n            var stil = diff > 0 ? GUT : (diff < 0 ? ROT : GRAU);\n            hinweise.appendChild(el('p', ZELLE + stil + ' margin: 0 0 6px; font-weight: 700;',\n                text('vorher_hinweis', { vorher: b.vorher.punkte, jetzt: b.gesamt, diff: (diff > 0 ? '+' : '') + diff })));\n        }\n        if (b.uebersprungen > 0) { hinweise.appendChild(el('p', ZELLE + WARN + ' margin: 0 0 6px;', text('budget_hinweis', { n: b.uebersprungen }))); }\n        ziel.appendChild(hinweise);<\/p>\n<p>        \/\/ --- Erneut pruefen ---\n        var erneutBtn = el('button', 'background: transparent; color: var(--accent, #7ee787); border: 1px solid var(--accent, #7ee787); padding: 9px 16px; border-radius: 6px; font-weight: 700; cursor: pointer; font-size: 0.85rem; margin: 4px 0 10px;', T.knopf_erneut);\n        erneutBtn.className = 'button wh-erneut';\n        erneutBtn.setAttribute('data-url', b.url);\n        ziel.appendChild(erneutBtn);<\/p>\n<p>        \/\/ --- Uebersicht ---\n        ziel.appendChild(el('div', UEBERSCHRIFT, T.h_uebersicht));\n        var g = gitter('auto auto');\n        paar(g, T.zeile_endziel, b.endziel);\n        paar(g, T.zeile_wordpress, b.wordpress ? (b.wpVersion ? T.ja + ' (' + b.wpVersion + ')' : T.ja) : T.nein, b.wordpress ? GUT : WARN);\n        if (b.woocommerce) { paar(g, T.zeile_woocommerce, b.wcVersion ? T.ja + ' (' + b.wcVersion + ')' : T.ja, GUT); }\n        if (b.theme) { paar(g, T.zeile_theme, b.theme); }\n        paar(g, T.zeile_plugins, b.plugins.length ? b.plugins.join(', ') : T.wert_keine, GRAU);\n        if (b.server.software) { paar(g, T.zeile_server, b.server.software + (b.server.x_powered_by ? ' \/ ' + b.server.x_powered_by : ''), GRAU); }\n        if (b.server.http) { paar(g, T.zeile_http, 'HTTP\/' + b.server.http + (b.server.kompression ? ', ' + b.server.kompression : ''), GRAU); }\n        paar(g, T.zeile_seiten, String(b.seiten.length), GRAU);\n        if (b.limitRest !== null) { paar(g, T.zeile_limit, String(b.limitRest), GRAU); }\n        ziel.appendChild(g);<\/p>\n<p>        \/\/ --- Befunde ---\n        ziel.appendChild(el('div', UEBERSCHRIFT, T.h_befunde));\n        var irgendwas = false;\n        STUFEN.forEach(function (s) {\n            var gr = b.gruppen[s];\n            if (!gr.length) { return; }\n            irgendwas = true;\n            ziel.appendChild(el('div', 'font-weight: 700; font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.5px; margin: 14px 0 6px; color: ' + FARBEN[s] + ';', T['stufe_' + s] + ' (' + gr.length + ')'));\n            gr.forEach(function (f) {\n                var k = el('div', KASTEN + ' border-left: 3px solid ' + FARBEN[s] + ';');\n                var titel = text('befund_' + f.key, f.daten) || f.key;\n                var teile = titel.split(' || ');\n                var z1 = el('div', 'display: flex; justify-content: space-between; gap: 12px; align-items: baseline;');\n                z1.appendChild(el('div', 'color: var(--text-primary, #e8e8ee); font-size: 0.9rem; font-weight: 700;', teile[0]));\n                if (f.punkte > 0) { z1.appendChild(el('div', ZELLE_WERT + ' padding: 0; white-space: nowrap;' + GRAU, '-' + f.punkte)); }\n                k.appendChild(z1);\n                if (teile[1]) { k.appendChild(el('div', ZELLE + ' padding: 6px 0 0; line-height: 1.55;', teile[1])); }\n                if (Array.isArray(f.daten.liste) && f.daten.liste.length) {\n                    var l = el('ul', 'margin: 8px 0 0 18px; padding: 0; color: var(--text-secondary, #a0a0b0); font-size: 0.8rem; font-family: monospace; word-break: break-all;');\n                    f.daten.liste.forEach(function (x) { l.appendChild(el('li', '', String(x))); });\n                    k.appendChild(l);\n                }\n                ziel.appendChild(k);\n            });\n        });\n        if (!irgendwas) { ziel.appendChild(el('p', ZELLE + ' margin: 0;', T.keine_befunde)); }<\/p>\n<p>        \/\/ --- Seiten ---\n        if (b.seiten.length) {\n            ziel.appendChild(el('div', UEBERSCHRIFT, T.h_seiten));\n            var tabelle = el('div', 'overflow-x: auto;');\n            var gs = gitter('minmax(160px, 2fr) auto auto auto auto auto auto');\n            [T.spalte_seite, T.spalte_typ, T.spalte_ttfb, T.spalte_groesse, T.spalte_skripte, T.spalte_bilder, T.spalte_cache].forEach(function (s) {\n                gs.appendChild(el('div', ZELLE + ' font-weight: 700; color: var(--text-primary, #e8e8ee); white-space: nowrap;', s));\n            });\n            b.seiten.forEach(function (s) {\n                gs.appendChild(el('div', ZELLE_WERT, s.url));\n                gs.appendChild(el('div', ZELLE, T['typ_' + s.typ] || s.typ));\n                var t = zahl(s.ttfb_ms);\n                gs.appendChild(el('div', ZELLE_WERT + (t === null ? '' : (t >= 600 ? ROT : (t >= 300 ? WARN : GUT))), t === null ? '-' : t + ' ms'));\n                gs.appendChild(el('div', ZELLE_WERT, s.kb + ' KB'));\n                gs.appendChild(el('div', ZELLE_WERT, s.skripte + (s.blockierend ? ' (' + s.blockierend + ')' : '')));\n                gs.appendChild(el('div', ZELLE_WERT, String(s.bilder)));\n                var c = s.cache && s.cache.erkannt;\n                gs.appendChild(el('div', ZELLE + (c ? GUT : WARN), c ? (s.cache.name || T.ja) : T.nein));\n            });\n            tabelle.appendChild(gs);\n            ziel.appendChild(tabelle);\n        }<\/p>\n<p>        \/\/ --- Sonden ---\n        var so = b.sonden;\n        if (so.gelaufen) {\n            ziel.appendChild(el('div', UEBERSCHRIFT, T.h_sonden));\n            var gso = gitter('auto auto');\n            Object.keys(so.gelaufen).forEach(function (n) {\n                var lauf = so.gelaufen[n];\n                var w = '';\n                if (lauf !== 'ok') { w = lauf === 'budget' ? T.sonde_budget : T.sonde_fehler; }\n                else if (n === 'http' && so.http) { w = so.http.status + (so.http.ort ? ' \u2192 ' + so.http.ort : ''); }\n                else if (n === 'author' && so.author) { w = so.author.status + (so.author.ort ? ' \u2192 ' + so.author.ort : ''); }\n                else if ((n === 'css' || n === 'js') && so[n]) { w = so[n].status + (so[n].cache_control ? ' \u00b7 ' + so[n].cache_control : '') + (so[n].kompression ? ' \u00b7 ' + so[n].kompression : ''); }\n                else { w = String(so[n] === null || so[n] === undefined ? '-' : so[n]); }\n                paar(gso, T['sonde_' + n] || n, w, GRAU);\n            });\n            ziel.appendChild(gso);\n        }\n    }\n    window.LW_TEST.WH.darstellen = darstellen;<\/p>\n<p>    var laeuft = false;\n    function lauf(url, erneut) {\n        if (laeuft) { return; }\n        laeuft = true; btn.disabled = true;\n        out.innerHTML = '';\n        out.appendChild(el('p', ZELLE + GRAU + ' margin: 0;', T.laeuft));\n        var spaet = setTimeout(function () {\n            var p = out.querySelector('p');\n            if (p && laeuft) { p.textContent = T.laeuft_lang; }\n        }, 12000);\n        abfragen(url, erneut).then(function (a) {\n            clearTimeout(spaet);\n            darstellen(bewerten(a), out); laeuft = false; btn.disabled = false;\n        }, function () {\n            clearTimeout(spaet);\n            darstellen(bewerten({ fehler: 'netz' }), out); laeuft = false; btn.disabled = false;\n        });\n    }\n    btn.addEventListener('click', function () { lauf(wert('wh-url'), false); });\n    out.addEventListener('click', function (ev) {\n        var t = ev.target;\n        if (t && t.classList && t.classList.contains('wh-erneut')) {\n            ev.preventDefault();\n            lauf(t.getAttribute('data-url') || wert('wh-url'), true);\n        }\n    });\n})();\n<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Enter one address and get a scored optimisation report for a WordPress blog or WooCommerce shop: page cache, compression, HTTP\/2, render-blocking scripts, image loading, cart fragments on every page, version leaks and open XML-RPC. Reports are kept for a day; a button re-checks after changes.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":38,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"template-tool-base.php","meta":{"footnotes":""},"tags":[91339,91315,91115,91096],"class_list":["post-13514","page","type-page","status-publish","hentry","tag-e-commerce","tag-web-performance","tag-web-security","tag-wordpress"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>WordPress Site Health Analyzer - Lukas Wojcik - Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/wordpress-site-health-analyzer\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"WordPress Site Health Analyzer - Lukas Wojcik - Blog\" \/>\n<meta property=\"og:description\" content=\"Enter one address and get a scored optimisation report for a WordPress blog or WooCommerce shop: page cache, compression, HTTP\/2, render-blocking scripts, image loading, cart fragments on every page, version leaks and open XML-RPC. Reports are kept for a day; a button re-checks after changes.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/wordpress-site-health-analyzer\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/wordpress-site-health-analyzer\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/wordpress-site-health-analyzer\\\/\",\"name\":\"WordPress Site Health Analyzer - Lukas Wojcik - Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"datePublished\":\"2026-09-02T07:48:21+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/wordpress-site-health-analyzer\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/wordpress-site-health-analyzer\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/wordpress-site-health-analyzer\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Toolbox\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/toolbox\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"WordPress Site Health Analyzer\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\",\"name\":\"Lukas Wojcik - Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\",\"name\":\"luky\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"width\":424,\"height\":636,\"caption\":\"luky\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\"},\"sameAs\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"WordPress Site Health Analyzer - Lukas Wojcik - Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/wordpress-site-health-analyzer\/","og_locale":"en_US","og_type":"article","og_title":"WordPress Site Health Analyzer - Lukas Wojcik - Blog","og_description":"Enter one address and get a scored optimisation report for a WordPress blog or WooCommerce shop: page cache, compression, HTTP\/2, render-blocking scripts, image loading, cart fragments on every page, version leaks and open XML-RPC. Reports are kept for a day; a button re-checks after changes.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/wordpress-site-health-analyzer\/","og_site_name":"Lukas Wojcik - Blog","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/08\/og-default.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/wordpress-site-health-analyzer\/","url":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/wordpress-site-health-analyzer\/","name":"WordPress Site Health Analyzer - Lukas Wojcik - Blog","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"datePublished":"2026-09-02T07:48:21+00:00","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/wordpress-site-health-analyzer\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/wordpress-site-health-analyzer\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/wordpress-site-health-analyzer\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.lukaswojcik.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Toolbox","item":"https:\/\/www.lukaswojcik.com\/blog\/en\/toolbox\/"},{"@type":"ListItem","position":3,"name":"WordPress Site Health Analyzer"}]},{"@type":"WebSite","@id":"https:\/\/www.lukaswojcik.com\/blog\/#website","url":"https:\/\/www.lukaswojcik.com\/blog\/","name":"Lukas Wojcik - Blog","description":"","publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.lukaswojcik.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9","name":"luky","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","width":424,"height":636,"caption":"luky"},"logo":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg"},"sameAs":["https:\/\/www.lukaswojcik.com\/blog"]}]}},"_links":{"self":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/13514","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/comments?post=13514"}],"version-history":[{"count":0,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/13514\/revisions"}],"up":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/pages\/38"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=13514"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=13514"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}