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(