feat(pagespeed): render page load filmstrip between hero and metrics

Horizontal scrollable filmstrip showing page rendering progression
with timing labels. Appears between the score hero and metrics card.
This commit is contained in:
Usman Baig
2026-03-22 19:43:44 +01:00
parent 50960d0556
commit fcbf21b715
2 changed files with 26 additions and 0 deletions

View File

@@ -403,6 +403,26 @@ export default function PageSpeedPage() {
</div>
</div>
{/* Filmstrip — page load progression */}
{currentCheck?.filmstrip && currentCheck.filmstrip.length > 0 && (
<div className="bg-white dark:bg-neutral-900 border border-neutral-200 dark:border-neutral-800 rounded-2xl p-5 mb-6">
<div className="flex items-center overflow-x-auto gap-1">
{currentCheck.filmstrip.map((frame, idx) => (
<div key={idx} className="flex-shrink-0 text-center">
<img
src={frame.data}
alt={`${frame.timing}ms`}
className="h-24 rounded border border-neutral-200 dark:border-neutral-700 object-contain bg-white"
/>
<span className="text-[10px] text-neutral-400 mt-1 block">
{frame.timing < 1000 ? `${frame.timing}ms` : `${(frame.timing / 1000).toFixed(1)}s`}
</span>
</div>
))}
</div>
</div>
)}
{/* Section 2 — Metrics Card */}
<div className="bg-white dark:bg-neutral-900 border border-neutral-200 dark:border-neutral-800 rounded-2xl p-6 sm:p-8 mb-6">
<h3 className="text-xs font-semibold text-neutral-500 dark:text-neutral-400 uppercase tracking-wider mb-5">

View File

@@ -26,6 +26,11 @@ export interface AuditSummary {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type AuditDetailItem = Record<string, any>
export interface FilmstripFrame {
timing: number
data: string
}
export interface PageSpeedCheck {
id: string
site_id: string
@@ -42,6 +47,7 @@ export interface PageSpeedCheck {
tti_ms: number | null
audits: AuditSummary[] | null
screenshot?: string | null
filmstrip?: FilmstripFrame[] | null
triggered_by: 'scheduled' | 'manual'
checked_at: string
}