Commit 45c95b26 authored by John McCutchan's avatar John McCutchan Committed by GitHub

Performance fixes for hot reload when using a prebuilt loader (#6821)

parent cccd917a
...@@ -39,6 +39,7 @@ import 'src/devfs.dart'; ...@@ -39,6 +39,7 @@ import 'src/devfs.dart';
import 'src/device.dart'; import 'src/device.dart';
import 'src/doctor.dart'; import 'src/doctor.dart';
import 'src/globals.dart'; import 'src/globals.dart';
import 'src/hot.dart';
import 'src/runner/flutter_command_runner.dart'; import 'src/runner/flutter_command_runner.dart';
/// Main entry point for commands. /// Main entry point for commands.
...@@ -90,6 +91,8 @@ Future<Null> main(List<String> args) async { ...@@ -90,6 +91,8 @@ Future<Null> main(List<String> args) async {
context[DevFSConfig] = new DevFSConfig(); context[DevFSConfig] = new DevFSConfig();
if (context[Doctor] == null) if (context[Doctor] == null)
context[Doctor] = new Doctor(); context[Doctor] = new Doctor();
if (context[HotRunnerConfig] == null)
context[HotRunnerConfig] = new HotRunnerConfig();
dynamic result = await runner.run(args); dynamic result = await runner.run(args);
_exit(result is int ? result : 1); _exit(result is int ? result : 1);
......
...@@ -20,6 +20,8 @@ typedef void DevFSProgressReporter(int progress, int max); ...@@ -20,6 +20,8 @@ typedef void DevFSProgressReporter(int progress, int max);
class DevFSConfig { class DevFSConfig {
/// Should DevFS assume that symlink targets are stable? /// Should DevFS assume that symlink targets are stable?
bool cacheSymlinks = false; bool cacheSymlinks = false;
/// Should DevFS assume that there are no symlinks to directories?
bool noDirectorySymlinks = false;
} }
DevFSConfig get devFSConfig => context[DevFSConfig]; DevFSConfig get devFSConfig => context[DevFSConfig];
...@@ -521,12 +523,12 @@ class DevFS { ...@@ -521,12 +523,12 @@ class DevFS {
Stream<FileSystemEntity> files = Stream<FileSystemEntity> files =
directory.list(recursive: recursive, followLinks: false); directory.list(recursive: recursive, followLinks: false);
await for (FileSystemEntity file in files) { 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 String linkPath = file.resolveSymbolicLinksSync();
final FileSystemEntityType linkType = final FileSystemEntityType linkType =
FileStat.statSync(linkPath).type; FileStat.statSync(linkPath).type;
if (linkType == FileSystemEntityType.DIRECTORY) { if (linkType == FileSystemEntityType.DIRECTORY) {
// Skip links to directories.
continue; continue;
} }
} }
......
...@@ -12,6 +12,7 @@ import 'package:stack_trace/stack_trace.dart'; ...@@ -12,6 +12,7 @@ import 'package:stack_trace/stack_trace.dart';
import 'application_package.dart'; import 'application_package.dart';
import 'asset.dart'; import 'asset.dart';
import 'base/context.dart';
import 'base/logger.dart'; import 'base/logger.dart';
import 'base/process.dart'; import 'base/process.dart';
import 'base/utils.dart'; import 'base/utils.dart';
...@@ -27,6 +28,15 @@ import 'resident_runner.dart'; ...@@ -27,6 +28,15 @@ import 'resident_runner.dart';
import 'toolchain.dart'; import 'toolchain.dart';
import 'vmservice.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; const bool kHotReloadDefault = true;
String getDevFSLoaderScript() { String getDevFSLoaderScript() {
...@@ -132,6 +142,10 @@ class HotRunner extends ResidentRunner { ...@@ -132,6 +142,10 @@ class HotRunner extends ResidentRunner {
} }
bool _refreshDartDependencies() { bool _refreshDartDependencies() {
if (!hotRunnerConfig.computeDartDependencies) {
// Disabled.
return true;
}
if (_dartDependencies != null) { if (_dartDependencies != null) {
// Already computed. // Already computed.
return true; return true;
...@@ -364,8 +378,10 @@ class HotRunner extends ResidentRunner { ...@@ -364,8 +378,10 @@ class HotRunner extends ResidentRunner {
bundleDirty: rebuildBundle, bundleDirty: rebuildBundle,
fileFilter: _dartDependencies); fileFilter: _dartDependencies);
devFSStatus.stop(); devFSStatus.stop();
// Clear the set after the sync. if (!hotRunnerConfig.stableDartDependencies) {
_dartDependencies = null; // Clear the set after the sync so they are recomputed next time.
_dartDependencies = null;
}
printTrace('Synced ${getSizeAsMB(_devFS.bytes)}.'); printTrace('Synced ${getSizeAsMB(_devFS.bytes)}.');
return true; return true;
} }
......
...@@ -9,10 +9,13 @@ import 'package:flutter_tools/src/base/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/logger.dart';
import 'package:flutter_tools/src/base/os.dart'; import 'package:flutter_tools/src/base/os.dart';
import 'package:flutter_tools/src/device.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/doctor.dart';
import 'package:flutter_tools/src/hot.dart';
import 'package:flutter_tools/src/ios/mac.dart'; import 'package:flutter_tools/src/ios/mac.dart';
import 'package:flutter_tools/src/ios/simulators.dart'; import 'package:flutter_tools/src/ios/simulators.dart';
import 'package:flutter_tools/src/usage.dart'; import 'package:flutter_tools/src/usage.dart';
import 'package:mockito/mockito.dart'; import 'package:mockito/mockito.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
...@@ -54,6 +57,14 @@ void testUsingContext(String description, dynamic testMethod(), { ...@@ -54,6 +57,14 @@ void testUsingContext(String description, dynamic testMethod(), {
testContext[OperatingSystemUtils] = os; testContext[OperatingSystemUtils] = os;
} }
if (!overrides.containsKey(DevFSConfig)) {
testContext[DevFSConfig] = new DevFSConfig();
}
if (!overrides.containsKey(HotRunnerConfig)) {
testContext[HotRunnerConfig] = new HotRunnerConfig();
}
if (!overrides.containsKey(IOSSimulatorUtils)) { if (!overrides.containsKey(IOSSimulatorUtils)) {
MockIOSSimulatorUtils mock = new MockIOSSimulatorUtils(); MockIOSSimulatorUtils mock = new MockIOSSimulatorUtils();
when(mock.getAttachedDevices()).thenReturn(<IOSSimulator>[]); when(mock.getAttachedDevices()).thenReturn(<IOSSimulator>[]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment