From e9be230a0618ed384a7c084935bc40d71b7e1eea Mon Sep 17 00:00:00 2001 From: Michael Goderbauer Date: Mon, 11 Mar 2019 13:16:13 -0700 Subject: [PATCH] Deprecate profile() (#29054) --- .../flutter/lib/src/foundation/isolates.dart | 6 ++-- .../flutter/lib/src/foundation/profile.dart | 12 +++++-- .../flutter/lib/src/rendering/object.dart | 32 +++++++++++++------ .../flutter/lib/src/scheduler/binding.dart | 8 ++--- packages/flutter/lib/src/widgets/binding.dart | 16 +++++----- .../flutter/test/foundation/profile_test.dart | 2 +- 6 files changed, 48 insertions(+), 28 deletions(-) diff --git a/packages/flutter/lib/src/foundation/isolates.dart b/packages/flutter/lib/src/foundation/isolates.dart index fd6ee57a2c..a7bd1a3d13 100644 --- a/packages/flutter/lib/src/foundation/isolates.dart +++ b/packages/flutter/lib/src/foundation/isolates.dart @@ -8,7 +8,7 @@ import 'dart:isolate'; import 'package:meta/meta.dart'; -import 'profile.dart'; +import 'constants.dart'; /// Signature for the callback passed to [compute]. /// @@ -45,7 +45,9 @@ typedef ComputeCallback = R Function(Q message); /// The `debugLabel` argument can be specified to provide a name to add to the /// [Timeline]. This is useful when profiling an application. Future compute(ComputeCallback callback, Q message, { String debugLabel }) async { - profile(() { debugLabel ??= callback.toString(); }); + if (!kReleaseMode) { + debugLabel ??= callback.toString(); + } final Flow flow = Flow.begin(); Timeline.startSync('$debugLabel: start', flow: flow); final ReceivePort resultPort = ReceivePort(); diff --git a/packages/flutter/lib/src/foundation/profile.dart b/packages/flutter/lib/src/foundation/profile.dart index 21b55716ac..d1d5ff2f4a 100644 --- a/packages/flutter/lib/src/foundation/profile.dart +++ b/packages/flutter/lib/src/foundation/profile.dart @@ -6,10 +6,16 @@ import 'dart:ui' show VoidCallback; import 'constants.dart'; -/// When running in profile mode (or debug mode), invoke the given function. +/// DEPRECATED. `function` cannot be treeshaken out of release builds. /// -/// In release mode, the function is not invoked. -// TODO(devoncarew): Going forward, we'll want the call to profile() to be tree-shaken out. +/// Instead use: +/// +/// ```dart +/// if (!kReleaseMode) { +/// function(); +/// } +/// ``` +@Deprecated('Use `if (!kReleaseMode) { function(); }` instead') void profile(VoidCallback function) { if (kReleaseMode) return; diff --git a/packages/flutter/lib/src/rendering/object.dart b/packages/flutter/lib/src/rendering/object.dart index d4a8655833..b490143860 100644 --- a/packages/flutter/lib/src/rendering/object.dart +++ b/packages/flutter/lib/src/rendering/object.dart @@ -749,9 +749,9 @@ class PipelineOwner { /// /// See [RendererBinding] for an example of how this function is used. void flushLayout() { - profile(() { + if (!kReleaseMode) { Timeline.startSync('Layout', arguments: timelineWhitelistArguments); - }); + } assert(() { _debugDoingLayout = true; return true; @@ -771,9 +771,9 @@ class PipelineOwner { _debugDoingLayout = false; return true; }()); - profile(() { + if (!kReleaseMode) { Timeline.finishSync(); - }); + } } } @@ -809,14 +809,18 @@ class PipelineOwner { /// Called as part of the rendering pipeline after [flushLayout] and before /// [flushPaint]. void flushCompositingBits() { - profile(() { Timeline.startSync('Compositing bits'); }); + if (!kReleaseMode) { + Timeline.startSync('Compositing bits'); + } _nodesNeedingCompositingBitsUpdate.sort((RenderObject a, RenderObject b) => a.depth - b.depth); for (RenderObject node in _nodesNeedingCompositingBitsUpdate) { if (node._needsCompositingBitsUpdate && node.owner == this) node._updateCompositingBits(); } _nodesNeedingCompositingBitsUpdate.clear(); - profile(() { Timeline.finishSync(); }); + if (!kReleaseMode) { + Timeline.finishSync(); + } } List _nodesNeedingPaint = []; @@ -837,7 +841,9 @@ class PipelineOwner { /// /// See [RendererBinding] for an example of how this function is used. void flushPaint() { - profile(() { Timeline.startSync('Paint', arguments: timelineWhitelistArguments); }); + if (!kReleaseMode) { + Timeline.startSync('Paint', arguments: timelineWhitelistArguments); + } assert(() { _debugDoingPaint = true; return true; @@ -862,7 +868,9 @@ class PipelineOwner { _debugDoingPaint = false; return true; }()); - profile(() { Timeline.finishSync(); }); + if (!kReleaseMode) { + Timeline.finishSync(); + } } } @@ -937,7 +945,9 @@ class PipelineOwner { void flushSemantics() { if (_semanticsOwner == null) return; - profile(() { Timeline.startSync('Semantics'); }); + if (!kReleaseMode) { + Timeline.startSync('Semantics'); + } assert(_semanticsOwner != null); assert(() { _debugDoingSemantics = true; return true; }()); try { @@ -952,7 +962,9 @@ class PipelineOwner { } finally { assert(_nodesNeedingSemantics.isEmpty); assert(() { _debugDoingSemantics = false; return true; }()); - profile(() { Timeline.finishSync(); }); + if (!kReleaseMode) { + Timeline.finishSync(); + } } } } diff --git a/packages/flutter/lib/src/scheduler/binding.dart b/packages/flutter/lib/src/scheduler/binding.dart index f33ba8601d..bee7c34d6b 100644 --- a/packages/flutter/lib/src/scheduler/binding.dart +++ b/packages/flutter/lib/src/scheduler/binding.dart @@ -890,11 +890,11 @@ mixin SchedulerBinding on BindingBase, ServicesBinding { if (rawTimeStamp != null) _lastRawTimeStamp = rawTimeStamp; - profile(() { + if (!kReleaseMode) { _profileFrameNumber += 1; _profileFrameStopwatch.reset(); _profileFrameStopwatch.start(); - }); + } assert(() { if (debugPrintBeginFrameBanner || debugPrintEndFrameBanner) { @@ -957,10 +957,10 @@ mixin SchedulerBinding on BindingBase, ServicesBinding { } finally { _schedulerPhase = SchedulerPhase.idle; Timeline.finishSync(); // end the Frame - profile(() { + if (!kReleaseMode) { _profileFrameStopwatch.stop(); _profileFramePostEvent(); - }); + } assert(() { if (debugPrintEndFrameBanner) debugPrint('▀' * _debugBanner.length); diff --git a/packages/flutter/lib/src/widgets/binding.dart b/packages/flutter/lib/src/widgets/binding.dart index 128733f344..70f25ffc5d 100644 --- a/packages/flutter/lib/src/widgets/binding.dart +++ b/packages/flutter/lib/src/widgets/binding.dart @@ -270,7 +270,7 @@ mixin WidgetsBinding on BindingBase, SchedulerBinding, GestureBinding, RendererB void initServiceExtensions() { super.initServiceExtensions(); - profile(() { + if (!kReleaseMode) { registerSignalServiceExtension( name: 'debugDumpApp', callback: () { @@ -302,7 +302,7 @@ mixin WidgetsBinding on BindingBase, SchedulerBinding, GestureBinding, RendererB }; }, ); - }); + } assert(() { registerBoolServiceExtension( @@ -566,10 +566,10 @@ mixin WidgetsBinding on BindingBase, SchedulerBinding, GestureBinding, RendererB /// This is used by [WidgetsApp] to avoid reporting frames that aren't useful /// during startup as the "first frame". void deferFirstFrameReport() { - profile(() { + if (!kReleaseMode) { assert(_deferFirstFrameReportCount >= 0); _deferFirstFrameReportCount += 1; - }); + } } /// When called after [deferFirstFrameReport]: tell the framework to report @@ -581,10 +581,10 @@ mixin WidgetsBinding on BindingBase, SchedulerBinding, GestureBinding, RendererB /// This is used by [WidgetsApp] to report when the first useful frame is /// painted. void allowFirstFrameReport() { - profile(() { + if (!kReleaseMode) { assert(_deferFirstFrameReportCount >= 1); _deferFirstFrameReportCount -= 1; - }); + } } void _handleBuildScheduled() { @@ -706,13 +706,13 @@ mixin WidgetsBinding on BindingBase, SchedulerBinding, GestureBinding, RendererB return true; }()); } - profile(() { + if (!kReleaseMode) { if (_needToReportFirstFrame && _reportFirstFrame) { developer.Timeline.instantSync('Widgets completed first useful frame'); developer.postEvent('Flutter.FirstFrame', {}); _needToReportFirstFrame = false; } - }); + } } /// The [Element] that is at the root of the hierarchy (and which wraps the diff --git a/packages/flutter/test/foundation/profile_test.dart b/packages/flutter/test/foundation/profile_test.dart index c76dfdd3d2..3b57f13040 100644 --- a/packages/flutter/test/foundation/profile_test.dart +++ b/packages/flutter/test/foundation/profile_test.dart @@ -10,7 +10,7 @@ void main() { // that the code in the `profile` closure is omitted in release mode. test('profile invokes its closure in debug or profile mode', () { int count = 0; - profile(() { + profile(() { // ignore: deprecated_member_use_from_same_package count++; }); // We run our tests in debug mode, so kReleaseMode will always evaluate to