From c168afc0704a2d2addab0d5562950656650c7b64 Mon Sep 17 00:00:00 2001 From: xster Date: Wed, 31 May 2017 11:19:37 -0700 Subject: [PATCH] Fix performance regression with _InheritedTheme (#10311) Check ThemeData instead of Theme. --- packages/flutter/lib/src/material/theme.dart | 2 +- .../flutter/test/material/theme_test.dart | 68 +++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/material/theme.dart b/packages/flutter/lib/src/material/theme.dart index c6c5bb8e88..c036033cba 100644 --- a/packages/flutter/lib/src/material/theme.dart +++ b/packages/flutter/lib/src/material/theme.dart @@ -155,7 +155,7 @@ class _InheritedTheme extends InheritedWidget { final Theme theme; @override - bool updateShouldNotify(_InheritedTheme old) => theme != old.theme; + bool updateShouldNotify(_InheritedTheme old) => theme.data != old.theme.data; } /// An interpolation between two [ThemeData]s. diff --git a/packages/flutter/test/material/theme_test.dart b/packages/flutter/test/material/theme_test.dart index bb2ae1b844..b934e6a405 100644 --- a/packages/flutter/test/material/theme_test.dart +++ b/packages/flutter/test/material/theme_test.dart @@ -265,4 +265,72 @@ void main() { expect(glyphText.text.style.color, Colors.orange); expect(glyphText.text.style.fontSize, 20.0); }); + + testWidgets( + 'Same ThemeData reapplied does not trigger descendents rebuilds', + (WidgetTester tester) async { + testBuildCalled = 0; + ThemeData themeData = new ThemeData(primaryColor: const Color(0xFF000000)); + + await tester.pumpWidget( + new Theme( + data: themeData, + child: const Test(), + ), + ); + expect(testBuildCalled, 1); + + // Pump the same widgets again. + await tester.pumpWidget( + new Theme( + data: themeData, + child: const Test(), + ), + ); + // No repeated build calls to the child since it's the same theme data. + expect(testBuildCalled, 1); + + // New instance of theme data but still the same content. + themeData = new ThemeData(primaryColor: const Color(0xFF000000)); + await tester.pumpWidget( + new Theme( + data: themeData, + child: const Test(), + ), + ); + // Still no repeated calls. + expect(testBuildCalled, 1); + + // Different now. + themeData = new ThemeData(primaryColor: const Color(0xFF222222)); + await tester.pumpWidget( + new Theme( + data: themeData, + child: const Test(), + ), + ); + // Should call build again. + expect(testBuildCalled, 2); + }, + ); +} + +int testBuildCalled; +class Test extends StatefulWidget { + const Test(); + + @override + _TestState createState() => new _TestState(); +} + +class _TestState extends State { + @override + Widget build(BuildContext context) { + testBuildCalled += 1; + return new Container( + decoration: new BoxDecoration( + color: Theme.of(context).primaryColor, + ), + ); + } }