API
ogygia/insights
Findings computed from the event layer.
On this page
- analyze_cpu
- analyze_page
- analyze_session
- apply_attr_rules
- assets_diff
- browser_of
- compare
- defer_keys
- dev_compile_ms
- devtools_switched_on
- dynamic_imports
- engine_of
- explain_held_open
- first_difference
- hazard_fix
- hazard_words
- hole_segments
- html_diff
- hydration_hazards
- inline_threshold_tune
- is_trace
- late_found
- lcp_font
- lcp_rivals
- prebundled_names
- rate
- runtime_scripts
- session_timeline
- static_imports
- switch_in_url
- testing_lean
- vital_parts
- vitals_moved
- weigh_assets
- without_switch
- write_switch
- DEVTOOLS_COOKIE
- DEVTOOLS_ON
- DEVTOOLS_PARAM
- DOM_LARGE
- HOLE_SEG_LABEL
- TESTING_COOKIE
- TESTING_ENGINE_VERSION
- TESTING_LEAN
- TESTING_PARAM
- AssetRef
- AssetRef.url
- AssetRef.kind
- AssetRef.blocking
- AssetRef.via
- AssetRef.lazy
- AssetRef.runtime
- AssetRef.phase
- AssetsDiff
- AssetsDiff.js
- AssetsDiff.lazy_js
- AssetsDiff.added
- AssetsDiff.removed
- AssetsDiff.grew
- AssetsDiff.shrank
- AssetsDiff.to_start
- AssetsDiff.to_later
- AttrRule
- AttrRule.tag
- AttrRule.name
- AttrRule.value
- CpuFn
- CpuFn.name
- CpuFn.file
- CpuFn.line
- CpuFn.kind
- CpuFn.self_ms
- CpuFn.total_ms
- CpuSummary
- CpuSummary.window_ms
- CpuSummary.busy_ms
- CpuSummary.by_kind
- CpuSummary.fns
- CpuSummary.files
- CpuSummary.islands
- CpuSummary.outside
- CpuSummary.interval_ms
- CpuSummary.by_host
- Failure
- Failure.fp
- Failure.message
- Failure.span
- Failure.turn
- FpDrift
- FpDrift.entry
- FpDrift.fp_was
- FpDrift.fp_now
- FpDrift.path
- FpDrift.was
- FpDrift.now
- HeldOpen
- HeldOpen.side
- HeldOpen.keys
- HeldOpen.early_ms
- HeldOpen.early_bytes
- HeldOpen.late_ms
- HeldOpen.late_bytes
- HeldOpen.islands
- HoleBatch
- HoleBatch.sent
- HoleBatch.delivered
- HoleBatch.status
- HoleBatch.refused
- HoleBatch.final_url
- HoleBatch.names
- HoleFailure
- HoleFailure.fp
- HoleFailure.name
- HoleFailure.endpoint
- HoleFailure.reason
- HoleFailure.final_url
- HoleFailure.message
- HoleFailure.attempts
- HoleWait
- HoleWait.name
- HoleWait.wait_ms
- HoleWait.below_fold
- HoleWait.server_ms
- HoleWait.server_queue_ms
- HoleWait.endpoint
- HoleWait.shown_at
- HoleWait.left_at
- HoleWait.first_at
- HoleWait.end_at
- HoleWait.batch_size
- HtmlDiff
- HtmlDiff.hunks
- HtmlDiff.removed
- HtmlDiff.added
- HtmlDiff.partial
- InteractionCpuInput
- InteractionCpuInput.t
- InteractionCpuInput.mapped
- InteractionCpuInput.wait
- InteractionCpuInput.handler
- IslandCode
- IslandCode.fp
- IslandCode.name
- IslandCode.bytes
- IslandCode.top
- IslandCode.barrels
- IslandCode.hazards
- IslandRow
- IslandRow.fp
- IslandRow.name
- IslandRow.wake
- IslandRow.load_ms
- IslandRow.queue_ms
- IslandRow.hydrate_ms
- IslandRow.t0
- IslandRow.done
- IslandRow.recovered
- IslandRow.changed
- IslandRow.shift
- IslandRow.longtask_ms
- IslandRow.early_ms
- IslandRow.below_fold
- IslandRow.cpu_ms
- KeptIsland
- KeptIsland.entry
- KeptIsland.fp
- KeptIsland.props
- NavPhases
- NavPhases.redirect
- NavPhases.worker
- NavPhases.dns
- NavPhases.connect
- NavPhases.tls
- NavPhases.wait
- PageAssets
- PageAssets.assets
- PageAssets.unscoped
- PageAssets.missed
- PageAssets.missed_why
- PageAssets.html
- PageAssets.inline
- PageAssets.totals
- PageFinding
- PageFinding.code
- PageFinding.severity
- PageFinding.message
- PageFinding.fix
- PageFinding.fps
- PageFinding.dev_compile
- PageInput
- PageInput.dev
- PageInput.server_profiles
- PageInput.server_profile
- PageInput.interaction_cpu
- PageInput.held_open
- PageInput.vitals
- PageInput.visit
- PageInput.islands
- PageInput.firsts
- PageInput.shifts
- PageInput.longtasks
- PageInput.longtasks_from
- PageInput.shifts_from
- PageInput.snapshots
- PageInput.empty_slots
- PageInput.hole_failures
- PageInput.island_code
- PageInput.hole_waits
- PageInput.hole_batches
- PageInput.restore_events
- PageInput.fp_drift
- PageInput.prebundled
- PageInput.browser
- PageInput.dock_open_at
- PageInput.leftovers
- PageInput.scroll_blockers
- PageInput.bfcache
- PageInteraction
- PageInteraction.name
- PageInteraction.t
- PageInteraction.ms
- PageInteraction.delay
- PageInteraction.processing
- PageInteraction.presentation
- PageInteraction.target
- PageInteraction.fp
- PageInteraction.scripts
- PageNav
- PageNav.from
- PageNav.to
- PageNav.type
- PageNav.t
- PageNav.fetched
- PageNav.styled
- PageNav.swapped
- PageNav.server
- PageNav.download
- PageNav.bytes
- PageNav.prefetched
- PageNav.on_server
- PageReport
- PageReport.vitals
- PageReport.rows
- PageReport.findings
- PageReport.blocking
- PageReport.bytes
- PageReport.longtask_ms
- PageReport.third_party
- RatedVital
- RatedVital.key
- RatedVital.label
- RatedVital.value
- RatedVital.rating
- RegionFact
- RegionFact.fp
- RegionFact.name
- RegionFact.kind
- RegionFact.wake
- RegionFact.hydrated
- RegionFact.top
- RegionFact.height
- RegionFact.own_bytes
- RegionFact.hidden
- RegionFact.shows_at
- RegionFact.headless
- RestoreEvent
- RestoreEvent.kind
- RestoreEvent.host
- RestoreEvent.t
- RestoreEvent.diff
- RestoreEvent.island
- RuntimeScripts
- RuntimeScripts.files
- RuntimeScripts.bytes
- RuntimeScripts.wire
- RuntimeScripts.by
- RuntimeScripts.island_entries
- ServerProfileBrief
- ServerProfileBrief.ago_min
- ServerProfileBrief.render_ms
- ServerProfileBrief.top
- ServerProfileBrief.calls
- ServerProfileBrief.calls_ms
- ServerProfileBrief.no_store
- ServerProfileBrief.prerendered
- SessionClick
- SessionClick.t
- SessionClick.target
- SessionClick.fp
- SessionClick.el
- SessionClick.clickable
- SessionData
- SessionData.from
- SessionData.to
- SessionData.interactions
- SessionData.longtasks
- SessionData.frames
- SessionData.shifts
- SessionData.requests
- SessionData.mutations
- SessionData.mut_log
- SessionData.clicks
- SessionData.errors
- SessionData.navs
- SessionData.heap
- SessionData.events
- SessionData.cpu
- SessionData.cpu_off
- SessionData.page
- SessionData.pages
- SessionData.names
- SessionFinding
- SessionFinding.code
- SessionFinding.severity
- SessionFinding.message
- SessionFinding.fix
- SessionFinding.refs
- SessionFinding.url
- SessionFrame
- SessionFrame.t
- SessionFrame.ms
- SessionFrame.blocking
- SessionFrame.scripts
- SessionInteraction
- SessionInteraction.t
- SessionInteraction.name
- SessionInteraction.duration
- SessionInteraction.input_delay
- SessionInteraction.processing
- SessionInteraction.presentation
- SessionInteraction.id
- SessionInteraction.target
- SessionInteraction.fp
- SessionInteraction.el
- SessionNav
- SessionNav.url
- SessionNav.t
- SessionNav.type
- SessionNav.source
- SessionNav.fp
- SessionReport
- SessionReport.duration_ms
- SessionReport.counts
- SessionReport.findings
- SessionReport.interactions
- SessionReport.by_island
- SessionReport.requests
- SessionReport.failed
- SessionReport.by_element
- SessionReport.cpu
- SessionRequest
- SessionRequest.url
- SessionRequest.type
- SessionRequest.t
- SessionRequest.ms
- SessionRequest.bytes
- SessionRequest.status
- SessionRequest.server
- SessionShift
- SessionShift.t
- SessionShift.value
- SessionShift.input
- SessionShift.fp
- SessionShift.el
- TimelineItem
- TimelineItem.t0
- TimelineItem.t1
- TimelineItem.label
- TimelineItem.tone
- TimelineItem.server
- TimelineItem.ref
- TimelineLane
- TimelineLane.key
- TimelineLane.label
- TimelineLane.items
- VitalMove
- VitalMove.key
- VitalMove.a
- VitalMove.b
- VitalMove.part
- VitalPart
- VitalPart.key
- VitalPart.label
- VitalPart.ms
- Weight
- Weight.bytes
- Weight.wire
- Weight.imports
- Weight.dynamic
- Weight.unscoped
- Weight.vary
- AssetKind
- CodeKind
- HydrationStatus
- IslandHazard
- PartedVital
- Ref
This page is generated from the package’s own .d.ts files on every build, so the signatures, descriptions and examples below always match the source.
import { … } from 'ogygia/insights';Exports analyze_cpu · analyze_page · analyze_session · apply_attr_rules · assets_diff · browser_of · compare · defer_keys · dev_compile_ms · devtools_switched_on · dynamic_imports · engine_of · explain_held_open · first_difference · hazard_fix · hazard_words · hole_segments · html_diff · hydration_hazards · inline_threshold_tune · is_trace · late_found · lcp_font · lcp_rivals · prebundled_names · rate · runtime_scripts · session_timeline · static_imports · switch_in_url · testing_lean · vital_parts · vitals_moved · weigh_assets · without_switch · write_switch · DEVTOOLS_COOKIE · DEVTOOLS_ON · DEVTOOLS_PARAM · DOM_LARGE · HOLE_SEG_LABEL · TESTING_COOKIE · TESTING_ENGINE_VERSION · TESTING_LEAN · TESTING_PARAM · AssetRef · AssetsDiff · AttrRule · CpuFn · CpuSummary · Failure · FpDrift · HeldOpen · HoleBatch · HoleFailure · HoleWait · HtmlDiff · InteractionCpuInput · IslandCode · IslandRow · KeptIsland · NavPhases · PageAssets · PageFinding · PageInput · PageInteraction · PageNav · PageReport · RatedVital · RegionFact · RestoreEvent · RuntimeScripts · ServerProfileBrief · SessionClick · SessionData · SessionFinding · SessionFrame · SessionInteraction · SessionNav · SessionReport · SessionRequest · SessionShift · TimelineItem · TimelineLane · VitalMove · VitalPart · Weight · AssetKind · CodeKind · HydrationStatus · IslandHazard · PartedVital · Ref
analyze_cpu
function
function analyze_cpu(trace: SelfProfileTrace, windows: IslandWindow[], longtasks: {
t: number;
ms: number;
}[], page_url: string): CpuSummary;analyze_page
function
function analyze_page(page: PageInput, regions: RegionFact[], failures?: Failure[], now?: number, cpu?: CpuSummary | null): PageReport;analyze_session
function
function analyze_session(s: SessionData, names: (fp: string) => string, page_url: string): SessionReport;apply_attr_rules
function
Split changes into those rules ignore and those left.
function apply_attr_rules(changes: AttrChange[], rules: AttrRule[]): {
left: AttrChange[];
ignored: AttrChange[];
};assets_diff
function
function assets_diff(a: WeighedLike, b: WeighedLike): AssetsDiff;browser_of
function
The browser a page ran in, by name and major version (Safari 18, Chrome 141, Firefox 133, Edge 141), from its user-agent string by plain search; null when it says nothing known. Some
findings are one engine's (Safari reports no layout shifts; a preload one engine reuses another
fetches again): the profiler's report and the Page tab name which.
function browser_of(ua: string | undefined): string | null;compare
function
Islands matched by entry and their place among its copies; a moved fingerprint, explained.
function compare(was: Kept[], now: Kept[]): FpDrift[];defer_keys
function
The page seed's defer ids → the page.data key each stands for (top level and one level down):
the seed (application/ogygia-page, the flat devalue form) holds a defer marker [name, i] per
streamed promise, the marker's payload the id the streamed resolve script settles. From the whole
document's HTML or the seed script's own text. indexOf only.
function defer_keys(html: string, marker?: string): Map<number, string>;dev_compile_ms
function
On the dev server: how much of an island's code load was the server COMPILING files on this request — the time (overlaps counted once) the server took to answer each file fetched in its load window, when that took 80 ms or more (a transform: a warm dev server answers in a few). 0 off the dev server, or when the visit does not list the files.
function dev_compile_ms(page: Pick<PageInput, "dev" | "visit">, r: Pick<IslandRow, "t0" | "load_ms">): number;devtools_switched_on
function
Is it on in this browser (false off the browser, or with cookies blocked).
function devtools_switched_on(): boolean;dynamic_imports
function
import("x") / import('x') specifiers in a script's text (Kit's inline start).
function dynamic_imports(text: string): string[];engine_of
function
The engine family a user agent runs on: what makes two browsers measure a page differently (Edge and Chrome are one; Safari reports no layout shifts and refetches a preload Chromium reuses).
function engine_of(ua: string | undefined): "chromium" | "webkit" | "gecko" | null;explain_held_open
function
THE DOCUMENT HELD OPEN: the page painted early, but its HTML kept coming — and islands wake only
once the whole document is in (DOMContentLoaded, the wake gate), so every island waited for its
end, even one that reads nothing late. Usually a load's streamed promise: the response stays open
until the last one settles. From the browser (the navigation's first and last byte, the paint,
the islands' hydrate steps after the end) and, when known, what held it (held_open: each streamed
promise by its page.data key and when it settled). With no visit, the profiled render alone
says it (its chunks: the early part, then the tail after the longest pause).
function explain_held_open(page: PageInput, rows: readonly IslandRow[], name_of: (fp: string) => string): PageFinding | null;first_difference
function
Where two strings first differ, as a short "server … / now …" pair (the markup-changed proof).
function first_difference(a: string, b: string, span?: number): {
at: number;
server: string;
now: string;
} | null;hazard_fix
function
The fix for those lines: what to do with each kind.
function hazard_fix(lines: readonly IslandHazard[]): string;hazard_words
function
"In its own code, the likeliest: X.svelte:4 (…) awaits …; Y.svelte:8 reads Date.now( while rendering …" —
said the same by the profiler's report and the devtools' Page tab
function hazard_words(lines: readonly IslandHazard[]): string;hole_segments
function
The segments, in order. Without a timing, one: the wait. A request the document preloaded starts before the fallback counts: its segments start where it left.
function hole_segments(h: HoleTimes): {
k: HoleSegKind;
a: number;
b: number;
}[];html_diff
function
function html_diff(server: string, browser: string, context?: number, max_d?: number): HtmlDiff;hydration_hazards
function
function hydration_hazards(source: string): Hazard[];inline_threshold_tune
function
THE INLINE THRESHOLD THAT TAKES THE SMALL SHEETS OFF THE PAINT: Kit inlines its route stylesheets
under inlineStyleThreshold (ogygia's island sheets follow the same setting), as <style> in the
HTML — no request to wait on. Of the blocking build stylesheets (/_app/immutable/), the smallest
first, while each is 8 KB or less and the HTML grows by 24 KB at most: the threshold that inlines
them (just over the largest, in whole KB), how many, how many bytes. Null under two sheets. The
profiler's page weight (style) and the Page tab's resources (css) both ask it.
function inline_threshold_tune(blocking: readonly {
url: string;
kind: string;
bytes: number;
}[]): {
threshold: number;
files: number;
bytes: number;
} | null;is_trace
function
Is this a trace the analyzer can read.
function is_trace(x: unknown): x is SelfProfileTrace;late_found
function
WHY THE BROWSER FOUND THE LARGEST PAINT'S FILE LATE, from what the visit saw: a CSS background
(found only once its stylesheet is in and the element laid out), an image its island's code added
as it woke (the request began after it hydrated: the server HTML had none), or an <img> in the
HTML at the low priority an image starts at. The generic advice when none of them is it.
function late_found(p: NonNullable<NonNullable<PageInput["visit"]>["paints"]> | undefined, res: {
start: number;
req_start?: number;
} | undefined, islands: readonly PageIsland[], name_of: (fp: string | undefined) => string): string;lcp_font
function
THE FONT THE LARGEST PAINT WAITED FOR: a text paint (no file of its own) that came within 200 ms of a font file landing after the first paint, whose face hides its text until then (font-display auto/block). The page's text was there all along, invisible: the font, not the server, set the LCP. Shared by the Page tab's split and the profiler's LCP gap.
function lcp_font(visit: PageInput["visit"] | null | undefined): {
family: string;
file: string;
end: number;
} | null;lcp_rivals
function
WHAT THE LARGEST PAINT'S DOWNLOAD SHARED THE NETWORK WITH: images far below the first screen, not lazy, whose own download overlapped the largest paint's file (or, a text paint, the wait from the first byte to the paint). Shared by the Page tab's split and the profiler's LCP gap.
function lcp_rivals(visit: PageInput["visit"] | null | undefined): {
bytes: number;
files: string[];
} | null;prebundled_names
function
The packages a dev server's _metadata.json optimized keys name: svelte/internal/client → svelte, @scope/lib/x → @scope/lib, `ogygia >
function prebundled_names(keys: readonly string[]): string[];rate
function
function rate(key: RatedVital["key"], value: number): Rating;runtime_scripts
function
SCRIPTS LOADED AT RUNTIME — what the browser fetched that neither the HTML nor any module's
imports name: a script that loads more scripts (a CDN component library fetching its parts, a tag
manager, a runtime's on-demand chunk). The server cannot see them coming; the profiler user's own
visit saw them. until: the end of "at start" on the visit's clock (a lazy island woken by a
scroll later does not count). Null when there are none.
function runtime_scripts(assets: readonly {
url: string;
}[], resources: readonly {
url: string;
type: string;
start: number;
size?: number;
transfer?: number;
}[], origin: string, until: number): RuntimeScripts | null;session_timeline
function
The session on one clock, lane by lane (the Record tab draws it). Capped per lane.
function session_timeline(s: SessionData, names: (fp: string) => string): TimelineLane[];static_imports
function
The STATIC imports of a bundled module (import{a}from"./x.js", import"./y.js", export*from"./z.js"): specifiers after from / a bare import that look like module paths
(relative or absolute, ending in .js/.mjs). Bundler output writes them plainly; a string that
merely contains such text inflates nothing that does not exist — every hit is fetched, and a
miss is dropped.
function static_imports(code: string): string[];switch_in_url
function
What the URL asks for: true on, false off, null nothing (absent or another value).
function switch_in_url(url: URL): boolean | null;testing_lean
function
Lean testing in this browser: the cookie, or the URL param (false off the browser).
function testing_lean(): boolean;vital_parts
function
function vital_parts(page: PageInput, key: PartedVital): VitalPart[] | null;vitals_moved
function
WHICH VITALS MOVED between two visits of a page, past the noise, and for a split vital the part
that moved most. ONE rule for both tools: the profiler's "since your last profile" and the Page
tab's "since your last load" read the same moves. parts(side, key) gives a side's parts.
function vitals_moved(a: Record<string, number | undefined>, b: Record<string, number | undefined>, parts: (side: "a" | "b", key: PartedVital) => VitalPart[] | null): VitalMove[];weigh_assets
function
function weigh_assets(opts: WeighOptions): Promise<PageAssets>;without_switch
function
The URL without the switch param (the address after it was applied).
function without_switch(url: URL): URL;write_switch
function
Turn it on / off in this browser (the cookie; the caller updates what shows).
function write_switch(on: boolean): void;DEVTOOLS_COOKIE
const
THE DEVTOOLS SWITCH — whether devtools is on in this browser, in a BUILD with devtools (a QA or preview deploy; the dev server always has it on). One cookie decides all of it: the launcher shows, the page is measured from the start (runtime/beacon.ts), what islands leave running is watched (leftovers.ts), and the server writes its event side-channel (hooks.ts). Off — the default — a visitor sees nothing and pays nothing.
A developer turns it on for their own browser, and it stays on across navigations and reloads:
?og-devtools=on/?og-devtools=offon any page (the server sets the cookie on that very response, the browser too — a prerendered page has no server — and the address drops the param);ogygia.devtools.on()/.off()in the console;- "hide" in the dock turns it off.
(The value is not the 1 an earlier launcher set on a plain click: a browser that clicked the old
button once stays off until it opts in.)
A plain module: the server, the runtime and the launcher all read it.
const DEVTOOLS_COOKIE = "og_devtools"DEVTOOLS_ON
const
const DEVTOOLS_ON = "on"DEVTOOLS_PARAM
const
The URL param that flips it: ?og-devtools=on / ?og-devtools=off.
const DEVTOOLS_PARAM = "og-devtools"DOM_LARGE
const
a page of this many elements or more is named (the beacon reports from the same count)
const DOM_LARGE = 1500HOLE_SEG_LABEL
const
const HOLE_SEG_LABEL: Record<HoleSegKind, string>TESTING_COOKIE
const
LEAN TESTING: og_testing=lean (or ?og-testing=lean) beside the devtools switch — the testing API
(window.__ogygia_testing) works in full, and nothing else of devtools runs: no launcher, no dock, no
watcher of the page's timers, no server event side-channel in the HTML. The page loads what it loads
with devtools off, plus the testing engine when a test first asks. An engine that does not know the
cookie ignores it.
const TESTING_COOKIE = "og_testing"TESTING_ENGINE_VERSION
const
The report shape the page's testing engine answers (window.__ogygia_testing.version). The engine
ships with the SITE's build and @ogygia/testing with the TEST's package, so the two can differ: the
test side reads this from the page, fills in what it can for an older engine, and warns once.
Each version, and what it DETECTS differently (results across two versions compare only where nothing below changed):
1 — 0.8.2.
2 — hydration key, session navigations (with what started each), finding names, counts.cls, engine on every report, hydration t0 / done. Detection: a router navigation that never
swapped the page no longer starts a new page for page(). Hydration status: unchanged from 1 (an
island that reads clean on one and changed on the other differed in that run — input landing
while it hydrated is the usual cause; 3 flags it as input).
3 — hydration change (attributes / markup), attributes, input, ignoreAttributes; page ogygia (what measuring cost). Detection: unchanged — changed means what it meant in 2; the new
fields only say what kind of change it was.
const TESTING_ENGINE_VERSION = 3TESTING_LEAN
const
const TESTING_LEAN = "lean"TESTING_PARAM
const
const TESTING_PARAM = "og-testing"AssetRef
interface
interface AssetRef {/*…*/}AssetRef.url
url: string;AssetRef.kind
kind: AssetKind;AssetRef.blocking
the browser must have it before the first paint (a head stylesheet, a classic sync script)
blocking: boolean;AssetRef.via
how the document asks for it (island: the runtime loads it to wake an island)
via: "script" | "modulepreload" | "preload" | "stylesheet" | "inline-import" | "img" | "static-import" | "island" | "route-node" | "runtime-phase";AssetRef.lazy
loads later, on demand (an island that wakes when visible / on interaction), not at start
lazy?: boolean;AssetRef.runtime
the ogygia runtime's own script (data-ogygia-runtime): the parts it loads itself are its own
runtime?: true;AssetRef.phase
a part of the ogygia runtime it loads on demand as islands wake (and what that part imports)
phase?: true;AssetsDiff
interface
interface AssetsDiff {/*…*/}AssetsDiff.js
JS at start, decoded, then → now
js: {
a: number;
b: number;
};AssetsDiff.lazy_js
lazy_js: {
a: number;
b: number;
};AssetsDiff.added
added: AssetChange[];AssetsDiff.removed
removed: AssetChange[];AssetsDiff.grew
grew: AssetChange[];AssetsDiff.shrank
shrank: AssetChange[];AssetsDiff.to_start
the same file, now loaded at start (it loaded later before: an island's wake changed)
to_start: AssetChange[];AssetsDiff.to_later
the same file, now loaded later (it loaded at start before)
to_later: AssetChange[];AttrRule
interface
interface AttrRule {/*…*/}AttrRule.tag
tag?: Pat;AttrRule.name
name: Pat;AttrRule.value
value?: Pat;CpuFn
interface
interface CpuFn {/*…*/}CpuFn.name
name: string;CpuFn.file
file: string;CpuFn.line
line: number | null;CpuFn.kind
kind: CodeKind;CpuFn.self_ms
self_ms: number;CpuFn.total_ms
total_ms: number;CpuSummary
interface
interface CpuSummary {/*…*/}CpuSummary.window_ms
sampled span (first to last sample)
window_ms: number;CpuSummary.busy_ms
busy_ms: number;CpuSummary.by_kind
by_kind: {
kind: CodeKind;
ms: number;
}[];CpuSummary.fns
fns: CpuFn[];CpuSummary.files
files: {
file: string;
kind: CodeKind;
ms: number;
}[];CpuSummary.islands
per island fingerprint: CPU inside its hydrate window and the functions that took it
islands: Record<string, {
ms: number;
top: CpuFn[];
}>;CpuSummary.outside
long tasks outside every island's hydrate window
outside: {
ms: number;
top: CpuFn[];
};CpuSummary.interval_ms
the sampling interval seen (ms)
interval_ms: number;CpuSummary.by_host
main-thread ms per other origin (the nearest frame with a script URL decides)
by_host?: Record<string, number>;Failure
interface
interface Failure {/*…*/}Failure.fp
fp?: string;Failure.message
message: string;Failure.span
its wake → the failure (page clock): the island was loading, and held its turn, meanwhile
span?: [number, number];Failure.turn
when its hydrate step began (page clock): from here to the failure it held the thread, as a hydrating island does
turn?: number;FpDrift
interface
interface FpDrift {/*…*/}FpDrift.entry
entry: string;FpDrift.fp_was
fp_was: string;FpDrift.fp_now
fp_now: string;FpDrift.path
the first differing path in the props (stamp, items[2].id), when the props parse
path?: string;FpDrift.was
the values there, clipped (or the text around the first difference)
was?: string;FpDrift.now
now?: string;HeldOpen
interface
interface HeldOpen {/*…*/}HeldOpen.side
side: "server" | "browser";HeldOpen.keys
keys: {
key: string | null;
at: number;
}[];HeldOpen.early_ms
server side: the early part's last byte left at early_ms, the tail's (late_bytes) at late_ms
early_ms?: number;HeldOpen.early_bytes
early_bytes?: number;HeldOpen.late_ms
late_ms?: number;HeldOpen.late_bytes
late_bytes?: number;HeldOpen.islands
server side: the islands the page renders (the finding needs some to be about)
islands?: number;HoleBatch
interface
A batch request (runtime/frame-nav.ts) that carried fewer holes than it was sent for: the rest fetched on their own right after it.
interface HoleBatch {/*…*/}HoleBatch.sent
sent: number;HoleBatch.delivered
delivered: number;HoleBatch.status
the response's status (0: the request failed)
status: number;HoleBatch.refused
refused?: "redirected" | "document";HoleBatch.final_url
final_url?: string;HoleBatch.names
the holes it was for (names)
names: string[];HoleFailure
interface
interface HoleFailure {/*…*/}HoleFailure.fp
fp?: string;HoleFailure.name
name: string;HoleFailure.endpoint
endpoint?: string;HoleFailure.reason
reason: RegionRefusal | "error";HoleFailure.final_url
final_url?: string;HoleFailure.message
message?: string;HoleFailure.attempts
attempts: number;HoleWait
interface
interface HoleWait {/*…*/}HoleWait.name
name: string;HoleWait.wait_ms
ms from the hole's fetch start to its answer's swap
wait_ms: number;HoleWait.below_fold
below the first screen (its fallback is not what the visitor looks at first)
below_fold: boolean;HoleWait.server_ms
its server render, per request, when known (the profiler recorded the hole's requests, or the answer's Server-Timing said)
server_ms?: number;HoleWait.server_queue_ms
its wait on the server for a render slot, before the render (Server-Timing / the profiler)
server_queue_ms?: number;HoleWait.endpoint
the hole's endpoint (the devtools find its element by it: a hole has no fingerprint)
endpoint?: string;HoleWait.shown_at
page times: when the fallback began to count (the paint, or the hole's own start), and its request as the browser timed it — left, first byte back, last byte. They split the wait.
shown_at?: number;HoleWait.left_at
left_at?: number;HoleWait.first_at
first_at?: number;HoleWait.end_at
end_at?: number;HoleWait.batch_size
it came in ONE batch request with the holes that started with it: how many (its own part
landed when the server rendered it — first_at is that, out of order). No browser gate held it.
batch_size?: number;HtmlDiff
interface
interface HtmlDiff {/*…*/}HtmlDiff.hunks
hunks: DiffHunk[];HtmlDiff.removed
tokens removed / added
removed: number;HtmlDiff.added
added: number;HtmlDiff.partial
the diff gave up (too many changes) and shows only where they start
partial: boolean;InteractionCpuInput
interface
interface InteractionCpuInput {/*…*/}InteractionCpuInput.t
t: number;InteractionCpuInput.mapped
the frames' lines are the source's (mapped through a source map): else a line is the served code's, and only the function and its file are quoted
mapped?: boolean;InteractionCpuInput.wait
wait: {
ms: number;
top: CpuFn[];
} | null;InteractionCpuInput.handler
handler: {
ms: number;
top: CpuFn[];
} | null;IslandCode
interface
interface IslandCode {/*…*/}IslandCode.fp
fp?: string;IslandCode.name
name: string;IslandCode.bytes
the island's app code, served size in dev
bytes: number;IslandCode.top
its heaviest modules
top: {
file: string;
bytes: number;
}[];IslandCode.barrels
re-export barrels still imported whole, with the app modules each drags in
barrels: {
file: string;
fanout: number;
}[];IslandCode.hazards
its components' lines that draw differently in the browser (the dev server read their sources)
hazards?: IslandHazard[];IslandRow
interface
interface IslandRow {/*…*/}IslandRow.fp
fp: string;IslandRow.name
name: string;IslandRow.wake
wake: string;IslandRow.load_ms
wake began → module + hydrate core loaded
load_ms: number;IslandRow.queue_ms
loaded → its scheduler turn (the queue behind other islands, and the DCL/paint gate)
queue_ms: number | null;IslandRow.hydrate_ms
the synchronous hydrate step
hydrate_ms: number;IslandRow.t0
t0: number;IslandRow.done
done: number;IslandRow.recovered
recovered: boolean;IslandRow.changed
changed: boolean;IslandRow.shift
layout shift (summed) this island caused within a moment of hydrating
shift: number;IslandRow.longtask_ms
long-task ms that overlapped its hydration window
longtask_ms: number;IslandRow.early_ms
the first interaction reached it before it was awake (ms early), when it did
early_ms: number | null;IslandRow.below_fold
below_fold: boolean;IslandRow.cpu_ms
main-thread CPU sampled inside its hydrate window (null: no trace)
cpu_ms: number | null;KeptIsland
interface
One island as one load (or render) had it.
interface KeptIsland {/*…*/}KeptIsland.entry
entry: string;KeptIsland.fp
fp: string;KeptIsland.props
props?: string;NavPhases
interface
The document's steps before its first byte (ms).
interface NavPhases {/*…*/}NavPhases.redirect
redirect?: number;NavPhases.worker
worker?: number;NavPhases.dns
dns?: number;NavPhases.connect
connect?: number;NavPhases.tls
tls?: number;NavPhases.wait
the request until the server's first byte
wait?: number;PageAssets
interface
interface PageAssets {/*…*/}PageAssets.assets
assets: WeighedAsset[];PageAssets.unscoped
components whose styles shipped WITHOUT their scope (the build's fallback marker, in a
stylesheet or an inline <style>): their rules apply to the whole page
unscoped?: (UnscopedStyles & {
in: string;
})[];PageAssets.missed
references that could not be weighed (a 404, a timeout, the budget ran out)
missed: string[];PageAssets.missed_why
each of those, and why: budget (time ran out before it), timeout, status 404, file cap, error: … — a total with only status misses can be trusted; budget / timeout ones vary
missed_why?: {
url: string;
why: string;
}[];PageAssets.html
the HTML itself
html: {
bytes: number;
wire: number;
};PageAssets.inline
inline <script> / <style> text in the document, decoded bytes
inline: {
script: number;
style: number;
};PageAssets.totals
totals: {
js: number;
js_wire: number;
css: number;
css_wire: number;
font: number;
image: number;
wire: number;
lazy_js: number;
blocking: number;
blocking_count: number;
js_files: number;
};PageFinding
interface
interface PageFinding {/*…*/}PageFinding.code
code: string;PageFinding.severity
severity: Severity;PageFinding.message
message: string;PageFinding.fix
fix?: string;PageFinding.fps
the islands it is about (to light up on the page)
fps: string[];PageFinding.dev_compile
it is the dev server's own doing: its first compile of the page (a slow first byte while the page compiled on its first request), or the CSS it adds with JavaScript moving the page (a shift). A reload reads it differently: "since your last load" never calls it new or fixed
dev_compile?: true;PageInput
interface
interface PageInput {/*…*/}PageInput.dev
measured on the dev server (it compiles a page on its first request: a slow first byte there is not the app's)
dev?: boolean;PageInput.server_profiles
DEVTOOLS ONLY (the profiler's report is itself a profile): the profiler's last run of this page, and of the pages it navigated to by path. Present (even empty) means: say what the server did, or how to find out
server_profiles?: Record<string, ServerProfileBrief>;PageInput.server_profile
server_profile?: ServerProfileBrief;PageInput.interaction_cpu
the slowest interaction's CPU, when a trace of it was taken
interaction_cpu?: InteractionCpuInput;PageInput.held_open
what held the document open: its streamed promises by page.data key — when each settled
(side 'server': left the server, ms into the render, from the profiled render's chunks;
'browser': arrived, ms from the navigation, stamped by the resolve global)
held_open?: HeldOpen;PageInput.vitals
vitals: {
ttfb?: number;
fcp?: number;
lcp?: number;
cls?: number;
inp?: number;
};PageInput.visit
visit: {
nav?: {
dcl?: number;
load?: number;
res_start?: number;
start_hidden?: true;
res_end?: number;
size?: number;
raw?: true;
dom_interactive?: number;
phases?: NavPhases;
server_timing?: {
name: string;
ms: number;
desc?: string;
}[];
};
scripts?: {
url: string;
ms: number;
count: number;
}[];
warnings?: {
code: string;
message: string;
file?: string;
fp?: string;
t?: number;
}[];
paints?: {
fcp?: number;
lcp?: number;
lcp_fp?: string;
lcp_tag?: string;
lcp_url?: string;
lcp_replaced?: true;
lcp_lazy?: true;
lcp_priority?: "high" | "low";
held?: {
outcome: "arrived" | "input" | "cap" | "none";
resources: number;
waited_ms: number;
};
};
resources?: {
url: string;
type: string;
start: number;
end: number;
req_start?: number;
res_start?: number;
transfer?: number;
size?: number;
blocking?: boolean;
weighed?: true;
}[];
resource_totals?: {
type: string;
count: number;
transfer: number;
size: number;
}[];
viewport?: [number, number];
origin?: string;
named?: string[];
in_page?: string[];
preload_misses?: PreloadMiss[];
preloads_unused?: {
url: string;
as: string;
bytes: number;
}[];
uncompressed?: {
url: string;
type: string;
bytes: number;
}[];
font_faces?: {
family: string;
display: string;
urls: string[];
}[];
images_oversized?: {
url: string;
natural: [number, number];
shown: [number, number];
dpr: number;
bytes: number;
fp?: string;
}[];
scroll_jank?: {
start: number;
ms: number;
scripts: {
url: string;
fn: string;
invoker: string;
ms: number;
island?: string;
}[];
}[];
forced_layout?: {
start: number;
end: number;
ms: number;
url: string;
fn: string;
}[];
images_eager_below?: {
url: string;
top: number;
bytes: number;
fp?: string;
}[];
images_unsized?: string[];
dom?: {
nodes: number;
depth: number;
deepest: string;
widest: {
at: string;
children: number;
};
islands: {
fp: string;
nodes: number;
}[];
};
entry_fallbacks?: {
entry: string;
src: string;
recovered: boolean;
name?: string;
}[];
refetched?: {
url: string;
how: "revalidated" | "downloaded";
bytes: number;
ms: number;
entry?: string;
runtime?: boolean;
name?: string;
}[];
interaction?: PageInteraction;
navs?: PageNav[];
} | null;PageInput.islands
islands: PageIsland[];PageInput.firsts
firsts: {
fp: string;
t: number;
type: string;
}[];PageInput.shifts
shifts: {
t: number;
value: number;
fp?: string;
tag?: string;
}[];PageInput.longtasks
longtasks: {
t: number;
ms: number;
}[];PageInput.longtasks_from
frames: the browser has no long-task timing — these are frames drawn more than 50 ms late
longtasks_from?: "frames";PageInput.shifts_from
boxes: the browser has no layout-shift timing — the shifts are islands whose box changed as
they woke, scored the way a layout shift is (an estimate)
shifts_from?: "boxes";PageInput.snapshots
(from: a big island's window — where it starts in the markup without comments)
snapshots?: {
fp: string;
ssr: string;
hydrated: string;
final?: string;
from?: number;
}[];PageInput.empty_slots
awake islands showing a children slot with nothing in it (read off the DOM; devtools only)
empty_slots?: string[];PageInput.hole_failures
holes whose answer never came (the bus; devtools only)
hole_failures?: HoleFailure[];PageInput.island_code
each island's app code in dev (the dev server's module graph; devtools only)
island_code?: IslandCode[];PageInput.hole_waits
how long each hole's fallback showed before its answer (the bus; devtools only)
hole_waits?: HoleWait[];PageInput.hole_batches
batch requests that did not carry all their holes (the bus; devtools only)
hole_batches?: HoleBatch[];PageInput.restore_events
what the restorer of a server transform reported (runtime/restore.ts __og_restore_log)
restore_events?: RestoreEvent[];PageInput.fp_drift
islands whose fingerprint moved between two loads of this page (fp-drift.ts)
fp_drift?: {
name: string;
fp?: string;
path?: string;
was?: string;
now?: string;
}[];PageInput.prebundled
the dev server's pre-bundled packages (its .vite/deps/_metadata.json), read when the page
loaded one: a package also served raw from its folder runs as two copies
prebundled?: string[];PageInput.browser
the browser the page ran in (browser_of its user agent: Safari 26, Chrome 141)
browser?: string;PageInput.dock_open_at
when the devtools' own dock began to show as the page loaded (open, remembered from the last page), page clock; absent when it was opened later or not at all
dock_open_at?: number;PageInput.leftovers
what islands that left the page left running (devtools/leftovers.ts; devtools only)
leftovers?: {
name: string;
intervals: number;
listeners: string[];
fires: number;
last_ago?: number;
}[];PageInput.scroll_blockers
wheel / touch listeners still attached that hold scrolling (not passive), by the island (or the file) that added each (devtools/leftovers.ts; devtools only)
scroll_blockers?: {
owner: string;
type: string;
on: string;
forced: boolean;
}[];PageInput.bfcache
what keeps the page out of the back/forward cache: who added a window unload listener, and
the browser's own reasons when this load came from Back and was not restored (devtools only)
bfcache?: {
unload: string[];
not_restored?: string[];
};PageInteraction
interface
interface PageInteraction {/*…*/}PageInteraction.name
name: string;PageInteraction.t
t: number;PageInteraction.ms
ms: number;PageInteraction.delay
input → its handlers began (the main thread was busy)
delay: number;PageInteraction.processing
the handlers
processing: number;PageInteraction.presentation
handlers done → the next frame painted
presentation: number;PageInteraction.target
target: string;PageInteraction.fp
fp?: string;PageInteraction.scripts
(forced: of a script's time, the browser laying the page out because it read sizes after a change)
scripts?: {
url: string;
fn: string;
invoker: string;
ms: number;
phase: "delay" | "handler" | "paint";
island?: string;
forced?: number;
}[];PageNav
interface
One in-app navigation (the router's body swap), on the page's clock.
interface PageNav {/*…*/}PageNav.from
from: string;PageNav.to
to: string;PageNav.type
type: string;PageNav.t
t: number;PageNav.fetched
the new page's HTML arrived
fetched: number;PageNav.styled
its stylesheets were in
styled: number;PageNav.swapped
the swap committed: the new page shows
swapped: number;PageNav.server
the fetch split, from the page request's timing: the wait for the first byte, the download
server?: number;PageNav.download
download?: number;PageNav.bytes
bytes?: number;PageNav.prefetched
the request began before the click (a hover prefetch)
prefetched?: boolean;PageNav.on_server
the page request on the server (the profiler's request log): its ms, the CPU it burned, its outbound calls — what the server did with the wait
on_server?: {
ms: number;
cpu_ms: number;
net_ms: number;
net_count: number;
inflight?: number;
};PageReport
interface
interface PageReport {/*…*/}PageReport.vitals
vitals: RatedVital[];PageReport.rows
rows: IslandRow[];PageReport.findings
findings: PageFinding[];PageReport.blocking
blocking resources before first paint, slowest first
blocking: {
url: string;
ms: number;
bytes: number;
}[];PageReport.bytes
bytes: {
type: string;
count: number;
transfer: number;
size: number;
}[];PageReport.longtask_ms
longtask_ms: number;PageReport.third_party
other origins on this page (null: none, or no origin to tell them by)
third_party: ThirdParty | null;RatedVital
interface
interface RatedVital {/*…*/}RatedVital.key
key: "ttfb" | "fcp" | "lcp" | "cls" | "inp";RatedVital.label
label: string;RatedVital.value
value: number;RatedVital.rating
rating: Rating;RegionFact
interface
A region on the page, as the tab read it off the DOM. top is document-relative (px).
interface RegionFact {/*…*/}RegionFact.fp
fp: string;RegionFact.name
name: string;RegionFact.kind
kind: "island" | "lake" | "hole";RegionFact.wake
wake: string;RegionFact.hydrated
hydrated: boolean;RegionFact.top
top?: number;RegionFact.height
height?: number;RegionFact.own_bytes
the wire bytes only this island loads (a build's island graph × the browser's sizes)
own_bytes?: number;RegionFact.hidden
it draws nothing on this screen: no box of its own nor a child's (hidden by its CSS, or empty)
RegionFact.shows_at
the media query under which the page's CSS shows it (read off the sheets), when one does
shows_at?: string;RegionFact.headless
it never draws: no text, only hidden marker elements — an island there for its effects
headless?: true;RestoreEvent
interface
A restored host that went wrong: upgraded by its component before the restore reached it
(late), or restored to markup that does not match Svelte's (mismatch, the dev check).
interface RestoreEvent {/*…*/}RestoreEvent.kind
kind: "late" | "mismatch";RestoreEvent.host
the host's tag
host: string;RestoreEvent.t
page time
t: number;RestoreEvent.diff
the first difference (mismatch)
diff?: string;RestoreEvent.island
the island holding it, when one does
island?: string;RuntimeScripts
interface
interface RuntimeScripts {/*…*/}RuntimeScripts.files
files: number;RuntimeScripts.bytes
decoded
bytes: number;RuntimeScripts.wire
on the wire (a third of decoded where the browser saw none: a cached file)
wire: number;RuntimeScripts.by
by who serves them: this app, or a CDN package / host
by: {
who: string;
files: number;
bytes: number;
}[];RuntimeScripts.island_entries
of this app's, the island entry files (og-region.<id>.…js): islands no HTML named — the ones
a hole's answer brought
island_entries?: number;ServerProfileBrief
interface
THE PROFILER'S LAST RUN OF A PAGE, in brief (devtools: the dock's profile store, shared with the Profiler tab) — what the server did when it rendered that page
interface ServerProfileBrief {/*…*/}ServerProfileBrief.ago_min
minutes since the run
ago_min: number;ServerProfileBrief.render_ms
render_ms: number;ServerProfileBrief.top
its top cost, in its own words (the report's first warning, else its heaviest component)
top: string | null;ServerProfileBrief.calls
calls: number;ServerProfileBrief.calls_ms
calls_ms: number;ServerProfileBrief.no_store
the Cache-Control it saw the page answer, when that keeps the page out of the back/forward cache (no-store): the server's own answer, which the browser cannot read
no_store?: string;ServerProfileBrief.prerendered
the page is prerendered: 'file' (the build's file answered, no render), 'route' (its route prerenders)
prerendered?: "file" | "route";SessionClick
interface
interface SessionClick {/*…*/}SessionClick.t
t: number;SessionClick.target
target: string;SessionClick.fp
fp: string | null;SessionClick.el
el: WeakRef<Element> | null;SessionClick.clickable
it looked like it does something (a control, a link, a clickable role, a pointer cursor): a click on text or a blank stretch that changes nothing is no dead click
clickable?: true;SessionData
interface
interface SessionData {/*…*/}SessionData.from
from: number;SessionData.to
to: number;SessionData.interactions
interactions: SessionInteraction[];SessionData.longtasks
longtasks: {
t: number;
ms: number;
}[];SessionData.frames
frames: SessionFrame[];SessionData.shifts
shifts: SessionShift[];SessionData.requests
requests: SessionRequest[];SessionData.mutations
mutations: {
fp: string | null;
count: number;
el: WeakRef<Element> | null;
}[];SessionData.mut_log
when the DOM changed, and where (one stamp per island per batch of changes)
mut_log: {
t: number;
fp: string | null;
}[];SessionData.clicks
every click, fast ones too
clicks: SessionClick[];SessionData.errors
errors: {
t: number;
message: string;
}[];SessionData.navs
navigations as they started, with what started them (absent in a part saved before this field)
navs?: SessionNav[];SessionData.heap
heap: {
from: number;
to: number;
} | null;SessionData.events
events: DevtoolsEvent[];SessionData.cpu
cpu: unknown | null;SessionData.cpu_off
cpu_off: string | null;SessionData.page
page: string;SessionData.pages
the documents the session crossed (a full page load mid-session), each with when it began
pages: {
url: string;
t: number;
}[];SessionData.names
island fingerprint → component name, taken on each page (its islands are gone after it)
names: Record<string, string>;SessionFinding
interface
interface SessionFinding {/*…*/}SessionFinding.code
code: string;SessionFinding.severity
severity: "error" | "warn" | "info";SessionFinding.message
message: string;SessionFinding.fix
fix?: string;SessionFinding.refs
refs: Ref[];SessionFinding.url
a same-origin GET the tab can profile on the server in one click (server-time findings)
url?: string;SessionFrame
interface
interface SessionFrame {/*…*/}SessionFrame.t
t: number;SessionFrame.ms
ms: number;SessionFrame.blocking
blocking: number;SessionFrame.scripts
scripts: {
source: string;
fn: string;
invoker: string;
ms: number;
}[];SessionInteraction
interface
interface SessionInteraction {/*…*/}SessionInteraction.t
t: number;SessionInteraction.name
name: string;SessionInteraction.duration
duration: number;SessionInteraction.input_delay
input_delay: number;SessionInteraction.processing
processing: number;SessionInteraction.presentation
presentation: number;SessionInteraction.id
id: number;SessionInteraction.target
target: string;SessionInteraction.fp
fp: string | null;SessionInteraction.el
el: WeakRef<Element> | null;SessionNav
interface
A navigation as it started: where to, when, and the element that started it (the link or form, or the input being handled then) with its island.
interface SessionNav {/*…*/}SessionNav.url
url: string;SessionNav.t
t: number;SessionNav.type
type: string;SessionNav.source
source: string | null;SessionNav.fp
fp: string | null;SessionReport
interface
interface SessionReport {/*…*/}SessionReport.duration_ms
duration_ms: number;SessionReport.counts
shifts and cls: the layout moving with no input (the shifts the session's CLS counts)
counts: {
interactions: number;
slow: number;
longtasks: number;
longtask_ms: number;
requests: number;
request_bytes: number;
errors: number;
shifts: number;
cls: number;
mutations: number;
pages: number;
};SessionReport.findings
findings: SessionFinding[];SessionReport.interactions
the slowest interactions, for the timeline
interactions: {
i: number;
t: number;
name: string;
duration: number;
target: string;
fp: string | null;
}[];SessionReport.by_island
each island's part: clicks, slow interactions, the requests its clicks caused (server split)
by_island: Record<string, IslandSession>;SessionReport.requests
the slowest requests, with the server's own split when it sent one
requests: {
url: string;
ms: number;
status: number | null;
server_ms: number | null;
cpu_ms: number | null;
net_ms: number | null;
up: string | null;
}[];SessionReport.failed
every request that answered an error status (type: the browser's initiator type)
failed: {
url: string;
status: number;
type: string;
t: number;
}[];SessionReport.by_element
the slowest interaction on each element the session touched, however quick (0: a click the browser did not time, under its 16 ms floor)
by_element: {
target: string;
duration: number;
processing: number;
t: number;
fp: string | null;
}[];SessionReport.cpu
cpu: CpuSummary | null;SessionRequest
interface
interface SessionRequest {/*…*/}SessionRequest.url
url: string;SessionRequest.type
type: string;SessionRequest.t
t: number;SessionRequest.ms
ms: number;SessionRequest.bytes
bytes: number;SessionRequest.status
status: number | null;SessionRequest.server
the server's own account (Server-Timing: ogygia's profiler sends ssr / cpu / net / up1-3)
server?: {
name: string;
ms: number;
desc: string;
}[];SessionShift
interface
interface SessionShift {/*…*/}SessionShift.t
t: number;SessionShift.value
value: number;SessionShift.input
input: boolean;SessionShift.fp
fp: string | null;SessionShift.el
el: WeakRef<Element> | null;TimelineItem
interface
One item on the session's one-clock timeline (ms from the session start).
interface TimelineItem {/*…*/}TimelineItem.t0
t0: number;TimelineItem.t1
t1: number;TimelineItem.label
label: string;TimelineItem.tone
tone: "ok" | "warn" | "bad" | "info";TimelineItem.server
a request: the server's part and, inside it, the upstream wait (ms)
server?: {
ms: number;
up: number;
};TimelineItem.ref
ref?: Ref;TimelineLane
interface
interface TimelineLane {/*…*/}TimelineLane.key
key: "input" | "main" | "net" | "islands" | "layout" | "errors";TimelineLane.label
label: string;TimelineLane.items
items: TimelineItem[];VitalMove
interface
interface VitalMove {/*…*/}VitalMove.key
key: "ttfb" | "fcp" | "lcp" | "cls" | "inp";VitalMove.a
a: number;VitalMove.b
b: number;VitalMove.part
the part of a split vital that moved most (≥ 50 ms, else left out)
part?: {
label: string;
a: number;
b: number;
};VitalPart
interface
interface VitalPart {/*…*/}VitalPart.key
key: string;VitalPart.label
label: string;VitalPart.ms
ms: number;Weight
interface
interface Weight {/*…*/}Weight.bytes
bytes: number;Weight.wire
wire: number;Weight.imports
a module's static imports (resolved to absolute paths), for the walk
imports?: string[];Weight.dynamic
its dynamic imports (resolved) — followed only where the page names them (Kit's route nodes)
dynamic?: string[];Weight.unscoped
a stylesheet's unscoped fallbacks (see unscoped-css.ts)
unscoped?: UnscopedStyles[];Weight.vary
a font's Vary header (Safari refetches a font preload that varies by Origin when its
vary?: string;AssetKind
type
type AssetKind = "script" | "style" | "font" | "image" | "other";CodeKind
type
type CodeKind = "app" | "ogygia" | "svelte" | "dependency" | "page script" | "browser" | "devtools";HydrationStatus
type
An island's hydration status: worked out in the browser (devtools/hydration.ts), read by the testing API.
type HydrationStatus = "failed" | "recovered" | "healed" | "changed" | "asleep" | "clean";IslandHazard
type
a hazard with the file it is in (the profiler's island chunks, the dev server's module graph)
type IslandHazard = Hazard & {
file: string;
};PartedVital
type
A VITAL'S PARTS, as numbers (the same splits the explanations word): TTFB by its steps, FCP by first byte / HTML / blocking / render, LCP by first byte / delay / download / render, INP by the slowest interaction's wait / handlers / paint. What "since your last profile" (the profiler) and "since your last load" (the Page tab) compare, to say which part of a moved vital moved. Null when the visit cannot tell.
type PartedVital = "ttfb" | "fcp" | "lcp" | "inp";Ref
type
type Ref = {
kind: "interaction";
i: number;
} | {
kind: "click";
i: number;
} | {
kind: "shift";
i: number;
} | {
kind: "island";
fp: string;
};