diff --git a/src/components/RequestDebugger.tsx b/src/components/RequestDebugger.tsx index 6d4f998..b9a981f 100644 --- a/src/components/RequestDebugger.tsx +++ b/src/components/RequestDebugger.tsx @@ -1,4 +1,6 @@ import { useState, useMemo } from 'react' +import { Tooltip } from './shared/Tooltip' +import { TooltipType } from './shared/tooltipDefinitions' import type { TraceEvent } from '../../types/trace' interface RequestDebuggerProps { @@ -327,7 +329,9 @@ export default function RequestDebugger({ traceEvents }: RequestDebuggerProps) { return (
- Network Timing (from ResourceReceiveResponse): + + Network Timing (from ResourceReceiveResponse): +
requestTime: {timing.requestTime} seconds
dnsStart: {timing.dnsStart} ms
@@ -472,17 +476,30 @@ export default function RequestDebugger({ traceEvents }: RequestDebuggerProps) { borderRadius: '8px', padding: '20px' }}> -

Request Details: {selectedRequest.id}

+

+ + Request Details: {selectedRequest.id} + +

URL: {selectedRequest.url}
{/* Duration Calculations */} - {calculateDurations(selectedRequest.events)} +
+ +
+
+ {calculateDurations(selectedRequest.events)} +
{/* Event Details */}
-

All Events for this Request:

+

+ + All Events for this Request: + +

{(() => { const baseTimestamp = selectedRequest.events.sendRequest?.ts @@ -491,7 +508,10 @@ export default function RequestDebugger({ traceEvents }: RequestDebuggerProps) { {selectedRequest.events.sendRequest && (
- ResourceSendRequest - {formatTimestamp(selectedRequest.events.sendRequest.ts, baseTimestamp)} + + ResourceSendRequest + + {' '}- {formatTimestamp(selectedRequest.events.sendRequest.ts, baseTimestamp)}
                       {JSON.stringify(selectedRequest.events.sendRequest.args, null, 2)}
                     
@@ -500,7 +520,10 @@ export default function RequestDebugger({ traceEvents }: RequestDebuggerProps) { {selectedRequest.events.receiveResponse && (
- ResourceReceiveResponse - {formatTimestamp(selectedRequest.events.receiveResponse.ts, baseTimestamp)} + + ResourceReceiveResponse + + {' '}- {formatTimestamp(selectedRequest.events.receiveResponse.ts, baseTimestamp)} {formatTiming((selectedRequest.events.receiveResponse.args as any)?.data?.timing)}
                       {JSON.stringify(selectedRequest.events.receiveResponse.args, null, 2)}
@@ -510,7 +533,10 @@ export default function RequestDebugger({ traceEvents }: RequestDebuggerProps) {
 
                 {selectedRequest.events.receivedData.map((event, index) => (
                   
- ResourceReceivedData #{index + 1} - {formatTimestamp(event.ts, baseTimestamp)} + + ResourceReceivedData #{index + 1} + + {' '}- {formatTimestamp(event.ts, baseTimestamp)} {index === selectedRequest.events.receivedData.length - 1 && ( ← LAST DATA CHUNK )} @@ -532,7 +558,11 @@ export default function RequestDebugger({ traceEvents }: RequestDebuggerProps) { {/* Additional Event Types */} {selectedRequest.events.parseOnBackground && selectedRequest.events.parseOnBackground.length > 0 && (
-
V8 Parse Events:
+
+ + V8 Parse Events: + +
{selectedRequest.events.parseOnBackground.map((event, index) => (
{event.name} - {formatTimestamp(event.ts, baseTimestamp)} @@ -547,7 +577,11 @@ export default function RequestDebugger({ traceEvents }: RequestDebuggerProps) { {selectedRequest.events.compile && selectedRequest.events.compile.length > 0 && (
-
V8 Compile Events:
+
+ + V8 Compile Events: + +
{selectedRequest.events.compile.map((event, index) => (
{event.name} - {formatTimestamp(event.ts, baseTimestamp)} @@ -562,7 +596,11 @@ export default function RequestDebugger({ traceEvents }: RequestDebuggerProps) { {selectedRequest.events.evaluateScript && selectedRequest.events.evaluateScript.length > 0 && (
-
Script Evaluation Events:
+
+ + Script Evaluation Events: + +
{selectedRequest.events.evaluateScript.map((event, index) => (
{event.name} - {formatTimestamp(event.ts, baseTimestamp)} @@ -695,7 +733,11 @@ export default function RequestDebugger({ traceEvents }: RequestDebuggerProps) { {/* URL Loader Events */} {selectedRequest.events.throttlingURLLoader && selectedRequest.events.throttlingURLLoader.length > 0 && (
-
Throttling URL Loader Events ({selectedRequest.events.throttlingURLLoader.length}):
+
+ + Throttling URL Loader Events ({selectedRequest.events.throttlingURLLoader.length}): + +
{selectedRequest.events.throttlingURLLoader.map((event, index) => (
{event.name} - {formatTimestamp(event.ts, baseTimestamp)} diff --git a/src/components/httprequestviewer/RequestsTable.tsx b/src/components/httprequestviewer/RequestsTable.tsx index ac149b2..65a19d9 100644 --- a/src/components/httprequestviewer/RequestsTable.tsx +++ b/src/components/httprequestviewer/RequestsTable.tsx @@ -1,6 +1,8 @@ import React from 'react' import RequestRowSummary from './RequestRowSummary' import ScreenshotRow from './ScreenshotRow' +import { Tooltip } from '../shared/Tooltip' +import { TooltipType } from '../shared/tooltipDefinitions' import styles from './HTTPRequestViewer.module.css' import type { HTTPRequest, ScreenshotEvent } from './types/httpRequest' @@ -39,24 +41,96 @@ const RequestsTable: React.FC = ({ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/src/components/shared/Modal.tsx b/src/components/shared/Modal.tsx new file mode 100644 index 0000000..9704b4c --- /dev/null +++ b/src/components/shared/Modal.tsx @@ -0,0 +1,119 @@ +import { useEffect } from 'react' + +interface ModalProps { + isOpen: boolean + onClose: () => void + title: string + children: React.ReactNode +} + +export function Modal({ isOpen, onClose, title, children }: ModalProps) { + // Close modal on Escape key + useEffect(() => { + const handleEscape = (event: KeyboardEvent) => { + if (event.key === 'Escape') { + onClose() + } + } + + if (isOpen) { + document.addEventListener('keydown', handleEscape) + // Prevent body scrolling when modal is open + document.body.style.overflow = 'hidden' + } + + return () => { + document.removeEventListener('keydown', handleEscape) + document.body.style.overflow = 'unset' + } + }, [isOpen, onClose]) + + if (!isOpen) return null + + return ( +
+
e.stopPropagation()} + > + {/* Modal Header */} +
+

+ {title} +

+ +
+ + {/* Modal Content */} +
+ {children} +
+
+
+ ) +} \ No newline at end of file diff --git a/src/components/shared/Tooltip.tsx b/src/components/shared/Tooltip.tsx new file mode 100644 index 0000000..283d16f --- /dev/null +++ b/src/components/shared/Tooltip.tsx @@ -0,0 +1,215 @@ +import { useState } from 'react' +import { Modal } from './Modal' +import { TOOLTIP_DEFINITIONS } from './tooltipDefinitions' +import type { TooltipTypeValues } from './tooltipDefinitions' + +// Tooltip component for field explanations +interface TooltipProps { + children: React.ReactNode + type: TooltipTypeValues +} + +export function Tooltip({ children, type }: TooltipProps) { + const { title, description, lighthouseRelation, calculation, links } = TOOLTIP_DEFINITIONS[type] + const [isHovered, setIsHovered] = useState(false) + const [isModalOpen, setIsModalOpen] = useState(false) + + const handleIconClick = (e: React.MouseEvent) => { + e.preventDefault() + e.stopPropagation() + setIsHovered(false) // Hide hover tooltip when opening modal + setIsModalOpen(true) + } + + return ( + <> +
+ {children} + setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + onClick={handleIconClick} + style={{ + marginLeft: '6px', + cursor: 'pointer', + color: '#007bff', + fontSize: '14px', + fontWeight: 'bold', + width: '16px', + height: '16px', + borderRadius: '50%', + backgroundColor: '#e3f2fd', + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center', + userSelect: 'none', + transition: 'all 0.2s ease', + border: '1px solid transparent' + }} + onMouseDown={(e) => { + e.currentTarget.style.backgroundColor = '#bbdefb' + e.currentTarget.style.borderColor = '#2196f3' + }} + onMouseUp={(e) => { + e.currentTarget.style.backgroundColor = '#e3f2fd' + e.currentTarget.style.borderColor = 'transparent' + }} + > + ? + + + {/* Hover tooltip - only show when not modal open */} + {isHovered && !isModalOpen && ( +
+
+ {title} +
+
+ {description} +
+
+ Click for detailed information +
+
+ )} +
+ + {/* Modal with detailed content */} + setIsModalOpen(false)} + title={title} + > + + + + ) +} \ No newline at end of file diff --git a/src/components/shared/tooltipDefinitions.ts b/src/components/shared/tooltipDefinitions.ts new file mode 100644 index 0000000..89677fa --- /dev/null +++ b/src/components/shared/tooltipDefinitions.ts @@ -0,0 +1,345 @@ +// Centralized tooltip definitions +export const TooltipType = { + // HTTP Request Table Headers + EXPAND_ROW: 'EXPAND_ROW', + HTTP_METHOD: 'HTTP_METHOD', + HTTP_STATUS: 'HTTP_STATUS', + RESOURCE_TYPE: 'RESOURCE_TYPE', + REQUEST_PRIORITY: 'REQUEST_PRIORITY', + START_TIME: 'START_TIME', + QUEUE_TIME: 'QUEUE_TIME', + DNS_TIME: 'DNS_TIME', + CONNECTION_TIME: 'CONNECTION_TIME', + SERVER_LATENCY: 'SERVER_LATENCY', + REQUEST_URL: 'REQUEST_URL', + REQUEST_DURATION: 'REQUEST_DURATION', + TOTAL_RESPONSE_TIME: 'TOTAL_RESPONSE_TIME', + TRANSFER_SIZE: 'TRANSFER_SIZE', + CONTENT_LENGTH: 'CONTENT_LENGTH', + HTTP_PROTOCOL: 'HTTP_PROTOCOL', + CDN_DETECTION: 'CDN_DETECTION', + CACHE_STATUS: 'CACHE_STATUS', + + // Request Debugger Headers + REQUEST_DETAILS: 'REQUEST_DETAILS', + DURATION_CALCULATIONS: 'DURATION_CALCULATIONS', + ALL_EVENTS: 'ALL_EVENTS', + RESOURCE_SEND_REQUEST: 'RESOURCE_SEND_REQUEST', + RESOURCE_RECEIVE_RESPONSE: 'RESOURCE_RECEIVE_RESPONSE', + RESOURCE_RECEIVED_DATA: 'RESOURCE_RECEIVED_DATA', + V8_PARSE_EVENTS: 'V8_PARSE_EVENTS', + V8_COMPILE_EVENTS: 'V8_COMPILE_EVENTS', + SCRIPT_EVALUATION: 'SCRIPT_EVALUATION', + THROTTLING_URL_LOADER: 'THROTTLING_URL_LOADER', + NETWORK_TIMING: 'NETWORK_TIMING' +} as const + +export type TooltipTypeValues = typeof TooltipType[keyof typeof TooltipType] + +export interface TooltipDefinition { + title: string + description: string + lighthouseRelation?: string + calculation?: string + links?: Array<{ text: string; url: string }> +} + +export const TOOLTIP_DEFINITIONS: Record = { + // HTTP Request Table Headers + [TooltipType.EXPAND_ROW]: { + title: "Expand Row", + description: "Click to expand and see detailed request breakdown including timing waterfall, headers, and response details.", + lighthouseRelation: "Expanded view helps understand request bottlenecks affecting LCP, FCP, and overall performance scores." + }, + + [TooltipType.HTTP_METHOD]: { + title: "HTTP Method", + description: "The HTTP method used for this request (GET, POST, PUT, DELETE, etc.). Different methods have different caching and performance implications.", + lighthouseRelation: "GET requests are cacheable and can improve repeat visit performance. POST requests cannot be cached, affecting performance metrics.", + links: [ + { text: "HTTP Methods - MDN", url: "https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods" } + ] + }, + + [TooltipType.HTTP_STATUS]: { + title: "HTTP Status Code", + description: "HTTP response status code indicating success (2xx), redirection (3xx), client error (4xx), or server error (5xx).", + lighthouseRelation: "Status codes affect Lighthouse scoring: 4xx/5xx errors hurt performance scores, redirects (3xx) add latency affecting LCP and FCP.", + links: [ + { text: "HTTP Status Codes", url: "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" }, + { text: "Avoid Redirects", url: "https://web.dev/articles/redirects" } + ] + }, + + [TooltipType.RESOURCE_TYPE]: { + title: "Resource Type", + description: "Type of resource being requested: Document, Stylesheet, Script, Image, Font, XHR, Fetch, etc.", + lighthouseRelation: "Different resource types have different priority and impact on Core Web Vitals. Scripts/CSS block rendering, images affect LCP.", + calculation: "Derived from Content-Type header and request context.", + links: [ + { text: "Resource Prioritization", url: "https://web.dev/articles/resource-prioritization" }, + { text: "Critical Rendering Path", url: "https://web.dev/articles/critical-rendering-path" } + ] + }, + + [TooltipType.REQUEST_PRIORITY]: { + title: "Request Priority", + description: "Browser's internal priority for this request: VeryHigh, High, Medium, Low, VeryLow. Determines resource loading order.", + lighthouseRelation: "High priority resources are critical for LCP and FCP. Low priority resources should not block critical content.", + links: [ + { text: "Resource Prioritization", url: "https://web.dev/articles/resource-prioritization" }, + { text: "Chrome Resource Priorities", url: "https://docs.google.com/document/d/1bCDuq9H1ih9iNjgzyAL0gpwNFiEP4TZS-YLRp_RuMlc" } + ] + }, + + [TooltipType.START_TIME]: { + title: "Start Time", + description: "When the browser initiated this request, relative to navigation start or first request.", + lighthouseRelation: "Earlier start times generally improve performance scores. Delayed critical resource requests hurt LCP and FCP.", + calculation: "Timestamp relative to navigation start or performance.timeOrigin.", + links: [ + { text: "Navigation Timing API", url: "https://developer.mozilla.org/en-US/docs/Web/API/Navigation_timing_API" } + ] + }, + + [TooltipType.QUEUE_TIME]: { + title: "Queue Time", + description: "Time spent waiting in browser's request queue before being sent. Indicates network congestion or connection limits.", + lighthouseRelation: "High queue times delay resource loading, negatively impacting LCP, FCP, and Speed Index scores.", + calculation: "Time from request initiation to actual network send start.", + links: [ + { text: "HTTP/1.1 vs HTTP/2 Connection Limits", url: "https://web.dev/articles/http2" } + ] + }, + + [TooltipType.DNS_TIME]: { + title: "DNS Lookup Time", + description: "Time spent resolving the domain name to an IP address. First request to a domain includes DNS lookup.", + lighthouseRelation: "DNS lookup time contributes to TTFB (Time to First Byte) and overall request latency, affecting all performance metrics.", + calculation: "dnsEnd - dnsStart from Navigation Timing API.", + links: [ + { text: "Optimize DNS Lookups", url: "https://web.dev/articles/preconnect-and-dns-prefetch" }, + { text: "DNS Performance", url: "https://developer.mozilla.org/en-US/docs/Web/Performance/dns-prefetch" } + ] + }, + + [TooltipType.CONNECTION_TIME]: { + title: "Connection Time", + description: "Time to establish TCP connection (and SSL handshake if HTTPS). Includes connection reuse optimization.", + lighthouseRelation: "Connection time contributes to TTFB and affects all network-dependent metrics. HTTP/2 connection reuse improves performance.", + calculation: "connectEnd - connectStart, includes SSL time if HTTPS.", + links: [ + { text: "Preconnect to Required Origins", url: "https://web.dev/articles/preconnect-and-dns-prefetch" }, + { text: "HTTP/2 Connection Reuse", url: "https://web.dev/articles/http2" } + ] + }, + + [TooltipType.SERVER_LATENCY]: { + title: "Server Latency", + description: "Time from when request was sent to when first response byte was received. Measures server processing time.", + lighthouseRelation: "Server latency is a key component of TTFB (Time to First Byte), directly affecting LCP and FCP scores.", + calculation: "responseStart - requestStart from Navigation Timing API.", + links: [ + { text: "Reduce Server Response Times (TTFB)", url: "https://web.dev/articles/ttfb" }, + { text: "Server Performance Optimization", url: "https://web.dev/articles/fast" } + ] + }, + + [TooltipType.REQUEST_URL]: { + title: "Request URL", + description: "The full URL of the requested resource. Long URLs with many parameters can impact performance.", + lighthouseRelation: "URL structure affects caching efficiency. Query parameters can prevent caching, hurting repeat visit performance.", + links: [ + { text: "HTTP Caching", url: "https://web.dev/articles/http-cache" } + ] + }, + + [TooltipType.REQUEST_DURATION]: { + title: "Request Duration", + description: "Total time from request start to completion, including all network phases and data transfer.", + lighthouseRelation: "Long durations for critical resources directly impact LCP, FCP, and Speed Index. Background resource duration affects overall performance score.", + calculation: "responseEnd - requestStart from Navigation Timing API.", + links: [ + { text: "Optimize Resource Loading", url: "https://web.dev/articles/critical-rendering-path" } + ] + }, + + [TooltipType.TOTAL_RESPONSE_TIME]: { + title: "Total Response Time", + description: "Complete time from navigation start to request completion. Shows request timing in context of page load.", + lighthouseRelation: "Response time relative to navigation affects when resources become available for rendering, impacting LCP and FCP timing.", + calculation: "responseEnd - navigationStart." + }, + + [TooltipType.TRANSFER_SIZE]: { + title: "Transfer Size", + description: "Actual bytes transferred over network after compression, encoding, and headers. Includes HTTP overhead.", + lighthouseRelation: "Transfer size affects download time and bandwidth usage, impacting LCP for large resources and overall Speed Index.", + calculation: "Actual bytes received including headers and compression.", + links: [ + { text: "Optimize Resource Sizes", url: "https://web.dev/articles/fast#optimize_your_content_efficiency" }, + { text: "Enable Compression", url: "https://web.dev/articles/reduce-network-payloads-using-text-compression" } + ] + }, + + [TooltipType.CONTENT_LENGTH]: { + title: "Content-Length", + description: "Uncompressed size of response body as declared in Content-Length header. May differ from actual transfer size.", + lighthouseRelation: "Large content sizes increase download time, especially impacting LCP for critical resources and mobile performance scores.", + calculation: "Value from Content-Length HTTP response header.", + links: [ + { text: "Optimize Images", url: "https://web.dev/articles/fast#optimize_your_images" }, + { text: "Minify Resources", url: "https://web.dev/articles/reduce-network-payloads-using-text-compression" } + ] + }, + + [TooltipType.HTTP_PROTOCOL]: { + title: "HTTP Protocol", + description: "HTTP protocol version used: HTTP/1.1, HTTP/2, or HTTP/3. Newer protocols offer performance benefits.", + lighthouseRelation: "HTTP/2 and HTTP/3 improve multiplexing and reduce latency, positively impacting all performance metrics especially on mobile.", + links: [ + { text: "HTTP/2 Benefits", url: "https://web.dev/articles/http2" }, + { text: "HTTP/3 Performance", url: "https://web.dev/articles/http3" } + ] + }, + + [TooltipType.CDN_DETECTION]: { + title: "CDN Detection", + description: "Indicates if request was served by a Content Delivery Network. CDNs improve performance by serving content from geographically closer servers.", + lighthouseRelation: "CDN usage typically improves TTFB, LCP, and FCP by reducing latency. Critical for good mobile performance scores.", + links: [ + { text: "CDN Performance Benefits", url: "https://web.dev/articles/content-delivery-networks" } + ] + }, + + [TooltipType.CACHE_STATUS]: { + title: "Cache Status", + description: "Whether the resource was served from cache (browser, proxy, CDN) or fetched fresh from origin server.", + lighthouseRelation: "Cached resources load faster, improving repeat visit performance and Lighthouse scores. Critical for mobile performance optimization.", + links: [ + { text: "HTTP Caching", url: "https://web.dev/articles/http-cache" }, + { text: "Browser Caching", url: "https://web.dev/articles/uses-long-cache-ttl" } + ] + }, + + // Request Debugger Headers + [TooltipType.REQUEST_DETAILS]: { + title: "Request Details", + description: "Comprehensive trace analysis for a specific HTTP request, showing all related browser events and timing data.", + lighthouseRelation: "This detailed breakdown helps understand what contributes to Lighthouse metrics like LCP, FCP, and Speed Index. Each request impacts overall page load performance.", + links: [ + { text: "Chrome DevTools Network Panel", url: "https://developer.chrome.com/docs/devtools/network/" }, + { text: "Understanding Resource Loading", url: "https://web.dev/articles/critical-rendering-path" } + ] + }, + + [TooltipType.DURATION_CALCULATIONS]: { + title: "Duration Calculations", + description: "Key timing metrics extracted from trace events that show how long different phases of the request took.", + lighthouseRelation: "Directly impacts LCP (Largest Contentful Paint), FCP (First Contentful Paint), and overall Performance Score. Network request timings are critical components of Core Web Vitals.", + calculation: "Total Duration = Receive Response timestamp - Send Request timestamp. Individual phases calculated from trace event timing data.", + links: [ + { text: "Lighthouse Performance Scoring", url: "https://developer.chrome.com/docs/lighthouse/performance/performance-scoring/" }, + { text: "Core Web Vitals", url: "https://web.dev/articles/vitals" }, + { text: "Network Request Timing", url: "https://developer.mozilla.org/en-US/docs/Web/API/Performance_API/Resource_timing" } + ] + }, + + [TooltipType.ALL_EVENTS]: { + title: "All Events for this Request", + description: "Complete chronological list of browser trace events related to this HTTP request, from initiation to completion.", + lighthouseRelation: "These events show the complete request lifecycle that affects Lighthouse timing metrics. Each event type contributes differently to performance scores.", + links: [ + { text: "Chrome Trace Event Format", url: "https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview" }, + { text: "DevTools Performance Panel", url: "https://developer.chrome.com/docs/devtools/performance/" } + ] + }, + + [TooltipType.RESOURCE_SEND_REQUEST]: { + title: "ResourceSendRequest Event", + description: "Marks when the browser initiates sending the HTTP request. This is the starting point for network timing measurements.", + lighthouseRelation: "Start time for calculating request latency. Affects TTI (Time to Interactive) and Speed Index when blocking critical resources.", + calculation: "Request Duration = ResourceReceiveResponse.ts - ResourceSendRequest.ts", + links: [ + { text: "Network Request Lifecycle", url: "https://developer.chrome.com/blog/resource-loading-insights/" }, + { text: "Critical Request Chains", url: "https://web.dev/articles/critical-request-chains" } + ] + }, + + [TooltipType.RESOURCE_RECEIVE_RESPONSE]: { + title: "ResourceReceiveResponse Event", + description: "Indicates when the browser receives the HTTP response headers. Contains critical timing data like DNS lookup, connection establishment, and server response time.", + lighthouseRelation: "Key component of LCP (Largest Contentful Paint) and FCP (First Contentful Paint) measurements. Server response time directly impacts Lighthouse Performance Score.", + calculation: "Server Response Time = receiveHeadersEnd - sendStart (from timing object). Total request time measured from SendRequest to this event.", + links: [ + { text: "Server Response Time Optimization", url: "https://web.dev/articles/ttfb" }, + { text: "Navigation Timing API", url: "https://developer.mozilla.org/en-US/docs/Web/API/Navigation_timing_API" } + ] + }, + + [TooltipType.RESOURCE_RECEIVED_DATA]: { + title: "ResourceReceivedData Events", + description: "Shows when chunks of response data are received from the server. Multiple events indicate streaming/chunked transfer encoding.", + lighthouseRelation: "Affects Progressive Loading metrics and Speed Index. More data chunks generally indicate better streaming performance for large resources.", + calculation: "Data transfer progress can be tracked by summing encodedDataLength across all chunks. Last chunk indicates download completion.", + links: [ + { text: "Progressive Loading", url: "https://web.dev/articles/progressive-loading" }, + { text: "Chunked Transfer Encoding", url: "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding" } + ] + }, + + [TooltipType.V8_PARSE_EVENTS]: { + title: "V8 Parse Events", + description: "JavaScript parsing events that occur when V8 engine processes downloaded JS files. Background parsing improves main thread performance.", + lighthouseRelation: "Directly impacts TTI (Time to Interactive) and TBT (Total Blocking Time). Background parsing reduces main thread blocking, improving Lighthouse performance scores.", + calculation: "Parse time = event duration. Background parsing happens off main thread, reducing blocking time.", + links: [ + { text: "JavaScript Parsing Performance", url: "https://v8.dev/blog/background-compilation" }, + { text: "Reduce JavaScript Execution Time", url: "https://web.dev/articles/bootup-time" } + ] + }, + + [TooltipType.V8_COMPILE_EVENTS]: { + title: "V8 Compile Events", + description: "JavaScript compilation events in V8 engine. Shows when parsed JavaScript is compiled to bytecode or optimized machine code.", + lighthouseRelation: "Compilation time affects TTI (Time to Interactive) and can contribute to TBT (Total Blocking Time) if done on main thread. Efficient compilation improves runtime performance.", + calculation: "Compile time = event duration. Background compilation reduces main thread impact.", + links: [ + { text: "V8 Compilation Pipeline", url: "https://v8.dev/docs/ignition" }, + { text: "JavaScript Performance Best Practices", url: "https://web.dev/articles/fast" } + ] + }, + + [TooltipType.SCRIPT_EVALUATION]: { + title: "Script Evaluation Events", + description: "JavaScript execution/evaluation events. Shows when compiled scripts are actually executed by V8 engine.", + lighthouseRelation: "Direct impact on TTI (Time to Interactive) and TBT (Total Blocking Time). Script evaluation on main thread blocks user interaction, heavily affecting Lighthouse performance scores.", + calculation: "Execution time = event duration. All execution happens on main thread and contributes to blocking time.", + links: [ + { text: "Reduce JavaScript Execution Time", url: "https://web.dev/articles/bootup-time" }, + { text: "Main Thread Blocking", url: "https://web.dev/articles/long-tasks-devtools" } + ] + }, + + [TooltipType.THROTTLING_URL_LOADER]: { + title: "Throttling URL Loader Events", + description: "Network throttling and URL loading events from Chrome's network stack. Shows how requests are managed and potentially throttled.", + lighthouseRelation: "Network throttling affects all timing metrics (LCP, FCP, FID). Understanding these events helps identify network bottlenecks that impact Lighthouse scores.", + calculation: "Throttling delays can be calculated from event timestamps. Multiple events show request queuing and prioritization.", + links: [ + { text: "Network Throttling in DevTools", url: "https://developer.chrome.com/docs/devtools/network/#throttle" }, + { text: "Resource Prioritization", url: "https://web.dev/articles/resource-prioritization" } + ] + }, + + [TooltipType.NETWORK_TIMING]: { + title: "Network Timing Breakdown", + description: "Detailed network timing phases from the ResourceReceiveResponse event, showing DNS lookup, connection, SSL handshake, and data transfer times.", + lighthouseRelation: "These timings directly feed into TTFB (Time to First Byte) and overall request duration. DNS, connection, and SSL times affect all network-dependent Lighthouse metrics.", + calculation: "Total time = receiveHeadersEnd - requestTime. Each phase represents different network bottlenecks that can be optimized.", + links: [ + { text: "Navigation Timing API", url: "https://developer.mozilla.org/en-US/docs/Web/API/Navigation_timing_API" }, + { text: "Optimize TTFB", url: "https://web.dev/articles/ttfb" } + ] + } +} \ No newline at end of file
ExpandMethodStatusTypePriorityStart TimeQueue TimeDNSConnectionServer LatencyURLDurationTotal Response TimeSizeContent-LengthProtocolCDNCache + + Expand + + + + Method + + + + Status + + + + Type + + + + Priority + + + + Start Time + + + + Queue Time + + + + DNS + + + + Connection + + + + Server Latency + + + + URL + + + + Duration + + + + Total Response Time + + + + Size + + + + Content-Length + + + + Protocol + + + + CDN + + + + Cache + +