From db72a4fc99e1d2b9921b361198e0c57d93091f5e Mon Sep 17 00:00:00 2001 From: James deBoer Date: Wed, 4 Jun 2014 15:53:47 -0700 Subject: [PATCH] perf(view cache): Avoid http.get This change makes templateUrl component creation 100% faster. It is a stop-gap until #1107 is fixed. Closes #1108 --- benchmark/web/tree-tmpl.html | 4 ++++ benchmark/web/tree.dart | 10 ++++++++++ benchmark/web/tree.html | 2 ++ lib/core_dom/view_factory.dart | 12 ++++++++++-- lib/core_dom/web_platform.dart | 11 +++++++++-- test/core/templateurl_spec.dart | 6 ------ 6 files changed, 35 insertions(+), 10 deletions(-) create mode 100644 benchmark/web/tree-tmpl.html diff --git a/benchmark/web/tree-tmpl.html b/benchmark/web/tree-tmpl.html new file mode 100644 index 000000000..12a8d2241 --- /dev/null +++ b/benchmark/web/tree-tmpl.html @@ -0,0 +1,4 @@ + {{ctrl.data.value}} + + + diff --git a/benchmark/web/tree.dart b/benchmark/web/tree.dart index cc3975311..81d3e8b13 100644 --- a/benchmark/web/tree.dart +++ b/benchmark/web/tree.dart @@ -19,6 +19,15 @@ class TreeComponent { var data; } +@Component( + selector: 'tree-url', + templateUrl: 'tree-tmpl.html', + publishAs: 'ctrl') +class TreeUrlComponent { + @NgOneWay('data') + var data; +} + // This is a baseline implementation of TreeComponent. // It assumes the data never changes and simply throws elements on the DOM @@ -239,6 +248,7 @@ main() { var module = new Module() ..type(TreeComponent) + ..type(TreeUrlComponent) ..type(NgFreeTree) ..type(NgFreeTreeScoped) ..type(NgFreeTreeClass) diff --git a/benchmark/web/tree.html b/benchmark/web/tree.html index f8839c187..b7040040d 100644 --- a/benchmark/web/tree.html +++ b/benchmark/web/tree.html @@ -14,12 +14,14 @@

Default:
+
From URL:
Baseline:
Baseline + scope:
Baseline + class:
+ diff --git a/lib/core_dom/view_factory.dart b/lib/core_dom/view_factory.dart index e65a914c3..2fec262ba 100644 --- a/lib/core_dom/view_factory.dart +++ b/lib/core_dom/view_factory.dart @@ -118,6 +118,7 @@ class WalkingViewFactory implements ViewFactory { @Injectable() class ViewCache { // _viewFactoryCache is unbounded + // This cache contains both HTML and URL keys. final viewFactoryCache = new LruCache(); final Http http; final TemplateCache templateCache; @@ -138,8 +139,15 @@ class ViewCache { } async.Future fromUrl(String url, DirectiveMap directives) { - return http.get(url, cache: templateCache).then( - (resp) => fromHtml(resp.responseText, directives)); + ViewFactory viewFactory = viewFactoryCache.get(url); + if (viewFactory == null) { + return http.get(url, cache: templateCache).then((resp) { + var viewFactoryFromHttp = fromHtml(resp.responseText, directives); + viewFactoryCache.put(url, viewFactoryFromHttp); + return viewFactoryFromHttp; + }); + } + return new async.Future.value(viewFactory); } } diff --git a/lib/core_dom/web_platform.dart b/lib/core_dom/web_platform.dart index 37921acad..bd615cea3 100644 --- a/lib/core_dom/web_platform.dart +++ b/lib/core_dom/web_platform.dart @@ -91,7 +91,14 @@ class PlatformViewCache implements ViewCache { } async.Future fromUrl(String url, DirectiveMap directives) { - return http.get(url, cache: templateCache).then( - (resp) => fromHtml(resp.responseText, directives)); + ViewFactory viewFactory = viewFactoryCache.get(url); + if (viewFactory == null) { + return http.get(url, cache: templateCache).then((resp) { + var viewFactoryFromHttp = fromHtml(resp.responseText, directives); + viewFactoryCache.put(url, viewFactoryFromHttp); + return viewFactoryFromHttp; + }); + } + return new async.Future.value(viewFactory); } } diff --git a/test/core/templateurl_spec.dart b/test/core/templateurl_spec.dart index 3eb2c8605..693127947 100644 --- a/test/core/templateurl_spec.dart +++ b/test/core/templateurl_spec.dart @@ -269,15 +269,9 @@ void main() { '
Simple!
' ); - // Since the template cache is disabled, we expect a 'simple.html' call. - backend - ..expectGET('simple.html').respond(200, '
Simple!
'); - var element2 = e('
ignore
'); compile([element2], directives)(injector, [element2]); - microLeap(); - backend.flush(); microLeap(); expect(element2.children[0].shadowRoot).toHaveHtml(