Ensure frame is scheduled when root widget is attached (#40105)

diff --git a/packages/flutter/lib/src/widgets/binding.dart b/packages/flutter/lib/src/widgets/binding.dart
index 2d6a524..cded97b 100644
--- a/packages/flutter/lib/src/widgets/binding.dart
+++ b/packages/flutter/lib/src/widgets/binding.dart
@@ -940,6 +940,9 @@
       owner.buildScope(element, () {
         element.mount(null, null);
       });
+      // This is most likely the first time the framework is ready to produce
+      // a frame. Ensure that we are asked for one.
+      SchedulerBinding.instance.ensureVisualUpdate();
     } else {
       element._newWidget = this;
       element.markNeedsBuild();
diff --git a/packages/flutter/test/widgets/binding_attach_root_widget_test.dart b/packages/flutter/test/widgets/binding_attach_root_widget_test.dart
new file mode 100644
index 0000000..32918a4
--- /dev/null
+++ b/packages/flutter/test/widgets/binding_attach_root_widget_test.dart
@@ -0,0 +1,17 @@
+// Copyright 2019 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/scheduler.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:flutter/widgets.dart';
+
+void main() {
+  test('attachRootWidget will schedule a frame', () async {
+    final WidgetsFlutterBinding binding = WidgetsFlutterBinding.ensureInitialized();
+    expect(SchedulerBinding.instance.hasScheduledFrame, isFalse);
+
+    binding.attachRootWidget(const Placeholder());
+    expect(SchedulerBinding.instance.hasScheduledFrame, isTrue);
+  });
+}