Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit 9277283

Browse files
committed
perf(view factory): Compute DI Keys ahead of time
4% improvement in TreeComponent benchmark For #1081 Closes #1085
1 parent 6062610 commit 9277283

9 files changed

+95
-56
lines changed

Diff for: lib/core_dom/common.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ class MappingParts {
1616
class DirectiveRef {
1717
final dom.Node element;
1818
final Type type;
19+
final Key typeKey;
1920
final Directive annotation;
2021
final String value;
2122
final mappings = new List<MappingParts>();
2223

23-
DirectiveRef(this.element, this.type, this.annotation, [ this.value ]);
24+
DirectiveRef(this.element, this.type, this.annotation, this.typeKey, [ this.value ]);
2425

2526
String toString() {
2627
var html = element is dom.Element

Diff for: lib/core_dom/element_binder.dart

+26-25
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ class TemplateElementBinder extends ElementBinder {
2727
_registerViewFactory(node, parentInjector, nodeModule) {
2828
assert(templateViewFactory != null);
2929
nodeModule
30-
..bind(ViewPort, toFactory: (_) =>
31-
new ViewPort(node, parentInjector.get(Animate)))
32-
..bind(ViewFactory, toValue: templateViewFactory)
33-
..bind(BoundViewFactory, toFactory: (Injector injector) =>
30+
..bindByKey(_VIEW_PORT_KEY, toFactory: (_) =>
31+
new ViewPort(node, parentInjector.getByKey(_ANIMATE_KEY)))
32+
..bindByKey(_VIEW_FACTORY_KEY, toValue: templateViewFactory)
33+
..bindByKey(_BOUND_VIEW_FACTORY_KEY, toFactory: (Injector injector) =>
3434
templateViewFactory.bind(injector));
3535
}
3636
}
@@ -203,7 +203,7 @@ class ElementBinder {
203203

204204
void _link(nodeInjector, probe, scope, nodeAttrs, formatters) {
205205
_usableDirectiveRefs.forEach((DirectiveRef ref) {
206-
var directive = nodeInjector.get(ref.type);
206+
var directive = nodeInjector.getByKey(ref.typeKey);
207207
probe.directives.add(directive);
208208

209209
if (ref.annotation is Controller) {
@@ -240,18 +240,18 @@ class ElementBinder {
240240
void _createDirectiveFactories(DirectiveRef ref, nodeModule, node, nodesAttrsDirectives, nodeAttrs,
241241
visibility) {
242242
if (ref.type == TextMustache) {
243-
nodeModule.bind(TextMustache, toFactory: (Injector injector) {
244-
return new TextMustache(node, ref.value, injector.get(Interpolate),
245-
injector.get(Scope), injector.get(FormatterMap));
243+
nodeModule.bindByKey(_TEXT_MUSTACHE_KEY, toFactory: (Injector injector) {
244+
return new TextMustache(node, ref.value, injector.getByKey(_INTERPOLATE_KEY),
245+
injector.getByKey(_SCOPE_KEY), injector.getByKey(_FORMATTER_MAP_KEY));
246246
});
247247
} else if (ref.type == AttrMustache) {
248248
if (nodesAttrsDirectives.isEmpty) {
249249
nodeModule.bind(AttrMustache, toFactory: (Injector injector) {
250-
var scope = injector.get(Scope);
251-
var interpolate = injector.get(Interpolate);
250+
var scope = injector.getByKey(_SCOPE_KEY);
251+
var interpolate = injector.getByKey(_INTERPOLATE_KEY);
252252
for (var ref in nodesAttrsDirectives) {
253253
new AttrMustache(nodeAttrs, ref.value, interpolate, scope,
254-
injector.get(FormatterMap));
254+
injector.getByKey(_FORMATTER_MAP_KEY));
255255
}
256256
});
257257
}
@@ -266,23 +266,24 @@ class ElementBinder {
266266
} else {
267267
factory = _componentFactory;
268268
}
269-
nodeModule.bind(ref.type, toFactory: factory.call(node, ref), visibility: visibility);
269+
nodeModule.bindByKey(ref.typeKey, toFactory: factory.call(node, ref), visibility: visibility);
270270
} else {
271-
nodeModule.bind(ref.type, visibility: visibility);
271+
nodeModule.bindByKey(ref.typeKey, visibility: visibility);
272272
}
273273
}
274274

275275
// Overridden in TemplateElementBinder
276276
void _registerViewFactory(node, parentInjector, nodeModule) {
277-
nodeModule..bind(ViewPort, toValue: null)
278-
..bind(ViewFactory, toValue: null)
279-
..bind(BoundViewFactory, toValue: null);
277+
nodeModule..bindByKey(_VIEW_PORT_KEY, toValue: null)
278+
..bindByKey(_VIEW_FACTORY_KEY, toValue: null)
279+
..bindByKey(_BOUND_VIEW_FACTORY_KEY, toValue: null);
280280
}
281281

282+
282283
Injector bind(View view, Injector parentInjector, dom.Node node) {
283284
Injector nodeInjector;
284-
Scope scope = parentInjector.get(Scope);
285-
FormatterMap formatters = parentInjector.get(FormatterMap);
285+
Scope scope = parentInjector.getByKey(_SCOPE_KEY);
286+
FormatterMap formatters = parentInjector.getByKey(_FORMATTER_MAP_KEY);
286287
var nodeAttrs = node is dom.Element ? new NodeAttrs(node) : null;
287288
ElementProbe probe;
288289

@@ -291,12 +292,12 @@ class ElementBinder {
291292

292293
var nodesAttrsDirectives = [];
293294
var nodeModule = new Module()
294-
..bind(NgElement)
295-
..bind(View, toValue: view)
296-
..bind(dom.Element, toValue: node)
297-
..bind(dom.Node, toValue: node)
298-
..bind(NodeAttrs, toValue: nodeAttrs)
299-
..bind(ElementProbe, toFactory: (_) => probe);
295+
..bindByKey(_NG_ELEMENT_KEY)
296+
..bindByKey(_VIEW_KEY, toValue: view)
297+
..bindByKey(_ELEMENT_KEY, toValue: node)
298+
..bindByKey(_NODE_KEY, toValue: node)
299+
..bindByKey(_NODE_ATTRS_KEY, toValue: nodeAttrs)
300+
..bindByKey(_ELEMENT_PROBE_KEY, toFactory: (_) => probe);
300301

301302
directiveRefs.forEach((DirectiveRef ref) {
302303
Directive annotation = ref.annotation;
@@ -317,7 +318,7 @@ class ElementBinder {
317318

318319
nodeInjector = parentInjector.createChild([nodeModule]);
319320
probe = _expando[node] = new ElementProbe(
320-
parentInjector.get(ElementProbe), node, nodeInjector, scope);
321+
parentInjector.getByKey(_ELEMENT_PROBE_KEY), node, nodeInjector, scope);
321322

322323
_link(nodeInjector, probe, scope, nodeAttrs, formatters);
323324

Diff for: lib/core_dom/module_internal.dart

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ part 'transcluding_component_factory.dart';
4444
part 'tree_sanitizer.dart';
4545
part 'walking_compiler.dart';
4646
part 'ng_element.dart';
47+
part 'static_keys.dart';
4748

4849
class CoreDomModule extends Module {
4950
CoreDomModule() {

Diff for: lib/core_dom/selector.dart

+3-3
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ class DirectiveSelector {
9696
// the value. Yes it is a bit of a hack.
9797
_directives[selectorRegExp.annotation].forEach((type) {
9898
builder.addDirective(new DirectiveRef(
99-
node, type, selectorRegExp.annotation, '$attrName=$value'));
99+
node, type, selectorRegExp.annotation, new Key(type), '$attrName=$value'));
100100
});
101101
}
102102
}
@@ -131,7 +131,7 @@ class DirectiveSelector {
131131
if (selectorRegExp.regexp.hasMatch(value)) {
132132
_directives[selectorRegExp.annotation].forEach((type) {
133133
builder.addDirective(new DirectiveRef(node, type,
134-
selectorRegExp.annotation, value));
134+
selectorRegExp.annotation, new Key(type), value));
135135
});
136136
}
137137
}
@@ -204,7 +204,7 @@ class _SelectorPart {
204204
_addRefs(ElementBinderBuilder builder, List<_Directive> directives, dom.Node node,
205205
[String attrValue]) {
206206
directives.forEach((directive) {
207-
builder.addDirective(new DirectiveRef(node, directive.type, directive.annotation, attrValue));
207+
builder.addDirective(new DirectiveRef(node, directive.type, directive.annotation, new Key(directive.type), attrValue));
208208
});
209209
}
210210

Diff for: lib/core_dom/shadow_dom_component_factory.dart

+26-24
Original file line numberDiff line numberDiff line change
@@ -33,22 +33,24 @@ class ShadowDomComponentFactory implements ComponentFactory {
3333

3434
final Map<_ComponentAssetKey, async.Future<dom.StyleElement>> _styleElementCache = {};
3535

36+
37+
3638
FactoryFn call(dom.Node node, DirectiveRef ref) {
3739
return (Injector injector) {
3840
var component = ref.annotation as Component;
39-
Scope scope = injector.get(Scope);
40-
ViewCache viewCache = injector.get(ViewCache);
41-
Http http = injector.get(Http);
42-
TemplateCache templateCache = injector.get(TemplateCache);
43-
DirectiveMap directives = injector.get(DirectiveMap);
44-
NgBaseCss baseCss = injector.get(NgBaseCss);
41+
Scope scope = injector.getByKey(_SCOPE_KEY);
42+
ViewCache viewCache = injector.getByKey(_VIEW_CACHE_KEY);
43+
Http http = injector.getByKey(_HTTP_KEY);
44+
TemplateCache templateCache = injector.getByKey(_TEMPLATE_CACHE_KEY);
45+
DirectiveMap directives = injector.getByKey(_DIRECTIVE_MAP_KEY);
46+
NgBaseCss baseCss = injector.getByKey(_NG_BASE_CSS_KEY);
4547
// This is a bit of a hack since we are returning different type then we are.
4648
var componentFactory = new _ComponentFactory(node,
47-
ref.type,
49+
ref.typeKey,
4850
component,
49-
injector.get(dom.NodeTreeSanitizer),
50-
injector.get(WebPlatform),
51-
injector.get(ComponentCssRewriter),
51+
injector.getByKey(_NODE_TREE_SANITIZER_KEY),
52+
injector.getByKey(_WEB_PLATFORM_KEY),
53+
injector.getByKey(_COMPONENT_CSS_REWRITER_KEY),
5254
_expando,
5355
baseCss,
5456
_styleElementCache);
@@ -70,7 +72,7 @@ class ShadowDomComponentFactory implements ComponentFactory {
7072
class _ComponentFactory implements Function {
7173

7274
final dom.Element element;
73-
final Type type;
75+
final Key typeKey;
7476
final Component component;
7577
final dom.NodeTreeSanitizer treeSanitizer;
7678
final Expando _expando;
@@ -85,7 +87,7 @@ class _ComponentFactory implements Function {
8587
Injector shadowInjector;
8688
var controller;
8789

88-
_ComponentFactory(this.element, this.type, this.component, this.treeSanitizer,
90+
_ComponentFactory(this.element, this.typeKey, this.component, this.treeSanitizer,
8991
this.platform, this.componentCssRewriter, this._expando,
9092
this._baseCss, this._styleElementCache);
9193

@@ -164,7 +166,7 @@ class _ComponentFactory implements Function {
164166
}
165167
return shadowDom;
166168
}));
167-
controller = createShadowInjector(injector, templateLoader).get(type);
169+
controller = createShadowInjector(injector, templateLoader).getByKey(typeKey);
168170
ComponentFactory._setupOnShadowDomAttach(controller, templateLoader, shadowScope);
169171
return controller;
170172
}
@@ -177,17 +179,17 @@ class _ComponentFactory implements Function {
177179

178180
Injector createShadowInjector(injector, TemplateLoader templateLoader) {
179181
var probe;
180-
var shadowModule = new Module()
181-
..bind(type)
182-
..bind(NgElement)
183-
..bind(EventHandler, toImplementation: ShadowRootEventHandler)
184-
..bind(Scope, toValue: shadowScope)
185-
..bind(TemplateLoader, toValue: templateLoader)
186-
..bind(dom.ShadowRoot, toValue: shadowDom)
187-
..bind(ElementProbe, toFactory: (_) => probe);
188-
shadowInjector = injector.createChild([shadowModule], name: SHADOW_DOM_INJECTOR_NAME);
182+
var shadowModule = new Module()
183+
..bindByKey(typeKey)
184+
..bindByKey(_NG_ELEMENT_KEY)
185+
..bindByKey(_EVENT_HANDLER_KEY, toImplementation: ShadowRootEventHandler)
186+
..bindByKey(_SCOPE_KEY, toValue: shadowScope)
187+
..bindByKey(_TEMPLATE_LOADER_KEY, toValue: templateLoader)
188+
..bindByKey(_SHADOW_ROOT_KEY, toValue: shadowDom)
189+
..bindByKey(_ELEMENT_PROBE, toFactory: (_) => probe);
190+
shadowInjector = injector.createChild([shadowModule], name: SHADOW_DOM_INJECTOR_NAME);
189191
probe = _expando[shadowDom] = new ElementProbe(
190-
injector.get(ElementProbe), shadowDom, shadowInjector, shadowScope);
192+
injector.getByKey(_ELEMENT_PROBE), shadowDom, shadowInjector, shadowScope);
191193
return shadowInjector;
192194
}
193195
}
@@ -220,4 +222,4 @@ class ComponentCssRewriter {
220222
String call(String css, { String selector, String cssUrl} ) {
221223
return css;
222224
}
223-
}
225+
}

Diff for: lib/core_dom/static_keys.dart

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
part of angular.core.dom_internal;
2+
3+
// Keys used to call Injector.getByKey and Module.bindByKey
4+
5+
Key _ANIMATE_KEY = new Key(Animate);
6+
Key _BOUND_VIEW_FACTORY_KEY = new Key(BoundViewFactory);
7+
Key _COMPONENT_CSS_REWRITER_KEY = new Key(ComponentCssRewriter);
8+
Key _DIRECTIVE_MAP_KEY = new Key(DirectiveMap);
9+
Key _ELEMENT_KEY = new Key(dom.Element);
10+
Key _ELEMENT_PROBE_KEY = new Key(ElementProbe);
11+
Key _ELEMENT_PROBE = new Key(ElementProbe);
12+
Key _EVENT_HANDLER_KEY = new Key(EventHandler);
13+
Key _FORMATTER_MAP_KEY = new Key(FormatterMap);
14+
Key _HTTP_KEY = new Key(Http);
15+
Key _INTERPOLATE_KEY = new Key(Interpolate);
16+
Key _NG_BASE_CSS_KEY = new Key(NgBaseCss);
17+
Key _NG_ELEMENT_KEY = new Key(NgElement);
18+
Key _NODE_ATTRS_KEY = new Key(NodeAttrs);
19+
Key _NODE_KEY = new Key(dom.Node);
20+
Key _NODE_TREE_SANITIZER_KEY = new Key(dom.NodeTreeSanitizer);
21+
Key _SCOPE_KEY = new Key(Scope);
22+
Key _SHADOW_ROOT_KEY = new Key(dom.ShadowRoot);
23+
Key _TEMPLATE_CACHE_KEY = new Key(TemplateCache);
24+
Key _TEMPLATE_LOADER_KEY = new Key(TemplateLoader);
25+
Key _TEXT_MUSTACHE_KEY = new Key(TextMustache);
26+
Key _VIEW_CACHE_KEY = new Key(ViewCache);
27+
Key _VIEW_FACTORY_KEY = new Key(ViewFactory);
28+
Key _VIEW_KEY = new Key(View);
29+
Key _VIEW_PORT_KEY = new Key(ViewPort);
30+
Key _WEB_PLATFORM_KEY = new Key(WebPlatform);

Diff for: lib/core_dom/tagging_view_factory.dart

+3-1
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,16 @@ class TaggingViewFactory implements ViewFactory {
99

1010
BoundViewFactory bind(Injector injector) => new BoundViewFactory(this, injector);
1111

12+
static Key _EVENT_HANDLER_KEY = new Key(EventHandler);
13+
1214
View call(Injector injector, [List<dom.Node> nodes /* TODO: document fragment */]) {
1315
if (nodes == null) {
1416
nodes = cloneElements(templateNodes);
1517
}
1618
var timerId;
1719
try {
1820
assert((timerId = _perf.startTimer('ng.view')) != false);
19-
var view = new View(nodes, injector.get(EventHandler));
21+
var view = new View(nodes, injector.getByKey(_EVENT_HANDLER_KEY));
2022
_link(view, nodes, injector);
2123
return view;
2224
} finally {

Diff for: lib/core_dom/view_factory.dart

+3-1
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ class BoundViewFactory {
1515

1616
BoundViewFactory(this.viewFactory, this.injector);
1717

18+
static Key _SCOPE_KEY = new Key(Scope);
19+
1820
View call(Scope scope) =>
19-
viewFactory(injector.createChild([new Module()..bind(Scope, toValue: scope)]));
21+
viewFactory(injector.createChild([new Module()..bindByKey(_SCOPE_KEY, toValue: scope)]));
2022
}
2123

2224
abstract class ViewFactory implements Function {

Diff for: test/core_dom/element_binder_builder_spec.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ main() => describe('ElementBinderBuilder', () {
3838
addDirective(selector) {
3939
directives.forEach((Directive annotation, Type type) {
4040
if (annotation.selector == selector)
41-
b.addDirective(new DirectiveRef(node, type, annotation, null));
41+
b.addDirective(new DirectiveRef(node, type, annotation, new Key(type), null));
4242
});
4343
b = b.binder;
4444
}

0 commit comments

Comments
 (0)