From 90044b9d5a352e338e2536200636de194ef75fa5 Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Mon, 2 Nov 2026 19:42:40 +0100 Subject: [PATCH] perf: draw the mail skeleton's rows with less markup --- app/boot-skeleton.css | 56 +++++++- .../__tests__/mail-skeleton.test.tsx | 2 +- components/boot-skeleton/mail-skeleton.tsx | 135 +++++++++--------- components/boot-skeleton/shell.tsx | 4 - 4 files changed, 120 insertions(+), 77 deletions(-) diff --git a/app/boot-skeleton.css b/app/boot-skeleton.css index 09908b5c4..5254a5240 100644 --- a/app/boot-skeleton.css +++ b/app/boot-skeleton.css @@ -95,8 +95,9 @@ /* mail */ /* List density (the density setting, data-boot-density): extra-compact rows + (boot-density-xc, the same variant contacts uses: drop one copy on merging) have no avatar, compact and extra-compact ones no preview. */ -@custom-variant boot-xc (&:where([data-boot-density="extra-compact"] *)); +@custom-variant boot-density-xc (&:where([data-boot-density="extra-compact"] *)); @custom-variant boot-dense (&:where([data-boot-density="compact"] *, [data-boot-density="extra-compact"] *)); /* Message previews turned off (showPreview). */ @custom-variant boot-no-preview (&:where([data-boot-preview="off"] *)); @@ -104,3 +105,56 @@ @custom-variant boot-std (&:where(:root:not([data-interface-layout="mountain-view"]) *)); /* Mountain View's side panel shows only with calendar or contacts. */ @custom-variant boot-no-mv-side (&:where([data-boot-rail]:not([data-boot-rail~="calendar"]):not([data-boot-rail~="contacts"]) *)); + +/* Message list rows (MailListRowsSkeleton), in short classes because a + skeleton draws dozens of them. Geometry as ThreadListItem's: a 1px rule, + the cell's density padding and gap, its minimum height on stacked rows. + In the components layer, so utilities on the same element still win. */ +@layer components { + .sk-mrow { + border-bottom: 1px solid var(--color-border); + background-color: var(--color-background); + } + .sk-mcell { + display: flex; + align-items: flex-start; + gap: var(--density-item-gap); + padding: var(--density-item-py) 0.75rem; + } + .sk-mcell-min { + min-height: var(--list-item-height); + } + /* The avatar's column: centred on the row. */ + .sk-mav { + display: flex; + flex-shrink: 0; + align-self: stretch; + align-items: center; + } + /* A line of text as tall as the real one (font size and leading from its + classes), with its bar centred on it. */ + .sk-ml { + position: relative; + display: block; + height: 1lh; + } + .sk-ml > .sk-shape { + position: absolute; + inset-block: 0; + inset-inline-start: 0; + height: 0.75rem; + margin-block: auto; + border-radius: 0.25rem; + } +} + +/* Panels drawn in the shapes' own colour (the sidebar in dark themes, the + Mountain View phone header): lift the shapes off them. Below the contrast + rules' specificity, and not in forced colours. */ +@media not (forced-colors: active) { + :where(.dark) .sk-lift-dark .sk-shape, + :where([data-interface-layout="mountain-view"]) .sk-lift-mv .sk-shape, + .sk-lift .sk-shape { + background-color: color-mix(in oklab, var(--color-foreground) 10%, transparent); + } +} diff --git a/components/boot-skeleton/__tests__/mail-skeleton.test.tsx b/components/boot-skeleton/__tests__/mail-skeleton.test.tsx index 27d59123b..784665b8c 100644 --- a/components/boot-skeleton/__tests__/mail-skeleton.test.tsx +++ b/components/boot-skeleton/__tests__/mail-skeleton.test.tsx @@ -47,7 +47,7 @@ describe('mail skeleton', () => { it('draws every shape for the boot page and lets the boot attributes pick', () => { const rows = html(); - expect(rows.querySelector('.boot-xc\\:hidden')).not.toBeNull(); + expect(rows.querySelector('.boot-density-xc\\:hidden')).not.toBeNull(); expect(rows.querySelector('.boot-dense\\:hidden')).not.toBeNull(); expect(rows.querySelector('.md\\:mv\\:block')).not.toBeNull(); }); diff --git a/components/boot-skeleton/mail-skeleton.tsx b/components/boot-skeleton/mail-skeleton.tsx index 9d270b954..ae430177e 100644 --- a/components/boot-skeleton/mail-skeleton.tsx +++ b/components/boot-skeleton/mail-skeleton.tsx @@ -32,7 +32,6 @@ import { Search, Settings, Square, - Star, Users, } from "@/components/icons"; import { cn } from "@/lib/cn"; @@ -75,7 +74,7 @@ function TextLine({ className, w, bar = "h-3" }: { className?: string; w: string export function FolderRowsSkeleton({ count = 7 }: { count?: number }) { return ( // On the sidebar's panel colour, which dark themes share with the shapes. -