const fs = require('fs') const path = require('path') const html = fs.readFileSync('D:/Sites/Skinbase26/skinbase.top-20260429T075355.html', 'utf8') // The LH report embeds JSON like: const __json__ = ... or as a compressed string // Try to find the JSON blob by locating "requestedUrl" const idx = html.indexOf('"requestedUrl"') if (idx === -1) { console.log('No requestedUrl found in file') process.exit(1) } // Walk backwards to find the opening { of the top-level object let start = idx while (start > 0 && html[start] !== '{') start-- // Walk forward to find the matching close — take a large slice and try to parse const slice = html.slice(start) // Find the end by counting braces let depth = 0 let end = 0 for (let i = 0; i < slice.length; i++) { if (slice[i] === '{') depth++ else if (slice[i] === '}') { depth-- if (depth === 0) { end = i + 1 break } } } let lhr try { lhr = JSON.parse(slice.slice(0, end)) } catch { // Try taking the slice up to the first after requestedUrl const scriptEnd = html.indexOf('', idx) const scriptSlice = html.slice(start, scriptEnd).replace(/;?\s*$/, '') lhr = JSON.parse(scriptSlice) } // Print category scores console.log('=== CATEGORY SCORES ===') for (const [id, cat] of Object.entries(lhr.categories || {})) { console.log(` ${id}: ${Math.round((cat.score || 0) * 100)}`) } // Print failed/low audits (score < 1 and not null) console.log('\n=== FAILED / LOW AUDITS ===') for (const [id, audit] of Object.entries(lhr.audits || {})) { if (audit.score === null || audit.score === undefined) continue if (audit.score >= 1) continue const items = audit.details?.items?.length || 0 const displayValue = audit.displayValue || '' console.log(` [${(audit.score * 100).toFixed(0).padStart(3)}] ${id} ${displayValue}`) if (items > 0 && audit.score < 0.9) { const heads = (audit.details?.items || []).slice(0, 4) heads.forEach((item) => { const label = item.node?.snippet || item.url || item.description || item.label || JSON.stringify(item).slice(0, 120) console.log(` • ${label}`) }) } } // Print all opportunity audits console.log('\n=== OPPORTUNITY AUDITS ===') for (const [id, audit] of Object.entries(lhr.audits || {})) { if (audit.details?.type !== 'opportunity') continue const savings = audit.details?.overallSavingsMs || 0 if (savings < 100) continue console.log(` ${id}: ${savings}ms savings`) }