From 45c95b261d580e4762912c4e1ac244f5e4e19303 Mon Sep 17 00:00:00 2001 From: John McCutchan Date: Fri, 11 Nov 2016 13:28:21 -0800 Subject: [PATCH] Performance fixes for hot reload when using a prebuilt loader (#6821) --- packages/flutter_tools/lib/executable.dart | 3 +++ packages/flutter_tools/lib/src/devfs.dart | 6 ++++-- packages/flutter_tools/lib/src/hot.dart | 20 ++++++++++++++++++-- packages/flutter_tools/test/src/context.dart | 11 +++++++++++ 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/packages/flutter_tools/lib/executable.dart b/packages/flutter_tools/lib/executable.dart index b0dded20235..0cf2d45bd03 100644 --- a/packages/flutter_tools/lib/executable.dart +++ b/packages/flutter_tools/lib/executable.dart @@ -39,6 +39,7 @@ import 'src/devfs.dart'; import 'src/device.dart'; import 'src/doctor.dart'; import 'src/globals.dart'; +import 'src/hot.dart'; import 'src/runner/flutter_command_runner.dart'; /// Main entry point for commands. @@ -90,6 +91,8 @@ Future main(List args) async { context[DevFSConfig] = new DevFSConfig(); if (context[Doctor] == null) context[Doctor] = new Doctor(); + if (context[HotRunnerConfig] == null) + context[HotRunnerConfig] = new HotRunnerConfig(); dynamic result = await runner.run(args); _exit(result is int ? result : 1); diff --git a/packages/flutter_tools/lib/src/devfs.dart b/packages/flutter_tools/lib/src/devfs.dart index 02490750d55..304e12cef53 100644 --- a/packages/flutter_tools/lib/src/devfs.dart +++ b/packages/flutter_tools/lib/src/devfs.dart @@ -20,6 +20,8 @@ typedef void DevFSProgressReporter(int progress, int max); class DevFSConfig { /// Should DevFS assume that symlink targets are stable? bool cacheSymlinks = false; + /// Should DevFS assume that there are no symlinks to directories? + bool noDirectorySymlinks = false; } DevFSConfig get devFSConfig => context[DevFSConfig]; @@ -521,12 +523,12 @@ class DevFS { Stream files = directory.list(recursive: recursive, followLinks: false); await for (FileSystemEntity file in files) { - if (file is Link) { + if (!devFSConfig.noDirectorySymlinks && (file is Link)) { + // Check if this is a symlink to a directory and skip it. final String linkPath = file.resolveSymbolicLinksSync(); final FileSystemEntityType linkType = FileStat.statSync(linkPath).type; if (linkType == FileSystemEntityType.DIRECTORY) { - // Skip links to directories. continue; } } diff --git a/packages/flutter_tools/lib/src/hot.dart b/packages/flutter_tools/lib/src/hot.dart index e63e9186759..a139b42bc4c 100644 --- a/packages/flutter_tools/lib/src/hot.dart +++ b/packages/flutter_tools/lib/src/hot.dart @@ -12,6 +12,7 @@ import 'package:stack_trace/stack_trace.dart'; import 'application_package.dart'; import 'asset.dart'; +import 'base/context.dart'; import 'base/logger.dart'; import 'base/process.dart'; import 'base/utils.dart'; @@ -27,6 +28,15 @@ import 'resident_runner.dart'; import 'toolchain.dart'; import 'vmservice.dart'; +class HotRunnerConfig { + /// Should the hot runner compute the minimal Dart dependencies? + bool computeDartDependencies = true; + /// Should the hot runner assume that the minimal Dart dependencies do not change? + bool stableDartDependencies = false; +} + +HotRunnerConfig get hotRunnerConfig => context[HotRunnerConfig]; + const bool kHotReloadDefault = true; String getDevFSLoaderScript() { @@ -132,6 +142,10 @@ class HotRunner extends ResidentRunner { } bool _refreshDartDependencies() { + if (!hotRunnerConfig.computeDartDependencies) { + // Disabled. + return true; + } if (_dartDependencies != null) { // Already computed. return true; @@ -364,8 +378,10 @@ class HotRunner extends ResidentRunner { bundleDirty: rebuildBundle, fileFilter: _dartDependencies); devFSStatus.stop(); - // Clear the set after the sync. - _dartDependencies = null; + if (!hotRunnerConfig.stableDartDependencies) { + // Clear the set after the sync so they are recomputed next time. + _dartDependencies = null; + } printTrace('Synced ${getSizeAsMB(_devFS.bytes)}.'); return true; } diff --git a/packages/flutter_tools/test/src/context.dart b/packages/flutter_tools/test/src/context.dart index 38993ddbc95..e5bcad29af0 100644 --- a/packages/flutter_tools/test/src/context.dart +++ b/packages/flutter_tools/test/src/context.dart @@ -9,10 +9,13 @@ import 'package:flutter_tools/src/base/context.dart'; import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/os.dart'; import 'package:flutter_tools/src/device.dart'; +import 'package:flutter_tools/src/devfs.dart'; import 'package:flutter_tools/src/doctor.dart'; +import 'package:flutter_tools/src/hot.dart'; import 'package:flutter_tools/src/ios/mac.dart'; import 'package:flutter_tools/src/ios/simulators.dart'; import 'package:flutter_tools/src/usage.dart'; + import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; @@ -54,6 +57,14 @@ void testUsingContext(String description, dynamic testMethod(), { testContext[OperatingSystemUtils] = os; } + if (!overrides.containsKey(DevFSConfig)) { + testContext[DevFSConfig] = new DevFSConfig(); + } + + if (!overrides.containsKey(HotRunnerConfig)) { + testContext[HotRunnerConfig] = new HotRunnerConfig(); + } + if (!overrides.containsKey(IOSSimulatorUtils)) { MockIOSSimulatorUtils mock = new MockIOSSimulatorUtils(); when(mock.getAttachedDevices()).thenReturn([]);