diff --git a/app/(defaults)/page-speed-test/page.tsx b/app/(defaults)/page-speed-test/page.tsx index 9752ccd..c7b4e0b 100644 --- a/app/(defaults)/page-speed-test/page.tsx +++ b/app/(defaults)/page-speed-test/page.tsx @@ -53,6 +53,7 @@ const PageSpeedTest = () => { screenshot: tabData.screenshot || '', thumbnails: tabData.thumbnails || [], passedAudits: tabData.passedAudits || [], + treemapData: tabData.treemapData || [], treemapPath: tabData.treemapPath || null }, }; diff --git a/components/pages/components-pages-faq-with-tabs.tsx b/components/pages/components-pages-faq-with-tabs.tsx index a8ce34e..796a858 100644 --- a/components/pages/components-pages-faq-with-tabs.tsx +++ b/components/pages/components-pages-faq-with-tabs.tsx @@ -1,5 +1,6 @@ 'use client'; import React, { useState } from 'react'; +import { Treemap, ResponsiveContainer, Tooltip } from 'recharts'; import IconDesktop from '@/components/icon/icon-desktop'; import IconRefresh from '@/components/icon/icon-refresh'; import IconInfoCircle from '@/components/icon/icon-info-circle'; @@ -12,11 +13,42 @@ interface ReportMobileDesktopProps { loading: boolean; } +const CustomizedContent = (props: any) => { + const { root, depth, x, y, width, height, index, name, colors, bg, resourceSize } = props; + + return ( + + + {width > 50 && height > 30 && ( + + {name.split('/').pop().split('?')[0].substring(0, 15)} + + )} + + ); +}; + const ReportMobileDesktop: React.FC = ({ reports, loading }) => { const [activeTab, setActiveTab] = useState<'mobile' | 'desktop'>('mobile'); - - const currentReport = reports?.[activeTab]?.report || null; - const getScoreColor = (score: number) => { if (score >= 90) return '#10b981'; // Green-500 if (score >= 50) return '#f59e0b'; // Amber-500 @@ -31,6 +63,25 @@ const ReportMobileDesktop: React.FC = ({ reports, load const [hoveredMetric, setHoveredMetric] = useState(null); + const currentReport = reports?.[activeTab]?.report || null; + + // Format data for Recharts Treemap + const formatTreemapData = (data: any[]) => { + if (!data || !Array.isArray(data)) return []; + return data + .filter(node => node.resourceSize > 1000) // Only show relevant scripts > 1KB + .map((node, i) => ({ + name: node.name || 'Unknown', + size: node.resourceSize || 0, + bg: i % 2 === 0 ? '#3b82f6' : '#2563eb', // Alternating blues + resourceSize: (node.resourceSize / 1024).toFixed(1) + ' KB' + })) + .sort((a, b) => b.size - a.size) + .slice(0, 15); // Top 15 scripts + }; + + const treemapData = formatTreemapData(currentReport?.treemapData); + const getMetricColor = (label: string, value: string) => { const num = parseFloat(value || "0"); if (label === 'FCP') return num <= 1.8 ? '#10b981' : num <= 3.0 ? '#f59e0b' : '#ef4444'; @@ -394,24 +445,53 @@ const ReportMobileDesktop: React.FC = ({ reports, load - {/* Treemap Final CTA */} - {currentReport?.treemapPath && ( -
-
- {/* Abstract background shape */} -
+ {/* Treemap Inline Visualization */} + {treemapData && treemapData.length > 0 && ( +
+
+
+ Resource Map +
+ Javascript Distribution +
+

Script Treemap Analysis

+

Visual breakdown of your top 15 scripts by resource size. Identifying large third-party scripts is key to performance.

+
-

In-Depth Resource Treemap Analysis

-

Uncover hidden third-party scripts and Bloated assets that are stealing your performance. Interactive visual report awaits.

- - - Explore Treemap - +
+
+ + } + > + { + if (active && payload && payload.length) { + const data = payload[0].payload; + return ( +
+

Resource Info

+

{data.name}

+
+
+

Total Size

+

{data.resourceSize}

+
+
+
+ ); + } + return null; + }} + /> +
+
+
)}