Skip to content

Commit

Permalink
perf: Use precomputed keys with injector for performance reasons.
Browse files Browse the repository at this point in the history
  • Loading branch information
mvuksano authored and Diana Salsbury committed Jul 16, 2014
1 parent 7286f56 commit 149086a
Show file tree
Hide file tree
Showing 23 changed files with 139 additions and 84 deletions.
10 changes: 6 additions & 4 deletions lib/application.dart
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ import 'package:angular/formatter/module_internal.dart';
import 'package:angular/routing/module.dart';
import 'package:angular/introspection_js.dart';

import 'package:angular/core_dom/static_keys.dart';

/**
* This is the top level module which describes all Angular components,
* including services, formatters and directives. When instantiating an Angular application
Expand Down Expand Up @@ -146,7 +148,7 @@ abstract class Application {
modules.add(ngModule);
ngModule..bind(VmTurnZone, toValue: zone)
..bind(Application, toValue: this)
..bind(dom.Node, toFactory: (i) => i.get(Application).element);
..bind(dom.Node, toFactory: (i) => i.getByKey(new Key(Application)).element);
}

/**
Expand All @@ -164,11 +166,11 @@ abstract class Application {
return zone.run(() {
var rootElements = [element];
Injector injector = createInjector();
ExceptionHandler exceptionHandler = injector.get(ExceptionHandler);
ExceptionHandler exceptionHandler = injector.getByKey(EXCEPTION_HANDLER_KEY);
initializeDateFormatting(null, null).then((_) {
try {
var compiler = injector.get(Compiler);
var viewFactory = compiler(rootElements, injector.get(DirectiveMap));
var compiler = injector.getByKey(COMPILER_KEY);
var viewFactory = compiler(rootElements, injector.getByKey(DIRECTIVE_MAP_KEY));
viewFactory(injector, rootElements);
} catch (e, s) {
exceptionHandler(e, s);
Expand Down
3 changes: 2 additions & 1 deletion lib/core/module_internal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import 'package:angular/change_detection/dirty_checking_change_detector.dart';
import 'package:angular/core/parser/utils.dart';
import 'package:angular/core/parser/syntax.dart' as syntax;
import 'package:angular/core/registry.dart';
import 'package:angular/core/static_keys.dart';

part "cache.dart";
part "exception_handler.dart";
Expand All @@ -39,7 +40,7 @@ class CoreModule extends Module {
bind(FormatterMap);
bind(Interpolate);
bind(RootScope);
bind(Scope, toFactory: (injector) => injector.get(RootScope));
bind(Scope, toFactory: (injector) => injector.getByKey(ROOT_SCOPE_KEY));
bind(ClosureMap, toFactory: (_) => throw "Must provide dynamic/static ClosureMap.");
bind(ScopeStats);
bind(ScopeStatsEmitter);
Expand Down
11 changes: 11 additions & 0 deletions lib/core/static_keys.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
library angular.static_keys;

import 'package:di/di.dart';
import 'module_internal.dart';

Key EXCEPTION_HANDLER_KEY = new Key(ExceptionHandler);
Key ROOT_SCOPE_KEY = new Key(RootScope);
Key SCOPE_KEY = new Key(Scope);
Key SCOPE_STATS_CONFIG_KEY = new Key(ScopeStatsConfig);
Key FORMATTER_MAP_KEY = new Key(FormatterMap);
Key INTERPOLATE_KEY = new Key(Interpolate);
2 changes: 1 addition & 1 deletion lib/core_dom/common.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class DirectiveRef {
Injector forceNewDirectivesAndFormatters(Injector injector, List<Module> modules) {
modules.add(new Module()
..bind(Scope, toFactory: (i) {
var scope = i.parent.get(Scope);
var scope = i.parent.getByKey(SCOPE_KEY);
return scope.createChild(new PrototypeMap(scope.context));
}));

Expand Down
44 changes: 22 additions & 22 deletions lib/core_dom/element_binder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ class TemplateElementBinder extends ElementBinder {
_registerViewFactory(node, parentInjector, nodeModule) {
assert(templateViewFactory != null);
nodeModule
..bindByKey(_VIEW_PORT_KEY, toFactory: (_) =>
new ViewPort(node, parentInjector.getByKey(_ANIMATE_KEY)))
..bindByKey(_VIEW_FACTORY_KEY, toValue: templateViewFactory)
..bindByKey(_BOUND_VIEW_FACTORY_KEY, toFactory: (Injector injector) =>
..bindByKey(VIEW_PORT_KEY, toFactory: (_) =>
new ViewPort(node, parentInjector.getByKey(ANIMATE_KEY)))
..bindByKey(VIEW_FACTORY_KEY, toValue: templateViewFactory)
..bindByKey(BOUND_VIEW_FACTORY_KEY, toFactory: (Injector injector) =>
templateViewFactory.bind(injector));
}
}
Expand Down Expand Up @@ -240,18 +240,18 @@ class ElementBinder {
void _createDirectiveFactories(DirectiveRef ref, nodeModule, node, nodesAttrsDirectives, nodeAttrs,
visibility) {
if (ref.type == TextMustache) {
nodeModule.bindByKey(_TEXT_MUSTACHE_KEY, toFactory: (Injector injector) {
return new TextMustache(node, ref.value, injector.getByKey(_INTERPOLATE_KEY),
injector.getByKey(_SCOPE_KEY), injector.getByKey(_FORMATTER_MAP_KEY));
nodeModule.bindByKey(TEXT_MUSTACHE_KEY, toFactory: (Injector injector) {
return new TextMustache(node, ref.value, injector.getByKey(INTERPOLATE_KEY),
injector.getByKey(SCOPE_KEY), injector.getByKey(FORMATTER_MAP_KEY));
});
} else if (ref.type == AttrMustache) {
if (nodesAttrsDirectives.isEmpty) {
nodeModule.bind(AttrMustache, toFactory: (Injector injector) {
var scope = injector.getByKey(_SCOPE_KEY);
var interpolate = injector.getByKey(_INTERPOLATE_KEY);
var scope = injector.getByKey(SCOPE_KEY);
var interpolate = injector.getByKey(INTERPOLATE_KEY);
for (var ref in nodesAttrsDirectives) {
new AttrMustache(nodeAttrs, ref.value, interpolate, scope,
injector.getByKey(_FORMATTER_MAP_KEY));
injector.getByKey(FORMATTER_MAP_KEY));
}
});
}
Expand All @@ -274,16 +274,16 @@ class ElementBinder {

// Overridden in TemplateElementBinder
void _registerViewFactory(node, parentInjector, nodeModule) {
nodeModule..bindByKey(_VIEW_PORT_KEY, toValue: null)
..bindByKey(_VIEW_FACTORY_KEY, toValue: null)
..bindByKey(_BOUND_VIEW_FACTORY_KEY, toValue: null);
nodeModule..bindByKey(VIEW_PORT_KEY, toValue: null)
..bindByKey(VIEW_FACTORY_KEY, toValue: null)
..bindByKey(BOUND_VIEW_FACTORY_KEY, toValue: null);
}


Injector bind(View view, Injector parentInjector, dom.Node node) {
Injector nodeInjector;
Scope scope = parentInjector.getByKey(_SCOPE_KEY);
FormatterMap formatters = parentInjector.getByKey(_FORMATTER_MAP_KEY);
Scope scope = parentInjector.getByKey(SCOPE_KEY);
FormatterMap formatters = parentInjector.getByKey(FORMATTER_MAP_KEY);
var nodeAttrs = node is dom.Element ? new NodeAttrs(node) : null;
ElementProbe probe;

Expand All @@ -292,12 +292,12 @@ class ElementBinder {

var nodesAttrsDirectives = [];
var nodeModule = new Module()
..bindByKey(_NG_ELEMENT_KEY)
..bindByKey(_VIEW_KEY, toValue: view)
..bindByKey(_ELEMENT_KEY, toValue: node)
..bindByKey(_NODE_KEY, toValue: node)
..bindByKey(_NODE_ATTRS_KEY, toValue: nodeAttrs)
..bindByKey(_ELEMENT_PROBE_KEY, toFactory: (_) => probe);
..bindByKey(NG_ELEMENT_KEY)
..bindByKey(VIEW_KEY, toValue: view)
..bindByKey(ELEMENT_KEY, toValue: node)
..bindByKey(NODE_KEY, toValue: node)
..bindByKey(NODE_ATTRS_KEY, toValue: nodeAttrs)
..bindByKey(ELEMENT_PROBE_KEY, toFactory: (_) => probe);

directiveRefs.forEach((DirectiveRef ref) {
Directive annotation = ref.annotation;
Expand All @@ -318,7 +318,7 @@ class ElementBinder {

nodeInjector = parentInjector.createChild([nodeModule]);
probe = _expando[node] = new ElementProbe(
parentInjector.getByKey(_ELEMENT_PROBE_KEY), node, nodeInjector, scope);
parentInjector.getByKey(ELEMENT_PROBE_KEY), node, nodeInjector, scope);
scope.on(ScopeEvent.DESTROY).listen((_) {_expando[node] = null;});

_link(nodeInjector, probe, scope, nodeAttrs, formatters);
Expand Down
2 changes: 1 addition & 1 deletion lib/core_dom/module_internal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class CoreDomModule extends Module {
bind(ContentPort, toValue: null);
bind(ComponentCssRewriter);
bind(WebPlatform);

bind(Http);
bind(UrlRewriter);
bind(HttpBackend);
Expand Down
59 changes: 32 additions & 27 deletions lib/core_dom/static_keys.dart
Original file line number Diff line number Diff line change
@@ -1,30 +1,35 @@
part of angular.core.dom_internal;
library angular.core_dom.static_keys;

import 'dart:html' as dom;
import 'package:di/di.dart';
import 'package:angular/core/static_keys.dart';
import 'package:angular/core_dom/module_internal.dart';

export 'package:angular/directive/static_keys.dart' show NG_BASE_CSS_KEY;
export 'package:angular/core/static_keys.dart';

// Keys used to call Injector.getByKey and Module.bindByKey

Key _ANIMATE_KEY = new Key(Animate);
Key _BOUND_VIEW_FACTORY_KEY = new Key(BoundViewFactory);
Key _COMPONENT_CSS_REWRITER_KEY = new Key(ComponentCssRewriter);
Key _DIRECTIVE_MAP_KEY = new Key(DirectiveMap);
Key _ELEMENT_KEY = new Key(dom.Element);
Key _ELEMENT_PROBE_KEY = new Key(ElementProbe);
Key _ELEMENT_PROBE = new Key(ElementProbe);
Key _EVENT_HANDLER_KEY = new Key(EventHandler);
Key _FORMATTER_MAP_KEY = new Key(FormatterMap);
Key _HTTP_KEY = new Key(Http);
Key _INTERPOLATE_KEY = new Key(Interpolate);
Key _NG_BASE_CSS_KEY = new Key(NgBaseCss);
Key _NG_ELEMENT_KEY = new Key(NgElement);
Key _NODE_ATTRS_KEY = new Key(NodeAttrs);
Key _NODE_KEY = new Key(dom.Node);
Key _NODE_TREE_SANITIZER_KEY = new Key(dom.NodeTreeSanitizer);
Key _SCOPE_KEY = new Key(Scope);
Key _SHADOW_ROOT_KEY = new Key(dom.ShadowRoot);
Key _TEMPLATE_CACHE_KEY = new Key(TemplateCache);
Key _TEMPLATE_LOADER_KEY = new Key(TemplateLoader);
Key _TEXT_MUSTACHE_KEY = new Key(TextMustache);
Key _VIEW_CACHE_KEY = new Key(ViewCache);
Key _VIEW_FACTORY_KEY = new Key(ViewFactory);
Key _VIEW_KEY = new Key(View);
Key _VIEW_PORT_KEY = new Key(ViewPort);
Key _WEB_PLATFORM_KEY = new Key(WebPlatform);
Key ANIMATE_KEY = new Key(Animate);
Key BOUND_VIEW_FACTORY_KEY = new Key(BoundViewFactory);
Key COMPILER_KEY = new Key(Compiler);
Key COMPONENT_CSS_REWRITER_KEY = new Key(ComponentCssRewriter);
Key DIRECTIVE_MAP_KEY = new Key(DirectiveMap);
Key ELEMENT_KEY = new Key(dom.Element);
Key ELEMENT_PROBE_KEY = new Key(ElementProbe);
Key EVENT_HANDLER_KEY = new Key(EventHandler);
Key HTTP_KEY = new Key(Http);
Key NG_ELEMENT_KEY = new Key(NgElement);
Key NODE_ATTRS_KEY = new Key(NodeAttrs);
Key NODE_KEY = new Key(dom.Node);
Key NODE_TREE_SANITIZER_KEY = new Key(dom.NodeTreeSanitizer);
Key SHADOW_ROOT_KEY = new Key(dom.ShadowRoot);
Key TEMPLATE_CACHE_KEY = new Key(TemplateCache);
Key TEMPLATE_LOADER_KEY = new Key(TemplateLoader);
Key TEXT_MUSTACHE_KEY = new Key(TextMustache);
Key VIEW_CACHE_KEY = new Key(ViewCache);
Key VIEW_FACTORY_KEY = new Key(ViewFactory);
Key VIEW_KEY = new Key(View);
Key VIEW_PORT_KEY = new Key(ViewPort);
Key WEB_PLATFORM_KEY = new Key(WebPlatform);
Key WINDOW_KEY = new Key(dom.Window);
12 changes: 6 additions & 6 deletions lib/core_dom/transcluding_component_factory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,12 @@ class TranscludingComponentFactory implements ComponentFactory {
return (Injector injector) {
var childInjector;
var component = ref.annotation as Component;
Scope scope = injector.get(Scope);
ViewCache viewCache = injector.get(ViewCache);
Http http = injector.get(Http);
TemplateCache templateCache = injector.get(TemplateCache);
DirectiveMap directives = injector.get(DirectiveMap);
NgBaseCss baseCss = injector.get(NgBaseCss);
Scope scope = injector.getByKey(SCOPE_KEY);
ViewCache viewCache = injector.getByKey(VIEW_CACHE_KEY);
Http http = injector.getByKey(HTTP_KEY);
TemplateCache templateCache = injector.getByKey(TEMPLATE_CACHE_KEY);
DirectiveMap directives = injector.getByKey(DIRECTIVE_MAP_KEY);
NgBaseCss baseCss = injector.getByKey(NG_BASE_CSS_KEY);

var contentPort = new ContentPort(element);

Expand Down
6 changes: 2 additions & 4 deletions lib/core_dom/view_factory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@ class BoundViewFactory {

BoundViewFactory(this.viewFactory, this.injector);

static Key _SCOPE_KEY = new Key(Scope);

View call(Scope scope) =>
viewFactory(injector.createChild([new Module()..bindByKey(_SCOPE_KEY, toValue: scope)]));
viewFactory(injector.createChild([new Module()..bindByKey(SCOPE_KEY, toValue: scope)]));
}

abstract class ViewFactory implements Function {
Expand Down Expand Up @@ -51,7 +49,7 @@ class WalkingViewFactory implements ViewFactory {
var timerId;
try {
assert((timerId = _perf.startTimer('ng.view')) != false);
var view = new View(nodes, injector.get(EventHandler));
var view = new View(nodes, injector.getByKey(EVENT_HANDLER_KEY));
_link(view, nodes, elementBinders, injector);
return view;
} finally {
Expand Down
1 change: 1 addition & 0 deletions lib/directive/module.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import 'package:angular/core_dom/module_internal.dart';
import 'package:angular/utils.dart';
import 'package:angular/change_detection/watch_group.dart';
import 'package:angular/change_detection/change_detection.dart';
import 'package:angular/directive/static_keys.dart';

part 'a_href.dart';
part 'ng_base_css.dart';
Expand Down
2 changes: 1 addition & 1 deletion lib/directive/ng_control.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ abstract class NgControl implements AttachAware, DetachAware {

NgControl(NgElement this._element, Injector injector,
Animate this._animate)
: _parentControl = injector.parent.get(NgControl);
: _parentControl = injector.parent.getByKey(NG_CONTROL_KEY);

@override
void attach() {
Expand Down
2 changes: 1 addition & 1 deletion lib/directive/ng_form.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ part of angular.directive;
map: const { 'ng-form': '@name' })
class NgForm extends NgControl {
static final Module _module = new Module()
..bind(NgControl, toFactory: (i) => i.get(NgForm));
..bind(NgControl, toFactory: (i) => i.getByKey(NG_FORM_KEY));
static module() => _module;

final Scope _scope;
Expand Down
2 changes: 1 addition & 1 deletion lib/directive/ng_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,7 @@ class NgBindTypeForDateLike {
module: InputDateLike.moduleFactory)
class InputDateLike {
static Module moduleFactory() => new Module()..bind(NgBindTypeForDateLike,
toFactory: (Injector i) => new NgBindTypeForDateLike(i.get(dom.Element)));
toFactory: (Injector i) => new NgBindTypeForDateLike(i.getByKey(ELEMENT_KEY)));
final dom.InputElement inputElement;
final NgModel ngModel;
final NgModelOptions ngModelOptions;
Expand Down
11 changes: 11 additions & 0 deletions lib/directive/static_keys.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
library angular.directive.static_keys;

import 'package:di/di.dart';
import 'package:angular/directive/module.dart';
import 'package:angular/core_dom/static_keys.dart';

export 'package:angular/core_dom/static_keys.dart';

Key NG_CONTROL_KEY = new Key(NgControl);
Key NG_FORM_KEY = new Key(NgForm);
Key NG_BASE_CSS_KEY = new Key(NgBaseCss);
10 changes: 6 additions & 4 deletions lib/introspection_js.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'dart:js' as js;
import 'package:di/di.dart';
import 'package:angular/introspection.dart';
import 'package:angular/core/module_internal.dart';
import 'package:angular/core/static_keys.dart';
import 'package:angular/core_dom/module_internal.dart';

/**
Expand All @@ -22,16 +23,17 @@ void publishToJavaScript() {
..['ngInjector'] = new js.JsFunction.withThis((_, nodeOrSelector) =>
_jsInjector(ngInjector(nodeOrSelector)))
..['ngScope'] = new js.JsFunction.withThis((_, nodeOrSelector) =>
_jsScope(ngScope(nodeOrSelector), ngProbe(nodeOrSelector).injector.get(ScopeStatsConfig)))
..['ngQuery'] = new js.JsFunction.withThis((_, dom.Node node, String selector, [String containsText]) =>
new js.JsArray.from(ngQuery(node, selector, containsText)));
_jsScope(ngScope(nodeOrSelector),
ngProbe(nodeOrSelector).injector.getByKey(SCOPE_STATS_CONFIG_KEY)))
..['ngQuery'] = new js.JsFunction.withThis((_, dom.Node node, String selector,
[String containsText]) => new js.JsArray.from(ngQuery(node, selector, containsText)));
}

js.JsObject _jsProbe(ElementProbe probe) {
return new js.JsObject.jsify({
"element": probe.element,
"injector": _jsInjector(probe.injector),
"scope": _jsScope(probe.scope, probe.injector.get(ScopeStatsConfig)),
"scope": _jsScope(probe.scope, probe.injector.getByKey(SCOPE_STATS_CONFIG_KEY)),
"directives": probe.directives.map((directive) => _jsDirective(directive))
})..['_dart_'] = probe;
}
Expand Down
3 changes: 2 additions & 1 deletion lib/mock/module.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import 'package:angular/angular.dart';
import 'package:angular/core/module_internal.dart';
import 'package:angular/core_dom/module_internal.dart';
import 'package:angular/core/parser/parser.dart';
import 'package:angular/mock/static_keys.dart';
import 'package:di/di.dart';
import 'package:mock/mock.dart';

Expand Down Expand Up @@ -61,7 +62,7 @@ class AngularMockModule extends Module {
bind(MockHttpBackend);
bind(Element, toValue: document.body);
bind(Node, toValue: document.body);
bind(HttpBackend, toFactory: (Injector i) => i.get(MockHttpBackend));
bind(HttpBackend, toFactory: (Injector i) => i.getByKey(MOCK_HTTP_BACKEND_KEY));
bind(VmTurnZone, toFactory: (_) {
return new VmTurnZone()
..onError = (e, s, LongStackTrace ls) => dump('EXCEPTION: $e\n$s\n$ls');
Expand Down
8 changes: 8 additions & 0 deletions lib/mock/static_keys.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
library angular.mock.static_keys;

import 'package:di/di.dart';
import 'package:angular/mock/module.dart';

export 'package:angular/core_dom/static_keys.dart' show DIRECTIVE_MAP_KEY;

Key MOCK_HTTP_BACKEND_KEY = new Key(MockHttpBackend);
2 changes: 1 addition & 1 deletion lib/mock/test_bed.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class TestBed {
}
rootElement = rootElements.length > 0 && rootElements[0] is Element ? rootElements[0] : null;
if (directives == null) {
directives = injector.get(DirectiveMap);
directives = injector.getByKey(DIRECTIVE_MAP_KEY);
}
rootView = compiler(rootElements, directives)(injector, rootElements);
return rootElement;
Expand Down
Loading

0 comments on commit 149086a

Please sign in to comment.