[BUGFIX beta] Avoid creating enumerable properties on all objects created by DI.#15177
Conversation
67f6b55 to
34daea8
Compare
|
Did a quick benchmark via ember-macro-benchmark to see if this has an effect on perf and it looks pretty good to me. @krisselden / @stefanpenner - Mind confirming my interpretation? Raw data: results-pr-15177.zip |
|
I chatted with @krisselden in slack about the results, we came to roughly the same conclusion. That the changes in this PR do not reject the null hypothesis (that the variance between control and experiment are random) and therefore these changes do not represent a change in the performance profile of the application under test (emberaddons.com in this case). |
|
Changes like this (changing the |
stefanpenner
left a comment
There was a problem hiding this comment.
looks good, left some nit-picks.
packages/container/lib/container.js
Outdated
| // the customized toString, _debugContainerKey, | ||
| // owner, etc. without a double extend and without | ||
| // modifying the objects properties | ||
| if (this.class._initFactory) { |
There was a problem hiding this comment.
typeof this.class._initFactory === 'function' (more correct, and makes the JIT happy)
| let extension = hasToStringExtension ? `:${this.toStringExtension()}` : ''; | ||
| let ret = `<${this[NAME_KEY] || this.constructor.toString()}:${guidFor(this)}${extension}>`; | ||
|
|
||
| let m = meta(this); |
There was a problem hiding this comment.
550 and 551 are only required if this[NAME_KEY] isn't set, and it will be set most of the time. Can we avoid 550 and 551 unless we need to access it?
something like:
this[NAME_KEY] || meta(this).getFactory() || this.cosntructor.toString()
packages/ember-metal/lib/meta.js
Outdated
| } | ||
| } | ||
|
|
||
| setFactory(factory) { |
There was a problem hiding this comment.
Any preference to function accessors vs normal accessors? I can be fine with either, was just surprised this isn't a accessor and am curious if there was a reason for it
There was a problem hiding this comment.
get / set seem fine to me, I just slightly dislike the babel transpilation (which requires the createClass helper):
// input
class Foo {
get derp() { }
set derp(value) { }
}
// output
var Foo = function () {
function Foo() {
_classCallCheck(this, Foo);
}
_createClass(Foo, [{
key: "derp",
get: function get() {},
set: function set(value) {}
}]);
return Foo;
}();| } | ||
|
|
||
| let meta = peekMeta(this); | ||
| let factory = meta.getFactory(); |
There was a problem hiding this comment.
if we peekMeta meta may be undefined so we must guard before accessing getFactory
something like:
let meta = peekMeta(this)
if (meta === undefined) { return; }
let factory = meta.getFactory();
if (factory === undefined) { return ; }
return factory.fullName;| return factory && factory.owner; | ||
| }, | ||
|
|
||
| // we need a setter here largely to support the legacy |
There was a problem hiding this comment.
ah, so this [OVERRIDE_OWNER] both in the setter and getter can be removed once the legacy support is dropped?
There was a problem hiding this comment.
confirm, OVERRIDE_OWNER is only for deprecated container setter
| return this[OVERRIDE_OWNER]; | ||
| } | ||
|
|
||
| let meta = peekMeta(this); |
There was a problem hiding this comment.
Is it possible to have a ember-object without a meta? As we create its meta during within its constructor.
There was a problem hiding this comment.
it is not possible for it not to exists
There was a problem hiding this comment.
isn't it a tad strange to use peekMeta instead of meta ? But i'm fine if you are.
| return this[OVERRIDE_CONTAINER_KEY]; | ||
| } | ||
|
|
||
| let meta = peekMeta(this); |
There was a problem hiding this comment.
Is it possible to have a ember-object without a meta? As we create its meta during within its constructor.
| return this[OVERRIDE_OWNER]; | ||
| } | ||
|
|
||
| let meta = peekMeta(this); |
There was a problem hiding this comment.
it is not possible for it not to exists
| return factory && factory.owner; | ||
| }, | ||
|
|
||
| // we need a setter here largely to support the legacy |
There was a problem hiding this comment.
confirm, OVERRIDE_OWNER is only for deprecated container setter
…ated by DI. Prior to these changes, every object created via `owner.factoryFor(...).create()` was populated with `NAME_KEY`, `_debugContainerKey`, and `OWNER`. After these changes: * For `Ember.Object`'s, only actual injections are included in the create arguments. * For non-`Ember.Object`'s, only `OWNER` is included in the create arguments. `OWNER` is still provided for non-`Ember.Object`'s in order to support various classes that are used in the rendering layer that expect to be passed `options[OWNER]` so they can function properly. Examples are `ember-glimmer/environment` and `ember-glimmer/template`. These should be refactored away from `OWNER` being passed in, and this fallback should be removed. A handful of tests were added / updated. In some cases `_debugContainerKey` assertions were removed, since this is no longer supported configuration (e.g. there is no way to inject `_debugContainerKey` onto the class itself without double extend).
34daea8 to
652adee
Compare
|
Addressed concerns:
Anything else? |

Prior to these changes, every object created via
owner.factoryFor(...).create()was populated withNAME_KEY,_debugContainerKey, andOWNER.After these changes:
Ember.Object's, only actual injections are included in the create arguments.Ember.Object's, onlyOWNERis included in the create arguments.OWNERis still provided for non-Ember.Object's in order to support various classes that are used in the rendering layer that expect to be passedoptions[OWNER]so they can function properly. Examples areember-glimmer/environmentandember-glimmer/template. These should be refactored away fromOWNERbeing passed in, and this fallback should be removed.A handful of tests were added / updated. In some cases
_debugContainerKeyassertions were removed, since this is no longer supported configuration (e.g. there is no way to inject_debugContainerKeyonto the class itself without double extend).