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

Commit 9f0c7bc

Browse files
committed
perf(compiler): An option to disable the ElementProbe.
Closes #1118 Closes #1131
1 parent c6fcc74 commit 9f0c7bc

9 files changed

+118
-30
lines changed

lib/core/module.dart

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export "package:angular/core_dom/module_internal.dart" show
2828
BrowserCookies,
2929
Cache,
3030
Compiler,
31+
CompilerConfig,
3132
Cookies,
3233
BoundViewFactory,
3334
DirectiveMap,

lib/core_dom/compiler_config.dart

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
part of angular.core.dom_internal;
2+
3+
/**
4+
* Global configuration options for the Compiler
5+
*/
6+
@Injectable()
7+
class CompilerConfig {
8+
/**
9+
* True if the compiler should add ElementProbes to the elements.
10+
*/
11+
final bool elementProbeEnabled;
12+
13+
CompilerConfig() : elementProbeEnabled = true;
14+
CompilerConfig.withOptions({this.elementProbeEnabled: true});
15+
}

lib/core_dom/element_binder.dart

+20-9
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ class TemplateElementBinder extends ElementBinder {
1414
return _directiveCache = [template];
1515
}
1616

17-
TemplateElementBinder(perf, expando, parser, componentFactory,
17+
TemplateElementBinder(perf, expando, parser, config, componentFactory,
1818
transcludingComponentFactory, shadowDomComponentFactory,
1919
this.template, this.templateBinder,
2020
onEvents, bindAttrs, childMode)
21-
: super(perf, expando, parser, componentFactory,
21+
: super(perf, expando, parser, config, componentFactory,
2222
transcludingComponentFactory, shadowDomComponentFactory,
2323
null, null, onEvents, bindAttrs, childMode);
2424

@@ -45,6 +45,7 @@ class ElementBinder {
4545
final Profiler _perf;
4646
final Expando _expando;
4747
final Parser _parser;
48+
final CompilerConfig _config;
4849

4950
// The default component factory
5051
final ComponentFactory _componentFactory;
@@ -61,7 +62,7 @@ class ElementBinder {
6162
// Can be either COMPILE_CHILDREN or IGNORE_CHILDREN
6263
final String childMode;
6364

64-
ElementBinder(this._perf, this._expando, this._parser,
65+
ElementBinder(this._perf, this._expando, this._parser, this._config,
6566
this._componentFactory,
6667
this._transcludingComponentFactory,
6768
this._shadowDomComponentFactory,
@@ -207,7 +208,9 @@ class ElementBinder {
207208
void _link(nodeInjector, probe, scope, nodeAttrs) {
208209
_usableDirectiveRefs.forEach((DirectiveRef ref) {
209210
var directive = nodeInjector.getByKey(ref.typeKey);
210-
probe.directives.add(directive);
211+
if (probe != null) {
212+
probe.directives.add(directive);
213+
}
211214

212215
if (ref.annotation is Controller) {
213216
scope.context[(ref.annotation as Controller).publishAs] = directive;
@@ -295,8 +298,11 @@ class ElementBinder {
295298
..bindByKey(VIEW_KEY, toValue: view)
296299
..bindByKey(ELEMENT_KEY, toValue: node)
297300
..bindByKey(NODE_KEY, toValue: node)
298-
..bindByKey(NODE_ATTRS_KEY, toValue: nodeAttrs)
299-
..bindByKey(ELEMENT_PROBE_KEY, toFactory: (_) => probe);
301+
..bindByKey(NODE_ATTRS_KEY, toValue: nodeAttrs);
302+
303+
if (_config.elementProbeEnabled) {
304+
nodeModule.bindByKey(ELEMENT_PROBE_KEY, toFactory: (_) => probe);
305+
}
300306

301307
directiveRefs.forEach((DirectiveRef ref) {
302308
Directive annotation = ref.annotation;
@@ -316,9 +322,14 @@ class ElementBinder {
316322
_registerViewFactory(node, parentInjector, nodeModule);
317323

318324
nodeInjector = parentInjector.createChild([nodeModule]);
319-
probe = _expando[node] = new ElementProbe(
320-
parentInjector.getByKey(ELEMENT_PROBE_KEY), node, nodeInjector, scope);
321-
scope.on(ScopeEvent.DESTROY).listen((_) {_expando[node] = null;});
325+
if (_config.elementProbeEnabled) {
326+
probe = _expando[node] =
327+
new ElementProbe(parentInjector.getByKey(ELEMENT_PROBE_KEY),
328+
node, nodeInjector, scope);
329+
scope.on(ScopeEvent.DESTROY).listen((_) {
330+
_expando[node] = null;
331+
});
332+
}
322333

323334
_link(nodeInjector, probe, scope, nodeAttrs);
324335

lib/core_dom/element_binder_builder.dart

+7-4
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,30 @@ part of angular.core.dom_internal;
44
class ElementBinderFactory {
55
final Parser _parser;
66
final Profiler _perf;
7+
final CompilerConfig _config;
78
final Expando _expando;
89
final ComponentFactory _componentFactory;
910
final TranscludingComponentFactory _transcludingComponentFactory;
1011
final ShadowDomComponentFactory _shadowDomComponentFactory;
1112
final ASTParser _astParser;
1213

13-
ElementBinderFactory(this._parser, this._perf, this._expando, this._componentFactory,
14-
this._transcludingComponentFactory, this._shadowDomComponentFactory,
14+
ElementBinderFactory(this._parser, this._perf, this._config, this._expando,
15+
this._componentFactory,
16+
this._transcludingComponentFactory,
17+
this._shadowDomComponentFactory,
1518
this._astParser);
1619

1720
// TODO: Optimize this to re-use a builder.
1821
ElementBinderBuilder builder(FormatterMap formatters) =>
1922
new ElementBinderBuilder(this, _astParser, formatters);
2023

2124
ElementBinder binder(ElementBinderBuilder b) =>
22-
new ElementBinder(_perf, _expando, _parser, _componentFactory,
25+
new ElementBinder(_perf, _expando, _parser, _config, _componentFactory,
2326
_transcludingComponentFactory, _shadowDomComponentFactory,
2427
b.component, b.decorators, b.onEvents, b.bindAttrs, b.childMode);
2528

2629
TemplateElementBinder templateBinder(ElementBinderBuilder b, ElementBinder transclude) =>
27-
new TemplateElementBinder(_perf, _expando, _parser, _componentFactory,
30+
new TemplateElementBinder(_perf, _expando, _parser, _config, _componentFactory,
2831
_transcludingComponentFactory, _shadowDomComponentFactory,
2932
b.template, transclude, b.onEvents, b.bindAttrs, b.childMode);
3033
}

lib/core_dom/module_internal.dart

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ part 'view_factory.dart';
2727
part 'cookies.dart';
2828
part 'common.dart';
2929
part 'compiler.dart';
30+
part 'compiler_config.dart';
3031
part 'directive.dart';
3132
part 'directive_map.dart';
3233
part 'element_binder.dart';
@@ -60,6 +61,7 @@ class CoreDomModule extends Module {
6061
bind(AttrMustache);
6162

6263
bind(Compiler, toImplementation: TaggingCompiler);
64+
bind(CompilerConfig);
6365

6466
bind(ComponentFactory, toImplementation: ShadowDomComponentFactory);
6567
bind(ShadowDomComponentFactory);

lib/core_dom/shadow_dom_component_factory.dart

+20-8
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ abstract class ComponentFactory {
2828
@Injectable()
2929
class ShadowDomComponentFactory implements ComponentFactory {
3030
final Expando _expando;
31+
final CompilerConfig _config;
3132

32-
ShadowDomComponentFactory(this._expando);
33+
ShadowDomComponentFactory(this._expando, this._config);
3334

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

@@ -53,7 +54,8 @@ class ShadowDomComponentFactory implements ComponentFactory {
5354
injector.getByKey(COMPONENT_CSS_REWRITER_KEY),
5455
_expando,
5556
baseCss,
56-
_styleElementCache);
57+
_styleElementCache,
58+
_config);
5759
var controller = componentFactory.call(injector, scope, viewCache, http, templateCache,
5860
directives);
5961

@@ -81,6 +83,7 @@ class _ComponentFactory implements Function {
8183
_styleElementCache;
8284
final ComponentCssRewriter componentCssRewriter;
8385
final WebPlatform platform;
86+
final CompilerConfig _config;
8487

8588
dom.ShadowRoot shadowDom;
8689
Scope shadowScope;
@@ -89,7 +92,7 @@ class _ComponentFactory implements Function {
8992

9093
_ComponentFactory(this.element, this.typeKey, this.component, this.treeSanitizer,
9194
this.platform, this.componentCssRewriter, this._expando,
92-
this._baseCss, this._styleElementCache);
95+
this._baseCss, this._styleElementCache, this._config);
9396

9497
dynamic call(Injector injector, Scope scope,
9598
ViewCache viewCache, Http http, TemplateCache templateCache,
@@ -187,12 +190,21 @@ class _ComponentFactory implements Function {
187190
..bindByKey(EVENT_HANDLER_KEY, toImplementation: ShadowRootEventHandler)
188191
..bindByKey(SCOPE_KEY, toValue: shadowScope)
189192
..bindByKey(TEMPLATE_LOADER_KEY, toValue: templateLoader)
190-
..bindByKey(SHADOW_ROOT_KEY, toValue: shadowDom)
191-
..bindByKey(ELEMENT_PROBE_KEY, toFactory: (_) => probe);
193+
..bindByKey(SHADOW_ROOT_KEY, toValue: shadowDom);
194+
if (_config.elementProbeEnabled) {
195+
shadowModule.bindByKey(ELEMENT_PROBE_KEY, toFactory: (_) => probe);
196+
}
197+
192198
shadowInjector = injector.createChild([shadowModule], name: SHADOW_DOM_INJECTOR_NAME);
193-
probe = _expando[shadowDom] = new ElementProbe(
194-
injector.getByKey(ELEMENT_PROBE_KEY), shadowDom, shadowInjector, shadowScope);
195-
shadowScope.on(ScopeEvent.DESTROY).listen((ScopeEvent) {_expando[shadowDom] = null;});
199+
200+
if (_config.elementProbeEnabled) {
201+
probe = _expando[shadowDom] =
202+
new ElementProbe(injector.getByKey(ELEMENT_PROBE_KEY),
203+
shadowDom, shadowInjector, shadowScope);
204+
shadowScope.on(ScopeEvent.DESTROY).listen((ScopeEvent) {
205+
_expando[shadowDom] = null;
206+
});
207+
}
196208
return shadowInjector;
197209
}
198210
}

lib/core_dom/transcluding_component_factory.dart

+7-3
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,9 @@ class ContentPort {
7171
@Injectable()
7272
class TranscludingComponentFactory implements ComponentFactory {
7373
final Expando _expando;
74+
final CompilerConfig _config;
7475

75-
TranscludingComponentFactory(this._expando);
76+
TranscludingComponentFactory(this._expando, this._config);
7677

7778
FactoryFn call(dom.Node node, DirectiveRef ref) {
7879
// CSS is not supported.
@@ -116,8 +117,11 @@ class TranscludingComponentFactory implements ComponentFactory {
116117
..bind(ContentPort, toValue: contentPort)
117118
..bind(Scope, toValue: shadowScope)
118119
..bind(TemplateLoader, toValue: templateLoader)
119-
..bind(dom.ShadowRoot, toValue: new ShadowlessShadowRoot(element))
120-
..bind(ElementProbe, toFactory: (_) => probe);
120+
..bind(dom.ShadowRoot, toValue: new ShadowlessShadowRoot(element));
121+
122+
if (_config.elementProbeEnabled) {
123+
childModule.bind(ElementProbe, toFactory: (_) => probe);
124+
}
121125
childInjector = injector.createChild([childModule], name: SHADOW_DOM_INJECTOR_NAME);
122126

123127
var controller = childInjector.get(ref.type);

test/angular_spec.dart

+1
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ main() {
115115
"angular.core.dom_internal.BoundViewFactory",
116116
"angular.core.dom_internal.BrowserCookies",
117117
"angular.core.dom_internal.Compiler",
118+
"angular.core.dom_internal.CompilerConfig",
118119
"angular.core.dom_internal.Cookies",
119120
"angular.core.dom_internal.DirectiveMap",
120121
"angular.core.dom_internal.ElementProbe",

test/core_dom/compiler_spec.dart

+45-6
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,24 @@ forBothCompilers(fn) {
99
m.bind(Compiler, toImplementation: WalkingCompiler);
1010
return m;
1111
});
12-
fn();
12+
fn('walking');
1313
});
1414

1515
describe('tagging compiler', () {
1616
beforeEachModule((Module m) {
1717
m.bind(Compiler, toImplementation: TaggingCompiler);
1818
return m;
1919
});
20-
fn();
20+
fn('tagging');
21+
});
22+
23+
describe('tagging compiler with ElementProbe disabled', () {
24+
beforeEachModule((Module m) {
25+
m.bind(Compiler, toImplementation: TaggingCompiler);
26+
m.bind(CompilerConfig, toValue: new CompilerConfig.withOptions(elementProbeEnabled: false));
27+
return m;
28+
});
29+
fn('tagging-no-elementProbe');
2130
});
2231
}
2332

@@ -31,12 +40,12 @@ forAllCompilersAndComponentFactories(fn) {
3140

3241
return m;
3342
});
34-
fn();
43+
fn('transcluding');
3544
});
3645
}
3746

3847
void main() {
39-
forBothCompilers(() =>
48+
forBothCompilers((compilerType) =>
4049
describe('TranscludingComponentFactory', () {
4150
TestBed _;
4251

@@ -59,7 +68,7 @@ void main() {
5968
}));
6069
}));
6170

62-
forAllCompilersAndComponentFactories(() =>
71+
forAllCompilersAndComponentFactories((compilerType) =>
6372
describe('dte.compiler', () {
6473
TestBed _;
6574

@@ -357,6 +366,8 @@ void main() {
357366
}));
358367

359368
it('should store ElementProbe with Elements', async(() {
369+
if (compilerType == 'tagging-no-elementProbe') return;
370+
360371
_.compile('<div><simple>innerText</simple></div>');
361372
microLeap();
362373
_.rootScope.apply();
@@ -368,14 +379,40 @@ void main() {
368379
var shadowRoot = simpleElement.shadowRoot;
369380

370381
// If there is no shadow root, skip this.
371-
if (shadowRoot != null) {
382+
if (compilerType != 'transcluding') {
372383
var shadowProbe = ngProbe(shadowRoot);
373384
expect(shadowProbe).toBeNotNull();
374385
expect(shadowProbe.element).toEqual(shadowRoot);
375386
expect(shadowProbe.parent.element).toEqual(simpleElement);
376387
}
377388
}));
378389

390+
describe('elementProbeEnabled option', () {
391+
beforeEachModule((Module m) {
392+
m.bind(CompilerConfig, toValue:
393+
new CompilerConfig.withOptions(elementProbeEnabled: false));
394+
});
395+
396+
it('should not store ElementProbe with Elements', async(() {
397+
_.compile('<div><simple>innerText</simple></div>');
398+
microLeap();
399+
_.rootScope.apply();
400+
var simpleElement = _.rootElement.querySelector('simple');
401+
expect(simpleElement).toHaveText('INNER(innerText)');
402+
403+
expect(() => ngProbe(simpleElement))
404+
.toThrow("Could not find a probe for the node 'simple' nor its parents");
405+
406+
var shadowRoot = simpleElement.shadowRoot;
407+
408+
// If there is no shadow root, skip this.
409+
if (compilerType != 'transcluding') {
410+
expect(() => ngProbe(shadowRoot))
411+
.toThrow("Could not find a probe for the node 'Instance of 'ShadowRoot'' nor its parents");
412+
}
413+
}));
414+
});
415+
379416
it('should create a simple component', async((VmTurnZone zone) {
380417
_.rootScope.context['name'] = 'OUTTER';
381418
var element = _.compile(r'<div>{{name}}:<simple>{{name}}</simple></div>');
@@ -737,6 +774,8 @@ void main() {
737774
}));
738775

739776
describe('expando memory', () {
777+
if (compilerType == 'tagging-no-elementProbe') return;
778+
740779
Expando expando;
741780

742781
beforeEach(inject((Expando _expando) => expando = _expando));

0 commit comments

Comments
 (0)