Skip to content

Commit

Permalink
Various micro optimizations of the component boot flow.
Browse files Browse the repository at this point in the history
  • Loading branch information
cramforce committed Aug 7, 2019
1 parent 5b31760 commit 2384159
Show file tree
Hide file tree
Showing 8 changed files with 633 additions and 21 deletions.
569 changes: 569 additions & 0 deletions examples/lots-of-images.amp.html

Large diffs are not rendered by default.

43 changes: 36 additions & 7 deletions extensions/amp-fx-flying-carpet/0.1/amp-fx-flying-carpet.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@
* limitations under the License.
*/

import {AmpEvents} from '../../../src/amp-events';
import {CSS} from '../../../build/amp-fx-flying-carpet-0.1.css';
import {CommonSignals} from '../../../src/common-signals';
import {Layout} from '../../../src/layout';
import {Services} from '../../../src/services';
import {dev, userAssert} from '../../../src/log';
import {listen} from '../../../src/event-helper';
import {setStyle} from '../../../src/style';

const TAG = 'amp-fx-flying-carpet';
Expand Down Expand Up @@ -107,7 +106,7 @@ export class AmpFlyingCarpet extends AMP.BaseElement {
this.element,
this.children_
);
listen(this.element, AmpEvents.BUILT, this.layoutBuiltChild_.bind(this));
this.observeNewChildren_();
}
}

Expand Down Expand Up @@ -167,20 +166,50 @@ export class AmpFlyingCarpet extends AMP.BaseElement {
this.element,
this.children_
);
listen(this.element, AmpEvents.BUILT, this.layoutBuiltChild_.bind(this));
this.observeNewChildren_();
this.firstLayoutCompleted_ = true;
return Promise.resolve();
}

/**
* Makes sure we schedule layout for elements as they are added
* to the flying carpet.
* @private
*/
observeNewChildren_() {
const observer = new MutationObserver(changes => {
for (let i = 0; i < changes.length; i++) {
const {addedNodes} = changes[i];
if (!addedNodes) {
continue;
}
for (let n = 0; n < addedNodes.length; n++) {
const node = addedNodes[n];
if (!node.signals) {
return;
}
node
.signals()
.whenSignal(CommonSignals.BUILT)
.then(this.layoutBuiltChild_.bind(this, node));
}
}
});
observer.observe(this.element, {
childList: true,
subtree: true,
});
}

/**
* Listens for children element to be built, and schedules their layout.
* Necessary since not all children will be built by the time the
* flying-carpet has its #layoutCallback called.
* @param {!Event} event
* @param {!Node} node
* @private
*/
layoutBuiltChild_(event) {
const child = dev().assertElement(event.target);
layoutBuiltChild_(node) {
const child = dev().assertElement(node);
if (child.getOwner() === this.element) {
Services.ownersForDoc(this.element).scheduleLayout(this.element, child);
}
Expand Down
1 change: 0 additions & 1 deletion src/amp-events.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
* @enum {string}
*/
export const AmpEvents = {
BUILT: 'amp:built',
DOM_UPDATE: 'amp:dom-update',
FORM_DIRTINESS_CHANGE: 'amp:form-dirtiness-change',
FORM_VALUE_CHANGE: 'amp:form-value-change',
Expand Down
5 changes: 3 additions & 2 deletions src/base-element.js
Original file line number Diff line number Diff line change
Expand Up @@ -678,8 +678,9 @@ export class BaseElement {
attributes = isArray(attributes) ? attributes : [attributes];
for (let i = 0; i < attributes.length; i++) {
const attr = attributes[i];
if (this.element.hasAttribute(attr)) {
element.setAttribute(attr, this.element.getAttribute(attr));
const val = this.element.getAttribute(attr);
if (val !== null) {
element.setAttribute(attr, val);
} else if (opt_removeMissingAttrs) {
element.removeAttribute(attr);
}
Expand Down
11 changes: 6 additions & 5 deletions src/custom-element.js
Original file line number Diff line number Diff line change
Expand Up @@ -803,9 +803,11 @@ function createBaseCustomElementClass(win) {
this.isConnected_ = true;

if (!this.everAttached) {
this.classList.add('i-amphtml-element');
this.classList.add('i-amphtml-notbuilt');
this.classList.add('amp-notbuilt');
this.classList.add(
'i-amphtml-element',
'i-amphtml-notbuilt',
'amp-notbuilt'
);
}

if (!this.ampdoc_) {
Expand Down Expand Up @@ -862,8 +864,7 @@ function createBaseCustomElementClass(win) {
this.tryUpgrade_();
}
if (!this.isUpgraded()) {
this.classList.add('amp-unresolved');
this.classList.add('i-amphtml-unresolved');
this.classList.add('amp-unresolved', 'i-amphtml-unresolved');
// amp:attached is dispatched from the ElementStub class when it
// replayed the firstAttachedCallback call.
this.dispatchCustomEventForTesting(AmpEvents.STUBBED);
Expand Down
11 changes: 10 additions & 1 deletion src/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,16 @@ export function getParentWindow(win) {
* @return {!Window}
*/
export function getTopWindow(win) {
return win.__AMP_TOP || win;
const top = win.__AMP_TOP;
if (top === null) {
return win;
}
if (top != null) {
return top;
}
// Make this defined but null to speed up future lookups.
win.__AMP_TOP = null;
return win;
}

/**
Expand Down
10 changes: 9 additions & 1 deletion src/service/ampdoc-impl.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ export class AmpDocService {

/** @private {boolean} */
this.ampdocFieExperimentOn_ = isExperimentOn(win, 'ampdoc-fie');

/** @private {boolean} */
this.mightHaveShadowRoots_ = !isSingleDoc;
}

/**
Expand Down Expand Up @@ -149,6 +152,10 @@ export class AmpDocService {
continue;
}

if (!this.mightHaveShadowRoots_) {
break;
}

// Shadow doc.
const shadowRoot =
n.nodeType == /* DOCUMENT */ 9 ? n : getShadowRootNode(n);
Expand Down Expand Up @@ -203,6 +210,7 @@ export class AmpDocService {
* @restricted
*/
installShadowDoc(url, shadowRoot) {
this.mightHaveShadowRoots_ = true;
devAssert(
!shadowRoot[AMPDOC_PROP],
'The shadow root already contains ampdoc'
Expand All @@ -213,7 +221,7 @@ export class AmpDocService {
}

/**
* Creates and installs the ampdoc for the shadow root.
* Creates and installs the ampdoc for the fie root.
* @param {string} url
* @param {!Window} childWin
* @param {!AmpDocOptions=} opt_options
Expand Down
4 changes: 0 additions & 4 deletions src/service/resource.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
* limitations under the License.
*/

import {AmpEvents} from '../amp-events';
import {Deferred, tryResolve} from '../utils/promise';
import {Layout} from '../layout';
import {Services} from '../services';
Expand Down Expand Up @@ -340,9 +339,6 @@ export class Resource {
}
// TODO(dvoytenko): merge with the standard BUILT signal.
this.element.signals().signal('res-built');
// TODO(dvoytenko, #7389): cleanup once amp-sticky-ad signals are
// in PROD.
this.element.dispatchCustomEvent(AmpEvents.BUILT);
},
reason => {
this.maybeReportErrorOnBuildFailure(reason);
Expand Down

0 comments on commit 2384159

Please sign in to comment.