Add Size % and Response Time % columns to Request Breakdown
Enhances the breakdown tables with comprehensive percentage analysis across three dimensions: request count, data size, and response time. Features: - Size Percentage column showing data transfer distribution - Response Time Percentage column showing performance impact distribution - Visual progress bars for all percentage columns (Count %, Size %, Response Time %) - Updated grid layout to accommodate 8-column structure - Responsive design updates for mobile compatibility - Clear column headers with abbreviated labels for better readability This enables three-dimensional analysis to identify: - Categories with high request counts but low data usage - Categories consuming disproportionate bandwidth - Performance bottlenecks with high cumulative response times - Optimization opportunities across all metrics 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
33fb2b1674
commit
b3dedb3dbf
@ -93,7 +93,7 @@
|
||||
|
||||
.tableHeader {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr 1fr 1.5fr 1.5fr 1.5fr;
|
||||
grid-template-columns: 2fr 1fr 1fr 1.5fr 1fr 1.5fr 1fr 1.5fr;
|
||||
gap: 16px;
|
||||
padding: 16px 20px;
|
||||
background: #f8f9fa;
|
||||
@ -107,7 +107,7 @@
|
||||
|
||||
.tableRow {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr 1fr 1.5fr 1.5fr 1.5fr;
|
||||
grid-template-columns: 2fr 1fr 1fr 1.5fr 1fr 1.5fr 1fr 1.5fr;
|
||||
gap: 16px;
|
||||
padding: 16px 20px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
@ -178,7 +178,7 @@
|
||||
}
|
||||
|
||||
.tableHeader, .tableRow {
|
||||
grid-template-columns: 1.5fr 0.8fr 0.8fr 1fr 1fr 1fr;
|
||||
grid-template-columns: 1.5fr 0.8fr 0.8fr 1fr 0.8fr 1fr 0.8fr 1fr;
|
||||
gap: 8px;
|
||||
padding: 12px 15px;
|
||||
font-size: 13px;
|
||||
|
@ -26,8 +26,10 @@ interface CategoryBreakdown {
|
||||
count: number
|
||||
percentage: number
|
||||
totalSize: number
|
||||
averageResponseTime: number
|
||||
sizePercentage: number
|
||||
totalResponseTime: number
|
||||
responseTimePercentage: number
|
||||
averageResponseTime: number
|
||||
}
|
||||
|
||||
const RequestBreakdown: React.FC<RequestBreakdownProps> = ({ traceId }) => {
|
||||
@ -93,6 +95,15 @@ const RequestBreakdown: React.FC<RequestBreakdownProps> = ({ traceId }) => {
|
||||
typeMap.get(type)!.push(req)
|
||||
})
|
||||
|
||||
// Calculate total size and response time across all requests for percentage calculations
|
||||
const totalAllSize = httpRequests.reduce((sum, req) => {
|
||||
return sum + (req.contentLength || req.encodedDataLength || 0)
|
||||
}, 0)
|
||||
|
||||
const totalAllResponseTime = httpRequests.reduce((sum, req) => {
|
||||
return sum + (req.timing.totalResponseTime || 0)
|
||||
}, 0)
|
||||
|
||||
return Array.from(typeMap.entries()).map(([type, requests]) => {
|
||||
const totalSize = requests.reduce((sum, req) => {
|
||||
return sum + (req.contentLength || req.encodedDataLength || 0)
|
||||
@ -107,8 +118,10 @@ const RequestBreakdown: React.FC<RequestBreakdownProps> = ({ traceId }) => {
|
||||
count: requests.length,
|
||||
percentage: (requests.length / httpRequests.length) * 100,
|
||||
totalSize,
|
||||
averageResponseTime: totalResponseTime / requests.length,
|
||||
totalResponseTime
|
||||
sizePercentage: totalAllSize > 0 ? (totalSize / totalAllSize) * 100 : 0,
|
||||
totalResponseTime,
|
||||
responseTimePercentage: totalAllResponseTime > 0 ? (totalResponseTime / totalAllResponseTime) * 100 : 0,
|
||||
averageResponseTime: totalResponseTime / requests.length
|
||||
}
|
||||
}).sort((a, b) => b.count - a.count)
|
||||
}, [httpRequests])
|
||||
@ -124,6 +137,15 @@ const RequestBreakdown: React.FC<RequestBreakdownProps> = ({ traceId }) => {
|
||||
statusMap.get(status)!.push(req)
|
||||
})
|
||||
|
||||
// Calculate total size and response time across all requests for percentage calculations
|
||||
const totalAllSize = httpRequests.reduce((sum, req) => {
|
||||
return sum + (req.contentLength || req.encodedDataLength || 0)
|
||||
}, 0)
|
||||
|
||||
const totalAllResponseTime = httpRequests.reduce((sum, req) => {
|
||||
return sum + (req.timing.totalResponseTime || 0)
|
||||
}, 0)
|
||||
|
||||
return Array.from(statusMap.entries()).map(([status, requests]) => {
|
||||
const totalSize = requests.reduce((sum, req) => {
|
||||
return sum + (req.contentLength || req.encodedDataLength || 0)
|
||||
@ -138,8 +160,10 @@ const RequestBreakdown: React.FC<RequestBreakdownProps> = ({ traceId }) => {
|
||||
count: requests.length,
|
||||
percentage: (requests.length / httpRequests.length) * 100,
|
||||
totalSize,
|
||||
averageResponseTime: totalResponseTime / requests.length,
|
||||
totalResponseTime
|
||||
sizePercentage: totalAllSize > 0 ? (totalSize / totalAllSize) * 100 : 0,
|
||||
totalResponseTime,
|
||||
responseTimePercentage: totalAllResponseTime > 0 ? (totalResponseTime / totalAllResponseTime) * 100 : 0,
|
||||
averageResponseTime: totalResponseTime / requests.length
|
||||
}
|
||||
}).sort((a, b) => b.count - a.count)
|
||||
}, [httpRequests])
|
||||
@ -155,6 +179,15 @@ const RequestBreakdown: React.FC<RequestBreakdownProps> = ({ traceId }) => {
|
||||
hostMap.get(hostname)!.push(req)
|
||||
})
|
||||
|
||||
// Calculate total size and response time across all requests for percentage calculations
|
||||
const totalAllSize = httpRequests.reduce((sum, req) => {
|
||||
return sum + (req.contentLength || req.encodedDataLength || 0)
|
||||
}, 0)
|
||||
|
||||
const totalAllResponseTime = httpRequests.reduce((sum, req) => {
|
||||
return sum + (req.timing.totalResponseTime || 0)
|
||||
}, 0)
|
||||
|
||||
return Array.from(hostMap.entries()).map(([hostname, requests]) => {
|
||||
const totalSize = requests.reduce((sum, req) => {
|
||||
return sum + (req.contentLength || req.encodedDataLength || 0)
|
||||
@ -169,8 +202,10 @@ const RequestBreakdown: React.FC<RequestBreakdownProps> = ({ traceId }) => {
|
||||
count: requests.length,
|
||||
percentage: (requests.length / httpRequests.length) * 100,
|
||||
totalSize,
|
||||
averageResponseTime: totalResponseTime / requests.length,
|
||||
totalResponseTime
|
||||
sizePercentage: totalAllSize > 0 ? (totalSize / totalAllSize) * 100 : 0,
|
||||
totalResponseTime,
|
||||
responseTimePercentage: totalAllResponseTime > 0 ? (totalResponseTime / totalAllResponseTime) * 100 : 0,
|
||||
averageResponseTime: totalResponseTime / requests.length
|
||||
}
|
||||
}).sort((a, b) => b.count - a.count)
|
||||
}, [httpRequests])
|
||||
@ -241,9 +276,11 @@ const RequestBreakdown: React.FC<RequestBreakdownProps> = ({ traceId }) => {
|
||||
<div className={styles.tableHeader}>
|
||||
<span>Type</span>
|
||||
<span>Count</span>
|
||||
<span>Percentage</span>
|
||||
<span>Count %</span>
|
||||
<span>Total Size</span>
|
||||
<span>Size %</span>
|
||||
<span>Total Response Time</span>
|
||||
<span>Response Time %</span>
|
||||
<span>Avg Response Time</span>
|
||||
</div>
|
||||
{resourceTypeBreakdown.map(item => (
|
||||
@ -260,7 +297,25 @@ const RequestBreakdown: React.FC<RequestBreakdownProps> = ({ traceId }) => {
|
||||
</div>
|
||||
</div>
|
||||
<span>{formatSize(item.totalSize)}</span>
|
||||
<div className={styles.percentageCell}>
|
||||
<span>{item.sizePercentage.toFixed(1)}%</span>
|
||||
<div className={styles.progressBar}>
|
||||
<div
|
||||
className={styles.progressFill}
|
||||
style={{ width: `${item.sizePercentage}%` }}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<span>{formatDuration(item.totalResponseTime)}</span>
|
||||
<div className={styles.percentageCell}>
|
||||
<span>{item.responseTimePercentage.toFixed(1)}%</span>
|
||||
<div className={styles.progressBar}>
|
||||
<div
|
||||
className={styles.progressFill}
|
||||
style={{ width: `${item.responseTimePercentage}%` }}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<span>{formatDuration(item.averageResponseTime)}</span>
|
||||
</div>
|
||||
))}
|
||||
@ -274,9 +329,11 @@ const RequestBreakdown: React.FC<RequestBreakdownProps> = ({ traceId }) => {
|
||||
<div className={styles.tableHeader}>
|
||||
<span>Status</span>
|
||||
<span>Count</span>
|
||||
<span>Percentage</span>
|
||||
<span>Count %</span>
|
||||
<span>Total Size</span>
|
||||
<span>Size %</span>
|
||||
<span>Total Response Time</span>
|
||||
<span>Response Time %</span>
|
||||
<span>Avg Response Time</span>
|
||||
</div>
|
||||
{statusCodeBreakdown.map(item => (
|
||||
@ -293,7 +350,25 @@ const RequestBreakdown: React.FC<RequestBreakdownProps> = ({ traceId }) => {
|
||||
</div>
|
||||
</div>
|
||||
<span>{formatSize(item.totalSize)}</span>
|
||||
<div className={styles.percentageCell}>
|
||||
<span>{item.sizePercentage.toFixed(1)}%</span>
|
||||
<div className={styles.progressBar}>
|
||||
<div
|
||||
className={styles.progressFill}
|
||||
style={{ width: `${item.sizePercentage}%` }}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<span>{formatDuration(item.totalResponseTime)}</span>
|
||||
<div className={styles.percentageCell}>
|
||||
<span>{item.responseTimePercentage.toFixed(1)}%</span>
|
||||
<div className={styles.progressBar}>
|
||||
<div
|
||||
className={styles.progressFill}
|
||||
style={{ width: `${item.responseTimePercentage}%` }}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<span>{formatDuration(item.averageResponseTime)}</span>
|
||||
</div>
|
||||
))}
|
||||
@ -307,9 +382,11 @@ const RequestBreakdown: React.FC<RequestBreakdownProps> = ({ traceId }) => {
|
||||
<div className={styles.tableHeader}>
|
||||
<span>Hostname</span>
|
||||
<span>Count</span>
|
||||
<span>Percentage</span>
|
||||
<span>Count %</span>
|
||||
<span>Total Size</span>
|
||||
<span>Size %</span>
|
||||
<span>Total Response Time</span>
|
||||
<span>Response Time %</span>
|
||||
<span>Avg Response Time</span>
|
||||
</div>
|
||||
{hostnameBreakdown.slice(0, 10).map(item => (
|
||||
@ -326,7 +403,25 @@ const RequestBreakdown: React.FC<RequestBreakdownProps> = ({ traceId }) => {
|
||||
</div>
|
||||
</div>
|
||||
<span>{formatSize(item.totalSize)}</span>
|
||||
<div className={styles.percentageCell}>
|
||||
<span>{item.sizePercentage.toFixed(1)}%</span>
|
||||
<div className={styles.progressBar}>
|
||||
<div
|
||||
className={styles.progressFill}
|
||||
style={{ width: `${item.sizePercentage}%` }}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<span>{formatDuration(item.totalResponseTime)}</span>
|
||||
<div className={styles.percentageCell}>
|
||||
<span>{item.responseTimePercentage.toFixed(1)}%</span>
|
||||
<div className={styles.progressBar}>
|
||||
<div
|
||||
className={styles.progressFill}
|
||||
style={{ width: `${item.responseTimePercentage}%` }}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<span>{formatDuration(item.averageResponseTime)}</span>
|
||||
</div>
|
||||
))}
|
||||
|
Loading…
Reference in New Issue
Block a user