Skip to main content
Glama

Lighthouse MCP

by mizchi
analyze-lipscosme.ts7.58 kB
#!/usr/bin/env tsx import { executeL1Collect } from '../src/tools/l1-collect-single.js'; import { executeL2UnusedCode } from '../src/tools/l2-unused-code.js'; import { executeL2CriticalChain } from '../src/tools/l2-critical-chain.js'; import { executeL2DeepAnalysis } from '../src/tools/l2-deep-analysis.js'; async function analyzeLipscosme() { console.log('Starting analysis of lipscosme.com...\n'); try { // Step 1: Collect Lighthouse data console.log('Step 1: Collecting Lighthouse data...'); const collectResult = await executeL1Collect({ url: 'https://lipscosme.com/', device: 'mobile', categories: ['performance'] }); if (!collectResult.success || !collectResult.reportId) { throw new Error('Failed to collect Lighthouse data'); } console.log(`✓ Data collected. Report ID: ${collectResult.reportId}`); console.log(` Performance Score: ${collectResult.summary?.performanceScore || 'N/A'}`); console.log(` LCP: ${collectResult.summary?.lcp ? (collectResult.summary.lcp / 1000).toFixed(1) + 's' : 'N/A'}`); console.log(` FCP: ${collectResult.summary?.fcp ? (collectResult.summary.fcp / 1000).toFixed(1) + 's' : 'N/A'}`); console.log(` CLS: ${collectResult.summary?.cls || 'N/A'}`); console.log(` TBT: ${collectResult.summary?.tbt ? collectResult.summary.tbt + 'ms' : 'N/A'}\n`); // Step 2: Analyze unused code (particularly CSS) console.log('Step 2: Analyzing unused CSS and JavaScript...'); const unusedCodeResult = await executeL2UnusedCode({ reportId: collectResult.reportId }); if (unusedCodeResult.analysis) { console.log(`✓ Unused Code Analysis:`); console.log(` Total Unused CSS: ${(unusedCodeResult.analysis.totalUnusedCSSBytes / 1024).toFixed(0)}KB`); console.log(` Total Unused JS: ${(unusedCodeResult.analysis.totalUnusedJSBytes / 1024).toFixed(0)}KB`); console.log(` Total Wasted Bytes: ${(unusedCodeResult.analysis.totalWastedBytes / 1024).toFixed(0)}KB`); if (unusedCodeResult.analysis.unusedCSS.length > 0) { console.log('\n Top Unused CSS Files:'); unusedCodeResult.analysis.unusedCSS.slice(0, 3).forEach(css => { console.log(` - ${css.url}`); console.log(` Wasted: ${(css.wastedBytes / 1024).toFixed(0)}KB (${css.wastedPercent.toFixed(0)}%)`); }); } } // Step 3: Analyze critical request chains console.log('\nStep 3: Analyzing critical request chains...'); const criticalChainResult = await executeL2CriticalChain({ reportId: collectResult.reportId }); if (criticalChainResult.analysis) { console.log(`✓ Critical Chain Analysis:`); console.log(` Chain Depth: ${criticalChainResult.analysis.chainDepth}`); console.log(` Total Duration: ${(criticalChainResult.analysis.totalDuration / 1000).toFixed(1)}s`); console.log(` Total Transfer Size: ${(criticalChainResult.analysis.totalTransferSize / 1024).toFixed(0)}KB`); if (criticalChainResult.analysis.renderBlockingResources.length > 0) { console.log('\n Render-Blocking Resources:'); criticalChainResult.analysis.renderBlockingResources.slice(0, 5).forEach(resource => { console.log(` - ${resource.url}`); console.log(` Wasted: ${(resource.wastedMs / 1000).toFixed(1)}s`); }); } } // Step 4: Deep analysis for comprehensive insights console.log('\nStep 4: Performing deep analysis...'); const deepAnalysisResult = await executeL2DeepAnalysis({ reportId: collectResult.reportId, includeProblems: true, includeChains: true, includeThirdParty: true }); if (deepAnalysisResult.analysis) { console.log(`✓ Deep Analysis Complete:`); // CSS-specific findings const cssProblems = deepAnalysisResult.analysis.problems.filter(p => p.title.toLowerCase().includes('css') || p.title.toLowerCase().includes('style') || p.title.toLowerCase().includes('render') ); if (cssProblems.length > 0) { console.log('\n CSS-Related Problems:'); cssProblems.forEach(problem => { console.log(` - ${problem.title}`); console.log(` Impact: ${problem.impact}`); if (problem.savings) { console.log(` Potential Savings: ${problem.savings}`); } }); } // Third-party impact if (deepAnalysisResult.analysis.thirdPartyImpact) { const cssThirdParty = deepAnalysisResult.analysis.thirdPartyImpact.items.filter(item => item.entity.toLowerCase().includes('font') || item.entity.toLowerCase().includes('cdn') || item.entity.toLowerCase().includes('style') ); if (cssThirdParty.length > 0) { console.log('\n Third-Party CSS/Font Resources:'); cssThirdParty.forEach(item => { console.log(` - ${item.entity}`); console.log(` Transfer Size: ${(item.transferSize / 1024).toFixed(0)}KB`); console.log(` Blocking Time: ${item.blockingTime.toFixed(0)}ms`); }); } } } // Final diagnosis console.log('\n' + '='.repeat(60)); console.log('DIAGNOSIS: CSS Rendering Issues'); console.log('='.repeat(60)); // Calculate CSS impact const totalCSSWaste = unusedCodeResult.analysis?.totalUnusedCSSBytes || 0; const renderBlockingCSS = criticalChainResult.analysis?.renderBlockingResources .filter(r => r.url.includes('.css') || r.url.includes('style')) .reduce((sum, r) => sum + r.wastedMs, 0) || 0; console.log('\n📊 CSS Performance Impact:'); console.log(` - Unused CSS: ${(totalCSSWaste / 1024).toFixed(0)}KB`); console.log(` - Render-blocking CSS time: ${(renderBlockingCSS / 1000).toFixed(1)}s`); console.log(` - CSS Coverage: ${100 - (unusedCodeResult.analysis?.unusedCSS[0]?.wastedPercent || 0)}%`); console.log('\n🎯 Root Causes:'); if (totalCSSWaste > 100000) { console.log(' 1. Excessive unused CSS rules (over 100KB of waste)'); } if (renderBlockingCSS > 1000) { console.log(' 2. CSS files blocking initial render'); } if (criticalChainResult.analysis && criticalChainResult.analysis.chainDepth > 3) { console.log(' 3. Deep dependency chain for CSS resources'); } if (unusedCodeResult.analysis && unusedCodeResult.analysis.unusedCSS.some(css => css.wastedPercent > 80)) { console.log(' 4. CSS files with >80% unused rules'); } console.log('\n💡 Recommendations:'); console.log(' 1. Implement Critical CSS inlining'); console.log(' 2. Use CSS splitting and lazy-loading for non-critical styles'); console.log(' 3. Remove unused CSS rules with PurgeCSS or similar tools'); console.log(' 4. Minify and compress CSS files'); console.log(' 5. Use CSS containment for complex layouts'); console.log(' 6. Consider CSS-in-JS or atomic CSS for better tree-shaking'); // Estimate potential improvement const potentialSavings = totalCSSWaste + (renderBlockingCSS * 1000); console.log(`\n✨ Potential Performance Gain: ${(potentialSavings / 1024).toFixed(0)}KB reduction`); console.log(` Estimated LCP improvement: ${(renderBlockingCSS / 1000 * 0.7).toFixed(1)}s`); } catch (error) { console.error('Analysis failed:', error); process.exit(1); } } // Run the analysis analyzeLipscosme().then(() => { console.log('\n✅ Analysis complete!'); process.exit(0); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mizchi/lighthouse-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server