Guide

Prefer profile mode for any gate you care about.

Initialize

FrameGuard.initialize(
  config: FrameGuardConfig(
    samplingMode: SamplingMode.balanced,
    defaultBudget: BudgetProfile.midRange60().budget,
  ),
);
runApp(const FrameGuardScope(child: MyApp()));

Capture a session

final report = await FrameGuard.runSession(
  name: 'catalog_scroll',
  body: () async { await scrollCatalog(); },
);
await report.writeJson(File('reports/catalog.json'));
await report.writeHtml(File('reports/catalog.html'));
await report.writeMarkdown(File('reports/catalog.md'));

Assert in tests

import 'package:frameguard/frameguard_test.dart';

final report = await FrameGuardTest.measure(
  tester,
  name: 'catalog',
  action: () async {
    await tester.fling(find.byType(ListView), const Offset(0, -800), 1000);
    await tester.pumpAndSettle();
  },
);
expect(report, meetsFrameBudget(BudgetProfile.midRange60().budget));

Scaffold a project

dart run frameguard init

Creates frameguard.yaml, reports/, and baselines/ when missing.

Baselines

dart run frameguard baseline update reports/catalog.json --out baselines/catalog.json
dart run frameguard check reports/catalog.json --baseline baselines/catalog.json

Package docs also live in the repo under doc/ (API cookbook, CI, scenarios).