@@ -19,6 +19,8 @@ import { bindReporter } from './lib/bindReporter';
1919import { getActivationStart } from './lib/getActivationStart' ;
2020import { getNavigationEntry } from './lib/getNavigationEntry' ;
2121import { initMetric } from './lib/initMetric' ;
22+ import { observe } from './lib/observe' ;
23+ import { softNavs } from './lib/softNavs' ;
2224import { whenActivated } from './lib/whenActivated' ;
2325import type { MetricRatingThresholds , ReportOpts , TTFBMetric } from './types' ;
2426
@@ -56,21 +58,40 @@ const whenReady = (callback: () => void) => {
5658 * and server processing time.
5759 */
5860export const onTTFB = ( onReport : ( metric : TTFBMetric ) => void , opts : ReportOpts = { } ) => {
59- const metric = initMetric ( 'TTFB' ) ;
60- const report = bindReporter ( onReport , metric , TTFBThresholds , opts . reportAllChanges ) ;
61+ // Set defaults
62+ const softNavsEnabled = softNavs ( opts ) ;
6163
62- whenReady ( ( ) => {
63- const navigationEntry = getNavigationEntry ( ) ;
64+ let metric = initMetric ( 'TTFB' ) ;
65+ let report = bindReporter ( onReport , metric , TTFBThresholds , opts . reportAllChanges ) ;
6466
65- if ( navigationEntry ) {
67+ whenReady ( ( ) => {
68+ const hardNavEntry = getNavigationEntry ( ) ;
69+ if ( hardNavEntry ) {
70+ const responseStart = hardNavEntry . responseStart ;
6671 // The activationStart reference is used because TTFB should be
6772 // relative to page activation rather than navigation start if the
6873 // page was prerendered. But in cases where `activationStart` occurs
6974 // after the first byte is received, this time should be clamped at 0.
70- metric . value = Math . max ( navigationEntry . responseStart - getActivationStart ( ) , 0 ) ;
75+ metric . value = Math . max ( responseStart - getActivationStart ( ) , 0 ) ;
7176
72- metric . entries = [ navigationEntry ] ;
77+ metric . entries = [ hardNavEntry ] ;
7378 report ( true ) ;
79+
80+ // Listen for soft-navigation entries and emit a dummy 0 TTFB entry
81+ const reportSoftNavTTFBs = ( entries : SoftNavigationEntry [ ] ) => {
82+ entries . forEach ( entry => {
83+ if ( entry . navigationId ) {
84+ metric = initMetric ( 'TTFB' , 0 , 'soft-navigation' , entry . navigationId ) ;
85+ metric . entries = [ entry ] ;
86+ report = bindReporter ( onReport , metric , TTFBThresholds , opts . reportAllChanges ) ;
87+ report ( true ) ;
88+ }
89+ } ) ;
90+ } ;
91+
92+ if ( softNavsEnabled ) {
93+ observe ( 'soft-navigation' , reportSoftNavTTFBs , opts ) ;
94+ }
7495 }
7596 } ) ;
7697} ;
0 commit comments