PdfPerfLog class
Lightweight, frame-gated performance log for diagnosing scroll/render hangs on heavy documents.
Off by default. Enable at launch with --dart-define=PDF_PERF_LOG=true,
or flip enabled at runtime (e.g. from the example app). When enabled it
prints:
- every UI-thread interpret with its page index, path (recorded vs plain), and split (interpret/raster) milliseconds - a long interpret while you scroll IS the hang,
- render-scheduler grants and render-hold on/off transitions,
- background prerender warms,
- scroll velocity, and
- frame JANK (build or raster over the 16ms budget).
Each line prints immediately (synchronously, so a hang - which produces
no frames - can't swallow the lines that diagnose it); frame JANK is
appended from SchedulerBinding's timings callback. Printing is
debugPrintSynchronously, never a Timer, so it cannot trip widget
tests' !timersPending invariant (and it stays off there anyway: the
dart-define defaults false and tests never set it).
Enable on the live web demo without a rebuild by appending ?perf=1 to
the URL, then read the [perf …] lines in the browser console.
Properties
- hashCode → int
-
The hash code for this object.
no setterinherited
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
Methods
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited
Static Properties
- buildTag ↔ String
-
Identifies the build a trace came from - set by the host at startup, e.g.
commit=<sha>from a--dart-define. Emitted as the first line whenever the log turns on, however it was turned on (URL flag, devtools toggle, or dart-define). Empty means the host did not supply one, which is reported honestly as no line rather than as a guess.getter/setter pair - enabled ↔ bool
-
Master switch. Defaults to the
PDF_PERF_LOGdart-define so it is inert unless explicitly turned on for a diagnostic run.getter/setter pair - sink ↔ void Function(String line)?
-
Optional host sink that receives every flushed line IN ADDITION to the
console. This is the seam by which a host app (whose devtools export
must never depend on a console the user can't reach) mirrors the trace
into its own log - the package must not import the host, so the host
hands us a closure instead. Not consulted at all while the log is off.
getter/setter pair
Static Methods
-
interpret(
int page, {required String path, required double interpretMs, double? progressiveMs, double? waitMs, double? buildMs, double? decodeMs, double? replayMs, double? textShapeMs, int? textShapeMiss, int? textShapeHit, double? rasterMs, bool first = true, String note = ''}) → void -
Logs a UI-thread interpret.
firstmarks a page's first-ever interpret (the expensive content-stream walk), vs a cheap re-raster. -
log(
String message) → void - Records a line (cheap; the no-op path is a single bool check).
-
raster(
String kind, {required int page, required int imageWidth, required int imageHeight, double? ratio, double? elapsedMs, int? concurrency, ({double height, double width})? region}) → void -
Logs one raster allocation, the number that matters when diagnosing a
native-memory (GPU/Impeller) climb the Dart-side cache clears can't touch:
each line carries the raster's output size in megapixels, a monotonic
sequence number (so a per-frame loop is obvious -
nracing up), and the process RSS after the allocation (so the climb toward the OS high-water limit is visible against the same timeline as the JANK/vector-firstlines). Read in the DevTools console (the[perf … raster …]lines) or in an exported trace. -
rssSuffix(
) → String -
rss=NNNMBfor the current process, or''where RSS is unavailable (web) - a suffix any log line can append so the memory climb shows on the same timeline.