writePerformanceLog function

Future<String> writePerformanceLog({
  1. required TestLogger logger,
  2. required String filePrefix,
  3. required String name,
  4. required List<AppFrameTimingEntry> frames,
  5. List<PerformanceMarker> markers = const [],
  6. List<APICallRecord> apiCalls = const [],
})

Implementation

Future<String> writePerformanceLog({
  required TestLogger logger,
  required String filePrefix,
  required String name,
  required List<AppFrameTimingEntry> frames,
  List<PerformanceMarker> markers = const [],
  List<APICallRecord> apiCalls = const [],
}) {
  final jankyFrames = frames.where((frame) => frame.isJanky).length;
  final attributedFrames = frames
      .map((frame) => _AttributedFrame(frame, _markerForFrame(frame, markers)))
      .toList(growable: false);
  final slowestFrames = attributedFrames.toList()
    ..sort((a, b) => b.frame.totalSpanMs.compareTo(a.frame.totalSpanMs));
  final worstSteps = _worstSteps(attributedFrames);
  final worstScreens = _worstScreens(attributedFrames);
  final jankClusters = _jankClusters(attributedFrames);
  final apiCorrelation = _apiCorrelation(attributedFrames, apiCalls);
  final content = const JsonEncoder.withIndent('  ').convert({
    'testId': filePrefix.isEmpty ? 'suite' : filePrefix,
    'frameBudgetMs': AppFrameTimingEntry.frameBudgetMs,
    'summary': {
      'totalFrames': frames.length,
      'jankyFrames': jankyFrames,
      'jankyFrameRate': _ratio(jankyFrames, frames.length),
      'averageBuildMs': _average(frames.map((frame) => frame.buildMs)),
      'averageRasterMs': _average(frames.map((frame) => frame.rasterMs)),
      'averageTotalSpanMs': _average(frames.map((frame) => frame.totalSpanMs)),
      'maxBuildMs': _max(frames.map((frame) => frame.buildMs)),
      'maxRasterMs': _max(frames.map((frame) => frame.rasterMs)),
      'maxTotalSpanMs': _max(frames.map((frame) => frame.totalSpanMs)),
      if (worstSteps.isNotEmpty) 'worstStep': worstSteps.first['step'],
      if (worstScreens.isNotEmpty) 'worstScreen': worstScreens.first['screen'],
    },
    'totalFrames': frames.length,
    'jankyFrames': jankyFrames,
    'jankyFrameRate': _ratio(jankyFrames, frames.length),
    'averageBuildMs': _average(frames.map((frame) => frame.buildMs)),
    'averageRasterMs': _average(frames.map((frame) => frame.rasterMs)),
    'averageTotalSpanMs': _average(frames.map((frame) => frame.totalSpanMs)),
    'maxBuildMs': _max(frames.map((frame) => frame.buildMs)),
    'maxRasterMs': _max(frames.map((frame) => frame.rasterMs)),
    'maxTotalSpanMs': _max(frames.map((frame) => frame.totalSpanMs)),
    'worstSteps': worstSteps,
    'worstScreens': worstScreens,
    'jankClusters': jankClusters,
    'apiCorrelation': apiCorrelation,
    'slowestFrames':
        slowestFrames.take(10).map((frame) => frame.toJson()).toList(),
    'frames': attributedFrames.map((frame) => frame.toJson()).toList(),
  });

  return logger.writeLogFile(
    testId: filePrefix,
    name: name,
    content: content,
    extension: 'json',
  );
}