From a007320a9f01f86e3029eb60f1dd915a90807bcd Mon Sep 17 00:00:00 2001 From: Kristofer Baxter Date: Tue, 11 Feb 2020 16:05:33 -0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=80=20Remove=20older=20performance=20i?= =?UTF-8?q?nfo=20(#26711)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Remove older Performance information capturing * Remove unused function * Remove support for < Chromium 77 capturing FID * Additional cleanup --- src/service/performance-impl.js | 172 ++++------------------- test/unit/test-performance.js | 235 +------------------------------- 2 files changed, 28 insertions(+), 379 deletions(-) diff --git a/src/service/performance-impl.js b/src/service/performance-impl.js index b776d33ab267..94e75fe22b49 100644 --- a/src/service/performance-impl.js +++ b/src/service/performance-impl.js @@ -101,13 +101,6 @@ export class Performance { this.fcpDeferred_.resolve(null); } - /** - * How many times a layout jank metric has been ticked. - * - * @private {number} - */ - this.jankScoresTicked_ = 0; - /** * How many times a layout shift metric has been ticked. * @@ -115,14 +108,6 @@ export class Performance { */ this.shiftScoresTicked_ = 0; - /** - * The sum of all layout jank fractions triggered on the page from the - * Layout Jank API. - * - * @private {number} - */ - this.aggregateJankScore_ = 0; - /** * The sum of all layout shift fractions triggered on the page from the * Layout Instability API. @@ -131,66 +116,34 @@ export class Performance { */ this.aggregateShiftScore_ = 0; + const supportedEntryTypes = + (this.win.PerformanceObserver && + this.win.PerformanceObserver.supportedEntryTypes) || + []; /** * Whether the user agent supports the Layout Instability API that shipped - * with Chrome 76. - * - * @private {boolean} - */ - this.supportsLayoutInstabilityAPIv76_ = false; - - /** - * Whether the user agent supports the Layout Instability API that shipped - * with Chrome 77. - * - * @private {boolean} - */ - this.supportsLayoutInstabilityAPIv77_ = false; - - /** - * Whether the user agent supports the Event Timing API that shipped - * with Chrome 76. + * with Chromium 77. * * @private {boolean} */ - this.supportsEventTimingAPIv76_ = false; + this.supportsLayoutShift_ = supportedEntryTypes.includes('layout-shift'); /** * Whether the user agent supports the Event Timing API that shipped - * with Chrome 77. + * with Chromium 77. * * @private {boolean} */ - this.supportsEventTimingAPIv77_ = false; + this.supportsEventTiming_ = supportedEntryTypes.includes('first-input'); /** * Whether the user agent supports the Largest Contentful Paint metric. * * @private {boolean} */ - this.supportsLargestContentfulPaint_ = false; - - const {PerformanceObserver} = this.win; - if (PerformanceObserver) { - const {supportedEntryTypes} = PerformanceObserver; - if (supportedEntryTypes) { - this.supportsLayoutInstabilityAPIv76_ = this.win.PerformanceObserver.supportedEntryTypes.includes( - 'layoutShift' - ); - this.supportsLayoutInstabilityAPIv77_ = this.win.PerformanceObserver.supportedEntryTypes.includes( - 'layout-shift' - ); - this.supportsEventTimingAPIv76_ = this.win.PerformanceObserver.supportedEntryTypes.includes( - 'firstInput' - ); - this.supportsEventTimingAPIv77_ = this.win.PerformanceObserver.supportedEntryTypes.includes( - 'first-input' - ); - this.supportsLargestContentfulPaint_ = this.win.PerformanceObserver.supportedEntryTypes.includes( - 'largest-contentful-paint' - ); - } - } + this.supportsLargestContentfulPaint_ = supportedEntryTypes.includes( + 'largest-contentful-paint' + ); /** * The latest reported largest contentful paint time, where the loadTime @@ -256,10 +209,7 @@ export class Performance { }); const registerVisibilityChangeListener = - this.win.PerformanceLayoutJank || - this.supportsLargestContentfulPaint_ || - this.supportsLayoutInstabilityAPIv76_ || - this.supportsLayoutInstabilityAPIv77_; + this.supportsLargestContentfulPaint_ || this.supportsLayoutShift_; // Register a handler to record metrics when the page enters the hidden // lifecycle state. if (registerVisibilityChangeListener) { @@ -335,7 +285,7 @@ export class Performance { * See https://github.com/WICG/paint-timing */ registerPerformanceObserver_() { - // Chrome doesn't implement the buffered flag for PerformanceObserver. + // Chromium doesn't implement the buffered flag for PerformanceObserver. // That means we need to read existing entries and maintain state // as to whether we have reported a value yet, since in the future it may // be reported twice. @@ -354,16 +304,11 @@ export class Performance { this.tickDelta('fcp', entry.startTime + entry.duration); recordedFirstContentfulPaint = true; } else if ( - (entry.entryType === 'firstInput' || - entry.entryType === 'first-input') && + entry.entryType === 'first-input' && !recordedFirstInputDelay ) { this.tickDelta('fid', entry.processingStart - entry.startTime); recordedFirstInputDelay = true; - } else if (entry.entryType === 'layoutJank') { - this.aggregateJankScore_ += entry.fraction; - } else if (entry.entryType === 'layoutShift') { - this.aggregateShiftScore_ += entry.value; } else if (entry.entryType === 'layout-shift') { // Ignore layout shift that occurs within 500ms of user input, as it is // likely in response to the user's action. @@ -383,44 +328,18 @@ export class Performance { const entryTypesToObserve = []; if (this.win.PerformancePaintTiming) { // Programmatically read once as currently PerformanceObserver does not - // report past entries as of Chrome 61. + // report past entries as of Chromium 61. // https://bugs.chromium.org/p/chromium/issues/detail?id=725567 this.win.performance.getEntriesByType('paint').forEach(processEntry); entryTypesToObserve.push('paint'); } - if (this.supportsEventTimingAPIv76_) { - // Programmatically read once as currently PerformanceObserver does not - // report past entries as of Chrome 61. - // https://bugs.chromium.org/p/chromium/issues/detail?id=725567 - this.win.performance.getEntriesByType('firstInput').forEach(processEntry); - entryTypesToObserve.push('firstInput'); - } - - if (this.supportsEventTimingAPIv77_) { + if (this.supportsEventTiming_) { const firstInputObserver = this.createPerformanceObserver_(processEntry); firstInputObserver.observe({type: 'first-input', buffered: true}); } - if (this.win.PerformanceLayoutJank) { - // Programmatically read once as currently PerformanceObserver does not - // report past entries as of Chrome 61. - // https://bugs.chromium.org/p/chromium/issues/detail?id=725567 - this.win.performance.getEntriesByType('layoutJank').forEach(processEntry); - entryTypesToObserve.push('layoutJank'); - } - - if (this.supportsLayoutInstabilityAPIv76_) { - // Programmatically read once as currently PerformanceObserver does not - // report past entries as of Chrome 61. - // https://bugs.chromium.org/p/chromium/issues/detail?id=725567 - this.win.performance - .getEntriesByType('layoutShift') - .forEach(processEntry); - entryTypesToObserve.push('layoutShift'); - } - - if (this.supportsLayoutInstabilityAPIv77_) { + if (this.supportsLayoutShift_) { const layoutInstabilityObserver = this.createPerformanceObserver_( processEntry ); @@ -477,18 +396,12 @@ export class Performance { /** * When the visibility state of the document changes to hidden, - * send the layout jank score. + * send the layout scores. * @private */ onVisibilityChange_() { if (this.win.document.visibilityState === 'hidden') { - if (this.win.PerformanceLayoutJank) { - this.tickLayoutJankScore_(); - } - if ( - this.supportsLayoutInstabilityAPIv76_ || - this.supportsLayoutInstabilityAPIv77_ - ) { + if (this.supportsLayoutShift_) { this.tickLayoutShiftScore_(); } if (this.supportsLargestContentfulPaint_) { @@ -499,18 +412,12 @@ export class Performance { /** * When the viewer visibility state of the document changes to inactive, - * send the layout jank score. + * send the layout score. * @private */ onAmpDocVisibilityChange_() { if (this.ampdoc_.getVisibilityState() === VisibilityState.INACTIVE) { - if (this.win.PerformanceLayoutJank) { - this.tickLayoutJankScore_(); - } - if ( - this.supportsLayoutInstabilityAPIv76_ || - this.supportsLayoutInstabilityAPIv77_ - ) { + if (this.supportsLayoutShift_) { this.tickLayoutShiftScore_(); } if (this.supportsLargestContentfulPaint_) { @@ -519,37 +426,6 @@ export class Performance { } } - /** - * Tick the layout jank score metric. - * - * A value of the metric is recorded in under two names, `lj` and `lj-2`, - * for the first two times the page transitions into a hidden lifecycle state - * (when the page is navigated a way from, the tab is backgrounded for - * another tab, or the user backgrounds the browser application). - * - * Since we can't reliably detect when a page session finally ends, - * recording the value for these first two events should provide a fair - * amount of visibility into this metric. - */ - tickLayoutJankScore_() { - if (this.jankScoresTicked_ === 0) { - this.tickDelta('lj', this.aggregateJankScore_); - this.flush(); - this.jankScoresTicked_ = 1; - } else if (this.jankScoresTicked_ === 1) { - this.tickDelta('lj-2', this.aggregateJankScore_); - this.flush(); - this.jankScoresTicked_ = 2; - - // No more work to do, so clean up event listeners. - this.win.removeEventListener( - VISIBILITY_CHANGE_EVENT, - this.boundOnVisibilityChange_, - {capture: true} - ); - } - } - /** * Tick the layout shift score metric. * @@ -582,7 +458,7 @@ export class Performance { } /** - * Tick fp time based on Chrome's legacy paint timing API when + * Tick fp time based on Chromium's legacy paint timing API when * appropriate. * `registerPaintTimingObserver_` calls the standards based API and this * method does nothing if it is available. @@ -600,8 +476,8 @@ export class Performance { this.win.chrome.loadTimes()['firstPaintTime'] * 1000 - this.win.performance.timing.navigationStart; if (fpTime <= 1) { - // Throw away bad data generated from an apparent Chrome bug - // that is fixed in later Chrome versions. + // Throw away bad data generated from an apparent Chromium bug + // that is fixed in later Chromium versions. return; } this.tickDelta('fp', fpTime); diff --git a/test/unit/test-performance.js b/test/unit/test-performance.js index a08d4a0b8647..611d594e5cd8 100644 --- a/test/unit/test-performance.js +++ b/test/unit/test-performance.js @@ -898,11 +898,6 @@ describes.realWin('PeformanceObserver metrics', {amp: true}, env => { }); } - function getPerformance() { - installPerformanceService(fakeWin); - return Services.performanceFor(fakeWin); - } - function toggleVisibility(win, on) { win.document.visibilityState = on ? 'visible' : 'hidden'; fireEvent('visibilitychange'); @@ -997,7 +992,7 @@ describes.realWin('PeformanceObserver metrics', {amp: true}, env => { return entries; }, }; - // Fake a triggering of the firstInput event. + // Fake a triggering of the first-input event. performanceObserver.triggerCallback(list); expect(perf.events_.length).to.equal(2); expect(perf.events_[0]).to.be.jsonEqual( @@ -1090,73 +1085,8 @@ describes.realWin('PeformanceObserver metrics', {amp: true}, env => { ); PerformanceObserverConstructorStub.callsFake(PerformanceObserverStub); }); - it('created before performance service registered', () => { - // Pretend that the EventTiming API exists. - PerformanceObserverConstructorStub.supportedEntryTypes = ['firstInput']; - - const entries = [ - { - cancelable: true, - duration: 8, - entryType: 'firstInput', - name: 'mousedown', - processingEnd: 105, - processingStart: 103, - startTime: 100, - }, - ]; - const getEntriesByType = env.sandbox.stub(); - getEntriesByType.withArgs('firstInput').returns(entries); - getEntriesByType.returns([]); - env.sandbox - .stub(env.win.performance, 'getEntriesByType') - .callsFake(getEntriesByType); - - installPerformanceService(env.win); - - const perf = Services.performanceFor(env.win); - - expect(perf.events_.length).to.equal(1); - expect(perf.events_[0]).to.be.jsonEqual({ - label: 'fid', - delta: 3, - }); - }); - - it('created after performance service registered', () => { - // Pretend that the EventTiming API exists. - PerformanceObserverConstructorStub.supportedEntryTypes = ['firstInput']; - - installPerformanceService(env.win); - - const perf = Services.performanceFor(env.win); - - const entries = [ - { - cancelable: true, - duration: 8, - entryType: 'firstInput', - name: 'mousedown', - processingEnd: 105, - processingStart: 103, - startTime: 100, - }, - ]; - const list = { - getEntries() { - return entries; - }, - }; - // Fake a triggering of the firstInput event. - performanceObserver.triggerCallback(list); - expect(perf.events_.length).to.equal(1); - expect(perf.events_[0]).to.be.jsonEqual({ - label: 'fid', - delta: 3, - }); - }); - it('created before performance service registered for Chrome 77', () => { + it('created before performance service registered for Chromium 77', () => { // Pretend that the EventTiming API exists. PerformanceObserverConstructorStub.supportedEntryTypes = ['first-input']; @@ -1171,7 +1101,7 @@ describes.realWin('PeformanceObserver metrics', {amp: true}, env => { { cancelable: true, duration: 8, - entryType: 'firstInput', + entryType: 'first-input', name: 'mousedown', processingEnd: 105, processingStart: 103, @@ -1223,98 +1153,6 @@ describes.realWin('PeformanceObserver metrics', {amp: true}, env => { } }); - describe('forwards layout jank metric', () => { - beforeEach(() => { - setupFakesForVisibilityStateManipulation(); - fakeWin.PerformanceLayoutJank = true; - }); - it('for browsers that support the visibilitychange event', () => { - // Specify an Android Chrome user agent, which supports the - // visibilitychange event. - env.sandbox - .stub(Services.platformFor(fakeWin), 'isAndroid') - .returns(true); - env.sandbox.stub(Services.platformFor(fakeWin), 'isChrome').returns(true); - env.sandbox - .stub(Services.platformFor(fakeWin), 'isSafari') - .returns(false); - - // Document should be initially visible. - expect(fakeWin.document.visibilityState).to.equal('visible'); - - // Fake layoutJank that occured before the Performance service is started. - fakeWin.performance.getEntriesByType.withArgs('layoutJank').returns([ - {entryType: 'layoutJank', fraction: 0.25}, - {entryType: 'layoutJank', fraction: 0.3}, - ]); - - const perf = getPerformance(); - // visibilitychange/beforeunload listeners are now added. - perf.coreServicesAvailable(); - - // The document has become hidden, e.g. via the user switching tabs. - toggleVisibility(fakeWin, false); - expect(perf.events_.length).to.equal(1); - expect(perf.events_[0]).to.be.jsonEqual({ - label: 'lj', - delta: 0.55, - }); - - // The user returns to the tab, and more layout jank occurs. - toggleVisibility(fakeWin, true); - const list = { - getEntries() { - return [ - {entryType: 'layoutJank', fraction: 1}, - {entryType: 'layoutJank', fraction: 0.0001}, - ]; - }, - }; - performanceObserver.triggerCallback(list); - - toggleVisibility(fakeWin, false); - expect(perf.events_.length).to.equal(2); - expect(perf.events_[1]).to.be.jsonEqual({ - label: 'lj-2', - delta: 1.5501, - }); - - // Any more layout jank shouldn't be reported. - toggleVisibility(fakeWin, true); - performanceObserver.triggerCallback(list); - - toggleVisibility(fakeWin, false); - expect(perf.events_.length).to.equal(2); - }); - - it('forwards layout jank metric on viewer visibility change to inactive', () => { - // Specify an Android Chrome user agent. - env.sandbox - .stub(Services.platformFor(fakeWin), 'isAndroid') - .returns(true); - env.sandbox.stub(Services.platformFor(fakeWin), 'isChrome').returns(true); - env.sandbox - .stub(Services.platformFor(fakeWin), 'isSafari') - .returns(false); - - // Fake layoutJank that occured before the Performance service is started. - fakeWin.performance.getEntriesByType.withArgs('layoutJank').returns([ - {entryType: 'layoutJank', fraction: 0.25}, - {entryType: 'layoutJank', fraction: 0.3}, - ]); - const perf = getPerformance(); - perf.coreServicesAvailable(); - viewerVisibilityState = VisibilityState.INACTIVE; - perf.onAmpDocVisibilityChange_(); - - expect(perf.events_.length).to.equal(1); - expect(perf.events_[0]).to.be.jsonEqual({ - label: 'lj', - delta: 0.55, - }); - }); - }); - describe('forwards cumulative layout shift metric', () => { beforeEach(() => { setupFakesForVisibilityStateManipulation(); @@ -1335,72 +1173,7 @@ describes.realWin('PeformanceObserver metrics', {amp: true}, env => { (windowEventListeners[eventName] || []).forEach(cb => cb(event)); } - it('for Chrome 76', () => { - // Specify an Android Chrome user agent, which supports the - // visibilitychange event. - env.sandbox - .stub(Services.platformFor(fakeWin), 'isAndroid') - .returns(true); - env.sandbox.stub(Services.platformFor(fakeWin), 'isChrome').returns(true); - env.sandbox - .stub(Services.platformFor(fakeWin), 'isSafari') - .returns(false); - - // Fake the Performance API. - fakeWin.PerformanceObserver.supportedEntryTypes = ['layoutShift']; - - // Document should be initially visible. - expect(fakeWin.document.visibilityState).to.equal('visible'); - - // Fake layoutShift that occured before the Performance service is started. - fakeWin.performance.getEntriesByType.withArgs('layoutShift').returns([ - {entryType: 'layoutShift', value: 0.25}, - {entryType: 'layoutShift', value: 0.3}, - ]); - - const perf = getPerformance(); - // visibilitychange/beforeunload listeners are now added. - perf.coreServicesAvailable(); - - // The document has become hidden, e.g. via the user switching tabs. - toggleVisibility(fakeWin, false); - expect(perf.events_.length).to.equal(1); - expect(perf.events_[0]).to.be.jsonEqual({ - label: 'cls', - delta: 0.55, - }); - - // The user returns to the tab, and more layout shift occurs. - toggleVisibility(fakeWin, true); - performanceObserver.triggerCallback({ - getEntries() { - return [ - {entryType: 'layoutShift', value: 1}, - {entryType: 'layoutShift', value: 0.0001}, - ]; - }, - }); - - toggleVisibility(fakeWin, false); - expect(perf.events_.length).to.equal(2); - expect(perf.events_[1]).to.be.jsonEqual({ - label: 'cls-2', - delta: 1.5501, - }); - - // Any more layout shift shouldn't be reported. - toggleVisibility(fakeWin, true); - performanceObserver.triggerCallback({ - getEntries() { - return [{entryType: 'layoutShift', value: 2}]; - }, - }); - - toggleVisibility(fakeWin, false); - expect(perf.events_.length).to.equal(2); - }); - - it('for Chrome 77', () => { + it('for Chromium 77', () => { // Specify an Android Chrome user agent, which supports the // visibilitychange event. env.sandbox