2.x - Performance optimizations geared towards legacy Polymer({...}) use#5418
2.x - Performance optimizations geared towards legacy Polymer({...}) use#5418kevinpschaaf merged 42 commits into2.xfrom
Polymer({...}) use#5418Conversation
Set using `Polymer.setLegacyOptimizations(true)`. This flag enables optimizaitons including, always stripping whitespace from templates and avoiding cloning element templates (assumes no inheritance is used) Also re-enables dir-mixin.
* fix issue where registered was called on element instance instead of prototype * fix issue where applyListeners was called in constructor rather than initializeProperties; this made `disable-upgrade` mixin not properly work with litsners.
lib/mixins/element-mixin.html
Outdated
| templateStyle.parentNode.insertBefore(s, templateStyle); | ||
| } else { | ||
| templateStyleIndex++; | ||
| if (!window.skipStyleIncludesAndUrls) { |
There was a problem hiding this comment.
Rather than putting this on window, shouldn't we put this in the Polymer.Settings object?
There was a problem hiding this comment.
Oops, thanks. Going to get this window.ShadyCSS.cssBuild being set (which will shortly be added to ShadyCSS.
| }); | ||
|
|
||
| test('elements upgrade when `disable-upgrade` removed', function() { | ||
| assert.notOk(el.$.disabledEl.hasCreated); |
There was a problem hiding this comment.
Can we not remove these assertions or are they regressions? Are they a breaking change for our users?
There was a problem hiding this comment.
These were actually duplicate assertions from the previous test (https://github.com/Polymer/polymer/pull/5418/files#diff-ed6f0a354a50488549e9b8ea17788d86R240) that were incorrectly being tested again.
test/unit/mixin-behaviors.html
Outdated
|
|
||
| test('nested-behavior dedups', function() { | ||
| assert.equal(el.behaviors.length, 4); | ||
| assert.equal(el.behaviors.length, 2); |
There was a problem hiding this comment.
This also seems like a regression to me. Are we sure users will not run into any breaking changes?
There was a problem hiding this comment.
It's not a regression since the test changed, but the behavior is weird and I think we should change it.
We didn't have a test where Polymer.mixinBehaviors was called on a legacy element with behaviors (since this is pretty exotic) and this test was just updated to do that.
When that happens, the behaviors list is set to the subclasses' list of behaviors. However, the "active" set of behaviors on the element is the de-duplicated flat list of all behaviors on anything in the prototype chain. Given that, it seems like .behaviors should be this de-duplicated flattened list of "active" behaviors. We can make that change and update the test.
* Uses `window.ShadyCSS.cssBuild` to avoid doing unnecessary work in `processElementStyles` * Stores the list of active in-use behaviors in a legacy element's `behaviors` property. This only matters in the exotic case when elements with behaviors are extended with more behaviors and previously the list included only the subclasses behaviors (although the element otherwise worked as expected).
Also use exclusively in `properties-mixin`
IE/older Safari require all arguments.
Polymer({...}) usePolymer({...}) use
lib/legacy/class.html
Outdated
| GenerateClassFromInfo(b, klass); | ||
| function copyBehaviorProperties(behaviors, klass) { | ||
| const meta = {}; | ||
| const superMeta = klass.prototype.__behaviorMetaProps; |
There was a problem hiding this comment.
Since these are all lifecycle-related, maybe __behaviorCallbacks would be better than something with "props" in it, since that's sort of overloaded with all the data stuff.
lib/legacy/class.html
Outdated
| */ | ||
| created() { | ||
| super.created(); | ||
| const list = this.__behaviorMetaProps.created; |
There was a problem hiding this comment.
Consider adding info. from the base info to the list?
lib/legacy/class.html
Outdated
| mergeProperties(properties, b.properties); | ||
| } | ||
| } | ||
| mergeProperties(properties, info.properties); |
There was a problem hiding this comment.
It seemed like a possible optimization to skip the mergeProperties step from the base info object into an empty object; it seems superfulous for the initial class -- but then I realized this was required for the computed to readOnly coersion and the shorthand type expansion. So that was not intuitive, maybe due to the naming? Suggest different name or at least a comment.
lib/legacy/class.html
Outdated
| klass.prototype.__behaviorMetaProps = meta; | ||
| } | ||
|
|
||
| function memoizeBehaviorMetaProps(meta, behavior, superMeta) { |
There was a problem hiding this comment.
There's a bug here where the full flattened list of lifecycle callbacks is called once per call to GenerateClassFromInfo, which happens each time mixinBehaviors is called.
Instead, store the list of callbacks in the closure for one set of behaviors associated with each call to GenerateClassFromInfo.
There was a problem hiding this comment.
Fixed and test added.
lib/legacy/class.html
Outdated
| `is` in `beforeRegister` as you could in 1.x. | ||
| */ | ||
| const proto = this; | ||
| if (proto.hasOwnProperty('__behaviors')) { |
There was a problem hiding this comment.
This is just what's in the closure, i.e.
if (behaviors) {
lib/legacy/class.html
Outdated
| behaviors: true | ||
| }, metaProps); | ||
|
|
||
| const memoizedProps = Object.assign({ |
There was a problem hiding this comment.
Naming of these is confusing. Consider "memoized" --> "filtered"
| HTMLImports.whenReady(function() { | ||
| customElements.define('nested-behaviors', | ||
| class extends Polymer.mixinBehaviors( | ||
| class extends Polymer.mixinBehaviors([window.BehaviorD, window.LifeCycleBehavior1], Polymer.mixinBehaviors( |
There was a problem hiding this comment.
Add assertions for BehaviorD?
|
Also maybe add a test like const b1 = { ready() {..} };
const b2 = { ready() {..} };
const b3 = { ready() {..} };
const b4 = { ready() {..} };
const sup = Polymer({is: 'sup', behaviors: [b1, b2], ready() {..} })
class sub extends mixinBehaviors([b3,b4], sup) { ready() {..} }And verify that the lifecycle order goes: |
This ensures it's not called on extendors who do not specifically implement `_registered`. This is important since it's expected to do prototype specific work.
This better matches what Polymer 1.x did for: * hostAttributes * listeners * properties * observers
…present. This ensures ShadyCSS scoping classes are not removed when a class binding's initial literal value is set.
* ensure element has `is` on prototype early as this is sometimes checked in user code. * ensure properties copied onto elements from info/behaviors are forced to configurable so they can be re-configured by later behaviors. * add `_noAccessors` optimization for faster property copying
Previously, it could be called on a superclass' prototype and not the element's prototype.
* When extended, a behavior `registered` is always called on sub-most prototype rather than the prototype on which `registered` was defined. * behavior property default values are overwritten by later behaviors and elements * readOnly properties ignored when a previous behavior observes the property * observedAttributes when extended
* Don't set up observer in ShadyDOM * Move __activateDir into check instead of replace * skip some tests that never really worked in ShadyDOM
Polymer.legacyOptimizationsflag which avoids copying element templates (needed for subclassing) and turns onstripWhitespacefor all templates.Polymer.telemetry: now properly records registered elements, even if they have not been created