Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .github/workflows/lighthouse.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,21 @@ jobs:
- run: pnpm build
- run: pnpm check:events

- name: Identify audit browser
id: browser
run: |
chrome_path="$(command -v google-chrome)"
echo "CHROME_PATH=$chrome_path" >>"$GITHUB_ENV"
echo "version=$("$chrome_path" --version | sha256sum | cut -d ' ' -f1)" >>"$GITHUB_OUTPUT"

# The build is deterministic, so an identical `dist/` measured with the same server, config,
# and lhci version has already passed; only the marker file is cached.
- name: Look up a previous Lighthouse pass
id: lighthouse-pass
uses: actions/cache/restore@v6
with:
path: .lighthouseci/passed
key: lighthouse-${{ env.LHCI_VERSION }}-${{ hashFiles('dist/**', '.lighthouseci/events/**', 'tools/ci/**') }}
key: lighthouse-${{ runner.os }}-${{ runner.arch }}-${{ steps.browser.outputs.version }}-${{ env.LHCI_VERSION }}-${{ hashFiles('dist/**', '.lighthouseci/events/**', 'tools/ci/**', '.github/workflows/lighthouse.yml') }}
lookup-only: true

- name: Lighthouse CI
Expand Down
5 changes: 4 additions & 1 deletion docs/tooling.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,10 @@ and stores it in `.lighthouseci/events/`. The audit server exposes those pages u
`/__event-fixture/`; production `dist/` and source dates stay unchanged. The job summary and the
log carry the scores per URL, every failed assertion, and for each URL the LCP element, its
phases, and the request waterfall; full reports upload as an artifact. A `dist/` byte-identical
to one that already passed skips Lighthouse.
to one that already passed skips Lighthouse. SVG definition IDs use a counter scoped to each
page render so repeated builds preserve the same output bytes; random IDs invalidate this cache.
The cache also includes Chrome’s version, the runner OS/architecture, and the workflow. The
audit uses the installed Chrome on `ubuntu-latest`, with that exact binary passed to Lighthouse.

### Performance budgets

Expand Down
3 changes: 2 additions & 1 deletion src/components/ui/primitives/ChalkOval.astro
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
---
import { cn } from "@/lib/cn";
import { type ChalkOvalProps, handLinkShadeClass, handMarkClass, handToneClass } from "@/lib/hand";
import { nextSvgId } from "@/lib/svg-id";

type Props = ChalkOvalProps;

const { variant = 1, tone = "marker", around = "word", class: className } = Astro.props;
const maskId = `oval-${crypto.randomUUID()}`;
const maskId = nextSvgId(Astro.locals);

/** The inline margin matches the ring's overhang so neighbours clear it. */
const overhang = {
Expand Down
10 changes: 10 additions & 0 deletions src/lib/svg-id.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { AstroGlobal } from "astro";

const sequences = new WeakMap<AstroGlobal["locals"], number>();

/** Astro.locals scopes the sequence to a page render, including its nested components. */
export const nextSvgId = (locals: AstroGlobal["locals"]): string => {
const next = (sequences.get(locals) ?? 0) + 1;
sequences.set(locals, next);
return `svg-${String(next)}`;
};
Loading