@paulirish/trace_engine 0.0.48 → 0.0.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.tmp/tsbuildinfo/tsconfig.tsbuildinfo +1 -1
- package/core/platform/TypedArrayUtilities.d.ts +2 -1
- package/core/platform/TypedArrayUtilities.js +9 -4
- package/core/platform/TypedArrayUtilities.js.map +1 -1
- package/generated/protocol.d.ts +19 -2
- package/locales/af.json +229 -16
- package/locales/am.json +231 -18
- package/locales/ar.json +229 -16
- package/locales/as.json +231 -18
- package/locales/az.json +231 -18
- package/locales/be.json +228 -15
- package/locales/bg.json +229 -16
- package/locales/bn.json +229 -16
- package/locales/bs.json +229 -16
- package/locales/ca.json +229 -16
- package/locales/cs.json +228 -15
- package/locales/cy.json +231 -18
- package/locales/da.json +230 -17
- package/locales/de.json +228 -15
- package/locales/el.json +229 -16
- package/locales/en-GB.json +229 -16
- package/locales/en-US.json +30 -3
- package/locales/en-XL.json +30 -3
- package/locales/es-419.json +229 -16
- package/locales/es.json +228 -15
- package/locales/et.json +230 -17
- package/locales/eu.json +231 -18
- package/locales/fa.json +230 -17
- package/locales/fi.json +229 -16
- package/locales/fil.json +231 -18
- package/locales/fr-CA.json +230 -17
- package/locales/fr.json +230 -17
- package/locales/gl.json +228 -15
- package/locales/gu.json +230 -17
- package/locales/he.json +229 -16
- package/locales/hi.json +230 -17
- package/locales/hr.json +229 -16
- package/locales/hu.json +229 -16
- package/locales/hy.json +228 -15
- package/locales/id.json +228 -15
- package/locales/is.json +229 -16
- package/locales/it.json +232 -19
- package/locales/ja.json +228 -15
- package/locales/ka.json +230 -17
- package/locales/kk.json +230 -17
- package/locales/km.json +231 -18
- package/locales/kn.json +228 -15
- package/locales/ko.json +229 -16
- package/locales/ky.json +230 -17
- package/locales/lo.json +229 -16
- package/locales/lt.json +229 -16
- package/locales/lv.json +230 -17
- package/locales/mk.json +229 -16
- package/locales/ml.json +230 -17
- package/locales/mn.json +229 -16
- package/locales/mr.json +230 -17
- package/locales/ms.json +229 -16
- package/locales/my.json +231 -18
- package/locales/ne.json +229 -16
- package/locales/nl.json +229 -16
- package/locales/no.json +229 -16
- package/locales/or.json +231 -18
- package/locales/pa.json +228 -15
- package/locales/pl.json +230 -17
- package/locales/pt-PT.json +229 -16
- package/locales/pt.json +229 -16
- package/locales/ro.json +228 -15
- package/locales/ru.json +230 -17
- package/locales/si.json +231 -18
- package/locales/sk.json +229 -16
- package/locales/sl.json +230 -17
- package/locales/sq.json +229 -16
- package/locales/sr-Latn.json +229 -16
- package/locales/sr.json +229 -16
- package/locales/sv.json +229 -16
- package/locales/sw.json +231 -18
- package/locales/ta.json +230 -17
- package/locales/te.json +231 -18
- package/locales/th.json +229 -16
- package/locales/tr.json +230 -17
- package/locales/uk.json +229 -16
- package/locales/ur.json +230 -17
- package/locales/uz.json +229 -16
- package/locales/vi.json +230 -17
- package/locales/zh-HK.json +229 -16
- package/locales/zh-TW.json +230 -17
- package/locales/zh.json +228 -15
- package/locales/zu.json +230 -17
- package/models/trace/Processor.js +5 -3
- package/models/trace/Processor.js.map +1 -1
- package/models/trace/extras/ScriptDuplication.d.ts +27 -8
- package/models/trace/extras/ScriptDuplication.js +27 -26
- package/models/trace/extras/ScriptDuplication.js.map +1 -1
- package/models/trace/extras/StackTraceForEvent.js +7 -0
- package/models/trace/extras/StackTraceForEvent.js.map +1 -1
- package/models/trace/extras/extras.d.ts +1 -0
- package/models/trace/extras/extras.js +1 -0
- package/models/trace/handlers/ExtensionTraceDataHandler.js +14 -9
- package/models/trace/handlers/ExtensionTraceDataHandler.js.map +1 -1
- package/models/trace/handlers/MetaHandler.d.ts +13 -0
- package/models/trace/handlers/MetaHandler.js +27 -0
- package/models/trace/handlers/MetaHandler.js.map +1 -1
- package/models/trace/helpers/Network.d.ts +18 -0
- package/models/trace/helpers/Network.js +57 -0
- package/models/trace/helpers/Network.js.map +1 -1
- package/models/trace/helpers/SamplesIntegrator.js +1 -1
- package/models/trace/helpers/SamplesIntegrator.js.map +1 -1
- package/models/trace/helpers/Trace.js +4 -0
- package/models/trace/helpers/Trace.js.map +1 -1
- package/models/trace/insights/DocumentLatency.d.ts +2 -1
- package/models/trace/insights/DocumentLatency.js +3 -0
- package/models/trace/insights/DocumentLatency.js.map +1 -1
- package/models/trace/insights/{DuplicateJavaScript.d.ts → DuplicatedJavaScript.d.ts} +6 -1
- package/models/trace/insights/{DuplicateJavaScript.js → DuplicatedJavaScript.js} +15 -6
- package/models/trace/insights/DuplicatedJavaScript.js.map +1 -0
- package/models/trace/insights/FontDisplay.d.ts +1 -2
- package/models/trace/insights/FontDisplay.js.map +1 -1
- package/models/trace/insights/ForcedReflow.d.ts +23 -3
- package/models/trace/insights/ForcedReflow.js +63 -107
- package/models/trace/insights/ForcedReflow.js.map +1 -1
- package/models/trace/insights/Models.d.ts +2 -1
- package/models/trace/insights/Models.js +2 -1
- package/models/trace/insights/Models.js.map +1 -1
- package/models/trace/insights/NetworkDependencyTree.d.ts +2 -1
- package/models/trace/insights/NetworkDependencyTree.js +9 -4
- package/models/trace/insights/NetworkDependencyTree.js.map +1 -1
- package/models/trace/insights/Statistics.d.ts +4 -0
- package/models/trace/insights/Statistics.js +7 -0
- package/models/trace/insights/Statistics.js.map +1 -1
- package/models/trace/insights/UseCache.d.ts +69 -0
- package/models/trace/insights/UseCache.js +189 -0
- package/models/trace/insights/UseCache.js.map +1 -0
- package/models/trace/insights/insights-tsconfig.json +2 -1
- package/models/trace/insights/types.d.ts +1 -13
- package/models/trace/insights/types.js.map +1 -1
- package/models/trace/types/TraceEvents.d.ts +16 -4
- package/models/trace/types/TraceEvents.js +4 -1
- package/models/trace/types/TraceEvents.js.map +1 -1
- package/package.json +1 -1
- package/test/test-trace-engine.mjs +2 -1
- package/models/trace/insights/DuplicateJavaScript.js.map +0 -1
package/locales/zu.json
CHANGED
|
@@ -59,6 +59,9 @@
|
|
|
59
59
|
"generated/Deprecation.ts | InterestGroupDailyUpdateUrl": {
|
|
60
60
|
"message": "Inkambu ye-dailyUpdateUrl ye-InterestGroups idlule ku-joinAdInterestGroup() iqanjwe kabusha kuya ku-updateUrl, ukubonisa kahle ukuziphatha."
|
|
61
61
|
},
|
|
62
|
+
"generated/Deprecation.ts | IntlV8BreakIterator": {
|
|
63
|
+
"message": "I-Intl.v8BreakIterator ihoxisiwe. Kunalokho sicela usebenzise i-Intl.Segmenter."
|
|
64
|
+
},
|
|
62
65
|
"generated/Deprecation.ts | LocalCSSFileExtensionRejected": {
|
|
63
66
|
"message": "I-CSS ayikwazi ukulayishwa kusukela kuma-URL we-file: ngaphandle kwalapho uma ephela ngesijobelelo sefayela le-.css."
|
|
64
67
|
},
|
|
@@ -78,7 +81,7 @@
|
|
|
78
81
|
"message": "Imvume Yesaziso se-API ingase ingasacelwa ku-iframe ye-cross-origin. Kufanele ucabangele ukucela imvume kuhlaka lwezinga eliphezulu noma ukuvula iwindi elisha esikhundleni salokho."
|
|
79
82
|
},
|
|
80
83
|
"generated/Deprecation.ts | ObsoleteCreateImageBitmapImageOrientationNone": {
|
|
81
|
-
"message": "Ongakukhetha kwe-imageOrientation: 'none' ku-createImageBitmap kuhoxisiwe. Sicela usebenzise i-createImageBitmap
|
|
84
|
+
"message": "Ongakukhetha kwe-imageOrientation: 'none' ku-createImageBitmap kuhoxisiwe. Sicela usebenzise i-createImageBitmap ngokungakhethwa kukho kwe-{imageOrientation: 'from-image'} esikhundleni salokho."
|
|
82
85
|
},
|
|
83
86
|
"generated/Deprecation.ts | ObsoleteWebRtcCipherSuite": {
|
|
84
87
|
"message": "Uzakwenu uxoxisana ngohlobo oluphelelwe yisikhathi (D)TLS. Sicela uhlole nozakwenu ukuze kulungiswe lokhu."
|
|
@@ -155,107 +158,317 @@
|
|
|
155
158
|
"generated/Deprecation.ts | V8SharedArrayBufferConstructedInExtensionWithoutIsolation": {
|
|
156
159
|
"message": "Izandiso kufanele zingene ekuhlukaniseni imvelaphi ehlukene ukuze ziqhubeke nokusebenzisa i-SharedArrayBuffer. Bheka i-https://developer.chrome.com/docs/extensions/mv3/cross-origin-isolation/."
|
|
157
160
|
},
|
|
158
|
-
"generated/Deprecation.ts | WebGPULimitMaxInterStageShaderComponents": {
|
|
159
|
-
"message": "Umkhawulo we-WebGPU maxInterStageShaderComponents uhoxisiwe, kunalokho sebenzisa umkhawulo we-WebGPU maxInterStageShaderVariables."
|
|
160
|
-
},
|
|
161
|
-
"generated/Deprecation.ts | WebSQL": {
|
|
162
|
-
"message": "I-Web SQL ihoxisiwe. Sicela usebenzise i-SQLite WebAssembly noma i-Indexed Database"
|
|
163
|
-
},
|
|
164
161
|
"generated/Deprecation.ts | XHRJSONEncodingDetection": {
|
|
165
162
|
"message": "I-UTF-16 ayisekelwe yimpendulo ye-json ku-XMLHttpRequest"
|
|
166
163
|
},
|
|
167
164
|
"generated/Deprecation.ts | XMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload": {
|
|
168
165
|
"message": "Ukuvumelanisa i-XMLHttpRequest kuchungechunge oluyinhloko kuhoxisiwe ngenxa yemiphumela yako elimazayo kumuzwa womsebenzisi wokugcina. Mayelana nosizo olubanzi, hlola i-https://xhr.spec.whatwg.org/."
|
|
169
166
|
},
|
|
170
|
-
"
|
|
171
|
-
"message": "
|
|
167
|
+
"models/trace/insights/CLSCulprits.ts | animation": {
|
|
168
|
+
"message": "Opopayi"
|
|
172
169
|
},
|
|
173
170
|
"models/trace/insights/CLSCulprits.ts | description": {
|
|
174
171
|
"message": "Ukushintsha kwesakhiwo kwenzeka lapho ama-elementi enza ukuxhumana komsebenzisi kungabi khona. [Phenya ngezimbangela zokushintsha kohlaka](https://web.dev/articles/optimize-cls), njengezinto ezengezwayo, ezikhishwayo, noma amafonti awo ashintshayo njengoba ikhasi lilayisha."
|
|
175
172
|
},
|
|
173
|
+
"models/trace/insights/CLSCulprits.ts | fontRequest": {
|
|
174
|
+
"message": "Isicelo sefonti"
|
|
175
|
+
},
|
|
176
|
+
"models/trace/insights/CLSCulprits.ts | injectedIframe": {
|
|
177
|
+
"message": "I-iframe efakiwe"
|
|
178
|
+
},
|
|
179
|
+
"models/trace/insights/CLSCulprits.ts | layoutShiftCluster": {
|
|
180
|
+
"message": "Iqoqo leshift yohlaka ngo-{PH1}"
|
|
181
|
+
},
|
|
182
|
+
"models/trace/insights/CLSCulprits.ts | noCulprits": {
|
|
183
|
+
"message": "Akutholakalanga lutho olugudluza uhlaka"
|
|
184
|
+
},
|
|
185
|
+
"models/trace/insights/CLSCulprits.ts | noLayoutShifts": {
|
|
186
|
+
"message": "Alukho uhlaka lwama-shift"
|
|
187
|
+
},
|
|
176
188
|
"models/trace/insights/CLSCulprits.ts | title": {
|
|
177
189
|
"message": "Izimbangela zeshift yohlaka"
|
|
178
190
|
},
|
|
191
|
+
"models/trace/insights/CLSCulprits.ts | topCulprits": {
|
|
192
|
+
"message": "Izimbangela eziphezulu zokushintsha kohlaka"
|
|
193
|
+
},
|
|
194
|
+
"models/trace/insights/CLSCulprits.ts | unsizedImages": {
|
|
195
|
+
"message": "Izithombe ezingenabo osayizi"
|
|
196
|
+
},
|
|
197
|
+
"models/trace/insights/CLSCulprits.ts | worstCluster": {
|
|
198
|
+
"message": "Iqoqo elibi kakhulu"
|
|
199
|
+
},
|
|
200
|
+
"models/trace/insights/CLSCulprits.ts | worstLayoutShiftCluster": {
|
|
201
|
+
"message": "Iqoqo lokushintsha uhlaka olubi kakhulu"
|
|
202
|
+
},
|
|
179
203
|
"models/trace/insights/DOMSize.ts | description": {
|
|
180
204
|
"message": "I-DOM enkulu ingakhulisa ubude besikhathi sezibalo zesitayela nereflow yohlaka, okuthinta ukuphendula kwekhasi. I-DOM enkulu izophinde yandise ukusetshenziswa kwenkumbulo. [Funda indlela yokugwema usayizi oweqile we-DOM](https://developer.chrome.com/docs/lighthouse/performance/dom-size/)."
|
|
181
205
|
},
|
|
206
|
+
"models/trace/insights/DOMSize.ts | element": {
|
|
207
|
+
"message": "I-elementi"
|
|
208
|
+
},
|
|
209
|
+
"models/trace/insights/DOMSize.ts | maxChildren": {
|
|
210
|
+
"message": "Izingane eziningi"
|
|
211
|
+
},
|
|
212
|
+
"models/trace/insights/DOMSize.ts | maxDOMDepth": {
|
|
213
|
+
"message": "Ukujula kwe-DOM"
|
|
214
|
+
},
|
|
215
|
+
"models/trace/insights/DOMSize.ts | statistic": {
|
|
216
|
+
"message": "Isibalo"
|
|
217
|
+
},
|
|
182
218
|
"models/trace/insights/DOMSize.ts | title": {
|
|
183
219
|
"message": "Lungiselela usayizi weDOM"
|
|
184
220
|
},
|
|
221
|
+
"models/trace/insights/DOMSize.ts | totalElements": {
|
|
222
|
+
"message": "Isamba sama-elementi"
|
|
223
|
+
},
|
|
224
|
+
"models/trace/insights/DOMSize.ts | value": {
|
|
225
|
+
"message": "Inani"
|
|
226
|
+
},
|
|
185
227
|
"models/trace/insights/DocumentLatency.ts | description": {
|
|
186
228
|
"message": "Isicelo sakho sokuqala senethiwekhi sibaluleke kakhulu. Nciphisa ukubambezeleka kwayo ngokugwema ukuqondiswa kabusha, okuqinisekisa impendulo esheshayo yeseva, nokunika amandla ukuminyaniswa kombhalo."
|
|
187
229
|
},
|
|
230
|
+
"models/trace/insights/DocumentLatency.ts | failedRedirects": {
|
|
231
|
+
"message": "Kuye kwaqondiswa kabusha"
|
|
232
|
+
},
|
|
233
|
+
"models/trace/insights/DocumentLatency.ts | failedServerResponseTime": {
|
|
234
|
+
"message": "Iseva ayisabelanga ngokushesha"
|
|
235
|
+
},
|
|
236
|
+
"models/trace/insights/DocumentLatency.ts | failedTextCompression": {
|
|
237
|
+
"message": "Akukho ukuminyanisa okusetshenzisiwe"
|
|
238
|
+
},
|
|
239
|
+
"models/trace/insights/DocumentLatency.ts | passingRedirects": {
|
|
240
|
+
"message": "Kugwema ukuqondisa kabusha"
|
|
241
|
+
},
|
|
242
|
+
"models/trace/insights/DocumentLatency.ts | passingServerResponseTime": {
|
|
243
|
+
"message": "Iseva isabela ngokushesha"
|
|
244
|
+
},
|
|
245
|
+
"models/trace/insights/DocumentLatency.ts | passingTextCompression": {
|
|
246
|
+
"message": "Ifaka ukuminyaniswa kombhalo"
|
|
247
|
+
},
|
|
248
|
+
"models/trace/insights/DocumentLatency.ts | redirectsLabel": {
|
|
249
|
+
"message": "Iqondisa kabusha"
|
|
250
|
+
},
|
|
251
|
+
"models/trace/insights/DocumentLatency.ts | serverResponseTimeLabel": {
|
|
252
|
+
"message": "Isikhathi sokuphendula seseva"
|
|
253
|
+
},
|
|
188
254
|
"models/trace/insights/DocumentLatency.ts | title": {
|
|
189
255
|
"message": "Ukubambezeleka kwesicelo sedokhumenti"
|
|
190
256
|
},
|
|
257
|
+
"models/trace/insights/DocumentLatency.ts | uncompressedDownload": {
|
|
258
|
+
"message": "Ukudawuniloda okungacindezelwe"
|
|
259
|
+
},
|
|
260
|
+
"models/trace/insights/DuplicateJavaScript.ts | description": {
|
|
261
|
+
"message": "Susa amamojula amakhulu, ayimpinda we-JavaScript kwizinqwaba ukuze unciphise amabhayithi angadingekile adliwa ngumsebenzi wenethiwekhi."
|
|
262
|
+
},
|
|
263
|
+
"models/trace/insights/DuplicateJavaScript.ts | title": {
|
|
264
|
+
"message": "Phinda iJavaScript"
|
|
265
|
+
},
|
|
191
266
|
"models/trace/insights/FontDisplay.ts | description": {
|
|
192
267
|
"message": "Cabanga ukusetha i-[font-display](https://developer.chrome.com/blog/font-display) ibe yi-swap noma i-optional ukuze uqinisekise ukuthi umbhalo ubonakala ngokulandelanayo. I-swap ingaqhubeka ilungiselelwe ukuze kungenelelwe ekushintsheni kohlaka [ngokukhishwa kwemethrikhi yefonti](https://developer.chrome.com/blog/font-fallbacks)."
|
|
193
268
|
},
|
|
269
|
+
"models/trace/insights/FontDisplay.ts | fontColumn": {
|
|
270
|
+
"message": "Ifonti"
|
|
271
|
+
},
|
|
194
272
|
"models/trace/insights/FontDisplay.ts | title": {
|
|
195
273
|
"message": "Ukubonisa ifonti"
|
|
196
274
|
},
|
|
275
|
+
"models/trace/insights/FontDisplay.ts | wastedTimeColumn": {
|
|
276
|
+
"message": "Isikhathi esichithiwe"
|
|
277
|
+
},
|
|
197
278
|
"models/trace/insights/ForcedReflow.ts | description": {
|
|
198
279
|
"message": "Ama-API amaningi, ngokuvamile ukufunda ijiyomethri yohlaka, aphoqa injini yokunikezela ukuba imise ukusetshenziswa kwesikriphti ukuze abale isitayela nohlaka. Funda kabanzi mayelana [nereflow ephoqelelwe](https://developers.google.com/web/fundamentals/performance/rendering/avoid-large-complex-layouts-and-layout-thrashing#avoid-forced-synchronous-layouts) kanye nezixazululo zayo."
|
|
199
280
|
},
|
|
281
|
+
"models/trace/insights/ForcedReflow.ts | relatedStackTrace": {
|
|
282
|
+
"message": "Ukulandelela istaki"
|
|
283
|
+
},
|
|
200
284
|
"models/trace/insights/ForcedReflow.ts | title": {
|
|
201
285
|
"message": "Ireflow ephoqelelwe"
|
|
202
286
|
},
|
|
287
|
+
"models/trace/insights/ForcedReflow.ts | topTimeConsumingFunctionCall": {
|
|
288
|
+
"message": "Okukhethwayo okuphambili kokufona"
|
|
289
|
+
},
|
|
290
|
+
"models/trace/insights/ForcedReflow.ts | totalReflowTime": {
|
|
291
|
+
"message": "Isamba sesikhathi sereflow"
|
|
292
|
+
},
|
|
203
293
|
"models/trace/insights/ImageDelivery.ts | description": {
|
|
204
294
|
"message": "Ukunciphisa isikhathi sokudawuniloda izithobe kungathuthukisa isikhathi sokulayisha sekhasi esilindelekile kanye ne-LCP. [Funda kabanzi ngokulungiselela ubungakho besithombe](https://developer.chrome.com/docs/lighthouse/performance/uses-optimized-images/)"
|
|
205
295
|
},
|
|
296
|
+
"models/trace/insights/ImageDelivery.ts | estimatedSavings": {
|
|
297
|
+
"message": "{PH1} (Isilinganiso {PH2})"
|
|
298
|
+
},
|
|
299
|
+
"models/trace/insights/ImageDelivery.ts | noOptimizableImages": {
|
|
300
|
+
"message": "Azikho izithombe ezingathuthukiswa"
|
|
301
|
+
},
|
|
302
|
+
"models/trace/insights/ImageDelivery.ts | optimizeFile": {
|
|
303
|
+
"message": "Lungiselela usayizi wefayela"
|
|
304
|
+
},
|
|
305
|
+
"models/trace/insights/ImageDelivery.ts | others": {
|
|
306
|
+
"message": "Okunye okungu-{PH1}"
|
|
307
|
+
},
|
|
206
308
|
"models/trace/insights/ImageDelivery.ts | title": {
|
|
207
309
|
"message": "Thuthukisa ukudilivwa kwesithombe"
|
|
208
310
|
},
|
|
209
311
|
"models/trace/insights/ImageDelivery.ts | useCompression": {
|
|
210
|
-
"message": "Ukwandisa isici sokuminyanisa isithombe kungase kuthuthukise usayizi wokudawuniloda lesi sithombe.
|
|
312
|
+
"message": "Ukwandisa isici sokuminyanisa isithombe kungase kuthuthukise usayizi wokudawuniloda lesi sithombe."
|
|
211
313
|
},
|
|
212
314
|
"models/trace/insights/ImageDelivery.ts | useModernFormat": {
|
|
213
|
-
"message": "Ukusebenzisa ifomethi yomfanekiso wesimanje (i-WebP, i-AVIF) noma ukwandisa ukuminyaniswa kwesithombe ukuze uthuthukise ukudawunilodwa kukasayizi walesi sithombe.
|
|
315
|
+
"message": "Ukusebenzisa ifomethi yomfanekiso wesimanje (i-WebP, i-AVIF) noma ukwandisa ukuminyaniswa kwesithombe ukuze uthuthukise ukudawunilodwa kukasayizi walesi sithombe."
|
|
214
316
|
},
|
|
215
317
|
"models/trace/insights/ImageDelivery.ts | useResponsiveSize": {
|
|
216
|
-
"message": "Leli fayela lesithombe likhulu kunalokho okudingeka libe yikho ({
|
|
318
|
+
"message": "Leli fayela lesithombe likhulu kunalokho okudingeka libe yikho ({PH1}) ngokwezibalo zalo ezibonisiwe ({PH2}). Sebenzisa izithombe ezisabelayo ukuze unciphise usayizi wokudawunilodwa kwesithombe."
|
|
217
319
|
},
|
|
218
320
|
"models/trace/insights/ImageDelivery.ts | useVideoFormat": {
|
|
219
|
-
"message": "Ukusebenzisa amafomethi evidiyo esikhundleni sama-GIF kungathuthukisa usayizi wokudawunilodwayo kokuqukethwe kopopayi.
|
|
321
|
+
"message": "Ukusebenzisa amafomethi evidiyo esikhundleni sama-GIF kungathuthukisa usayizi wokudawunilodwayo kokuqukethwe kopopayi."
|
|
220
322
|
},
|
|
221
323
|
"models/trace/insights/InteractionToNextPaint.ts | description": {
|
|
222
324
|
"message": "Qala ukuphenya ngesigaba eside kakhulu. [Ukulibaziseka kungancishiswa](https://web.dev/articles/optimize-inp#optimize_interactions). Ukuze unciphise ukucubungula ubude besikhathi, [lungiselela izindleko zochungechunge olukhulu](https://web.dev/articles/optimize-long-tasks), ngokuvamile i-JS."
|
|
223
325
|
},
|
|
326
|
+
"models/trace/insights/InteractionToNextPaint.ts | duration": {
|
|
327
|
+
"message": "Ubude besikhathi"
|
|
328
|
+
},
|
|
329
|
+
"models/trace/insights/InteractionToNextPaint.ts | inputDelay": {
|
|
330
|
+
"message": "Okokufaka okubambezelekile"
|
|
331
|
+
},
|
|
332
|
+
"models/trace/insights/InteractionToNextPaint.ts | noInteractions": {
|
|
333
|
+
"message": "Akukho ukuxhumana okutholakele"
|
|
334
|
+
},
|
|
335
|
+
"models/trace/insights/InteractionToNextPaint.ts | phase": {
|
|
336
|
+
"message": "Isigaba"
|
|
337
|
+
},
|
|
338
|
+
"models/trace/insights/InteractionToNextPaint.ts | presentationDelay": {
|
|
339
|
+
"message": "Ukubambezeleka kwephrezentheshini"
|
|
340
|
+
},
|
|
341
|
+
"models/trace/insights/InteractionToNextPaint.ts | processingDuration": {
|
|
342
|
+
"message": "Isikhathi sokucubungula"
|
|
343
|
+
},
|
|
224
344
|
"models/trace/insights/InteractionToNextPaint.ts | title": {
|
|
225
345
|
"message": "I-INP ngokwesigaba"
|
|
226
346
|
},
|
|
227
347
|
"models/trace/insights/LCPDiscovery.ts | description": {
|
|
228
348
|
"message": "Lungiselela i-LCP ngokwenza isithombe se-LCP [sitholakale](https://web.dev/articles/optimize-lcp#1_eliminate_resource_load_delay) ku-HTML ngokushesha, futhi [ugweme ukulayisha okulengayo](https://web.dev/articles/lcp-lazy-loading)"
|
|
229
349
|
},
|
|
350
|
+
"models/trace/insights/LCPDiscovery.ts | fetchPriorityApplied": {
|
|
351
|
+
"message": "fetchpriority=high kuyasebenza"
|
|
352
|
+
},
|
|
353
|
+
"models/trace/insights/LCPDiscovery.ts | fetchPriorityShouldBeApplied": {
|
|
354
|
+
"message": "fetchpriority=high should be applied"
|
|
355
|
+
},
|
|
356
|
+
"models/trace/insights/LCPDiscovery.ts | lazyLoadNotApplied": {
|
|
357
|
+
"message": "ukulayisha okulengayo akusebenzi"
|
|
358
|
+
},
|
|
359
|
+
"models/trace/insights/LCPDiscovery.ts | lcpLoadDelay": {
|
|
360
|
+
"message": "Isithombe se-LCP silayishwe kokuthi {PH1} ngemva kwephoyinti lokuqalisa lasekuqaleni."
|
|
361
|
+
},
|
|
362
|
+
"models/trace/insights/LCPDiscovery.ts | noLcp": {
|
|
363
|
+
"message": "Ayikho i-LCP etholakele"
|
|
364
|
+
},
|
|
365
|
+
"models/trace/insights/LCPDiscovery.ts | noLcpResource": {
|
|
366
|
+
"message": "Akutholakalanga mthombo we-LCP ngenxa yokuthi i-LCP ayisona isithombe"
|
|
367
|
+
},
|
|
368
|
+
"models/trace/insights/LCPDiscovery.ts | requestDiscoverable": {
|
|
369
|
+
"message": "Isicelo siyabonakala kudokhumenti yokuqala"
|
|
370
|
+
},
|
|
230
371
|
"models/trace/insights/LCPDiscovery.ts | title": {
|
|
231
372
|
"message": "Ukutholwa kwesicelo se-LCP"
|
|
232
373
|
},
|
|
233
374
|
"models/trace/insights/LCPPhases.ts | description": {
|
|
234
375
|
"message": "Isigaba [ngasinye sinamasu athile okuthuthukiswa](https://web.dev/articles/optimize-lcp#lcp-breakdown). Ngokufanelekile, iningi lesikhathi se-LCP kumele lichithwe ekulayisheni izinsiza, hhayi ngaphakathi kokulibaziseka."
|
|
235
376
|
},
|
|
377
|
+
"models/trace/insights/LCPPhases.ts | duration": {
|
|
378
|
+
"message": "Ubude besikhathi"
|
|
379
|
+
},
|
|
380
|
+
"models/trace/insights/LCPPhases.ts | elementRenderDelay": {
|
|
381
|
+
"message": "Ukwephuza kokunikeza isakhi"
|
|
382
|
+
},
|
|
383
|
+
"models/trace/insights/LCPPhases.ts | fieldDuration": {
|
|
384
|
+
"message": "Amaphesenti angu-75 enkundla"
|
|
385
|
+
},
|
|
386
|
+
"models/trace/insights/LCPPhases.ts | noLcp": {
|
|
387
|
+
"message": "Ayikho i-LCP etholakele"
|
|
388
|
+
},
|
|
389
|
+
"models/trace/insights/LCPPhases.ts | phase": {
|
|
390
|
+
"message": "Isigaba"
|
|
391
|
+
},
|
|
392
|
+
"models/trace/insights/LCPPhases.ts | resourceLoadDelay": {
|
|
393
|
+
"message": "Ukwephuza kokulayisha insiza"
|
|
394
|
+
},
|
|
395
|
+
"models/trace/insights/LCPPhases.ts | resourceLoadDuration": {
|
|
396
|
+
"message": "Ubude besikhathi sokulayisha insiza"
|
|
397
|
+
},
|
|
398
|
+
"models/trace/insights/LCPPhases.ts | timeToFirstByte": {
|
|
399
|
+
"message": "Isikhathi sebhayithi lokuqala"
|
|
400
|
+
},
|
|
236
401
|
"models/trace/insights/LCPPhases.ts | title": {
|
|
237
402
|
"message": "I-LCP ngesigaba"
|
|
238
403
|
},
|
|
239
|
-
"models/trace/insights/
|
|
404
|
+
"models/trace/insights/NetworkDependencyTree.ts | description": {
|
|
240
405
|
"message": "[Gwema ukulandelanisa eduze izicelo ezibucayi](https://developer.chrome.com/docs/lighthouse/performance/critical-request-chains) ngokunciphisa ubude bokulandelana, ukunciphisa usayizi wezinsiza ezidawunilodwayo, noma ukuhlehliswa kokudawunilodwa kwezinsiza ezingadingeki ukuze uthuthukise ukulayisha kwekhasi."
|
|
241
406
|
},
|
|
242
|
-
"models/trace/insights/
|
|
243
|
-
"message": "
|
|
407
|
+
"models/trace/insights/NetworkDependencyTree.ts | maxCriticalPathLatency": {
|
|
408
|
+
"message": "Ukubambezeleka kwendlela ebalulekile enkulu:"
|
|
409
|
+
},
|
|
410
|
+
"models/trace/insights/NetworkDependencyTree.ts | noNetworkDependencyTree": {
|
|
411
|
+
"message": "Ayikho imisebenzi enikeziwe ethintwe okuncike kunethiwekhi"
|
|
412
|
+
},
|
|
413
|
+
"models/trace/insights/NetworkDependencyTree.ts | title": {
|
|
414
|
+
"message": "Isihlahla sokuncika kunethiwekhi"
|
|
415
|
+
},
|
|
416
|
+
"models/trace/insights/NetworkDependencyTree.ts | warningDescription": {
|
|
417
|
+
"message": "Gwema ukuxhumanisa izicelo ezibucayi ngokunciphisa ubude bokuxhumanisa, ukwehlisa usayizi wokudawuniloda wezinsiza, noma ukuhlehlisa ukudawunilodwa kwezinsiza ezingadingekile ukuze kuthuthukiswe ukulayishwa kwekhasi."
|
|
244
418
|
},
|
|
245
419
|
"models/trace/insights/RenderBlocking.ts | description": {
|
|
246
420
|
"message": "Izicelo zivimbela umnikezi wasekuqaleni wekhasi, okungase kubambezele i-LCP. [Ukuhlehlisa noma ukuqondanisa](https://web.dev/learn/performance/understanding-the-critical-path#render-blocking_resources/) kungasusa lezi zicelo zenethiwekhi emzileni obucayi."
|
|
247
421
|
},
|
|
422
|
+
"models/trace/insights/RenderBlocking.ts | duration": {
|
|
423
|
+
"message": "Ubude besikhathi"
|
|
424
|
+
},
|
|
425
|
+
"models/trace/insights/RenderBlocking.ts | noRenderBlocking": {
|
|
426
|
+
"message": "Akukho ukuvinjelwa kwezicelo ezinikezelwe kwalokhu kufuna"
|
|
427
|
+
},
|
|
428
|
+
"models/trace/insights/RenderBlocking.ts | renderBlockingRequest": {
|
|
429
|
+
"message": "Isicelo"
|
|
430
|
+
},
|
|
248
431
|
"models/trace/insights/RenderBlocking.ts | title": {
|
|
249
432
|
"message": "Nikeza izicelo zokuvimbela"
|
|
250
433
|
},
|
|
251
434
|
"models/trace/insights/SlowCSSSelector.ts | description": {
|
|
252
435
|
"message": "Uma izindleko Zesitayela Sokuphinda kubalwe sihlala siphezulu, ukulungiselelwa kwesikhethi kungazinciphisa. [Lungiselela izikhethi](https://developer.chrome.com/docs/devtools/performance/selector-stats) nakho kokubili isikhathi esedlule esiphezulu nendlela ehamba kancane ephezulu engu-%. Izikhethi ezilula, izikhethi ezimbalwa, i-DOM encane, kanye ne-DOM engajulile konke kuzonciphisa izindleko ezifanayo."
|
|
253
436
|
},
|
|
437
|
+
"models/trace/insights/SlowCSSSelector.ts | elapsed": {
|
|
438
|
+
"message": "Isikhathi esedlule"
|
|
439
|
+
},
|
|
440
|
+
"models/trace/insights/SlowCSSSelector.ts | enableSelectorData": {
|
|
441
|
+
"message": "Ayikho idatha yesikhethi se-CSS etholakele. Isibalo sesikhethi se-CSS kudingeka sinikwe amandla kumasethingi okusebenza kwephaneli."
|
|
442
|
+
},
|
|
443
|
+
"models/trace/insights/SlowCSSSelector.ts | matchAttempts": {
|
|
444
|
+
"message": "Imizamo yokuqhathanisa"
|
|
445
|
+
},
|
|
446
|
+
"models/trace/insights/SlowCSSSelector.ts | matchCount": {
|
|
447
|
+
"message": "Isibalo sokufanayo"
|
|
448
|
+
},
|
|
254
449
|
"models/trace/insights/SlowCSSSelector.ts | title": {
|
|
255
450
|
"message": "Izindleko Zesikhethi se-CSS"
|
|
256
451
|
},
|
|
452
|
+
"models/trace/insights/SlowCSSSelector.ts | topSelectors": {
|
|
453
|
+
"message": "Izikhethi eziphezulu"
|
|
454
|
+
},
|
|
455
|
+
"models/trace/insights/SlowCSSSelector.ts | total": {
|
|
456
|
+
"message": "Ingqikithi"
|
|
457
|
+
},
|
|
458
|
+
"models/trace/insights/ThirdParties.ts | columnMainThreadTime": {
|
|
459
|
+
"message": "Isikhathi esikhulu sochungechunge"
|
|
460
|
+
},
|
|
461
|
+
"models/trace/insights/ThirdParties.ts | columnThirdParty": {
|
|
462
|
+
"message": "Inkampani engahlangene ngqo"
|
|
463
|
+
},
|
|
464
|
+
"models/trace/insights/ThirdParties.ts | columnTransferSize": {
|
|
465
|
+
"message": "Usayizi wokudlulisela"
|
|
466
|
+
},
|
|
257
467
|
"models/trace/insights/ThirdParties.ts | description": {
|
|
258
|
-
"message": "Ikhodi yenkampani engahlangene ngqo
|
|
468
|
+
"message": "Ikhodi yenkampani engahlangene ngqo ingathinta ukusebenza kokulayisha. [Nciphisa uphinde uhlehlise ukulayishwa kwekhodi yenkampani engahlangene ngqo](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/loading-third-party-javascript/) ukuze wenze kubaluleke ikhontenti yekhasi lakho."
|
|
469
|
+
},
|
|
470
|
+
"models/trace/insights/ThirdParties.ts | noThirdParties": {
|
|
471
|
+
"message": "Ayikho inhlangano engahlangene ngqo etholakele"
|
|
259
472
|
},
|
|
260
473
|
"models/trace/insights/ThirdParties.ts | title": {
|
|
261
474
|
"message": "Izinkampani ezingahlangene ngqo"
|
|
@@ -299,9 +299,10 @@ export class TraceProcessor extends EventTarget {
|
|
|
299
299
|
Viewport: null,
|
|
300
300
|
DOMSize: null,
|
|
301
301
|
ThirdParties: null,
|
|
302
|
-
|
|
302
|
+
DuplicatedJavaScript: null,
|
|
303
303
|
SlowCSSSelector: null,
|
|
304
304
|
ForcedReflow: null,
|
|
305
|
+
UseCache: null,
|
|
305
306
|
};
|
|
306
307
|
// Determine the weights for each metric based on field data, utilizing the same scoring curve that Lighthouse uses.
|
|
307
308
|
const weights = Insights.Common.calculateMetricWeightsForSorting(insightSet, metadata);
|
|
@@ -366,12 +367,13 @@ export class TraceProcessor extends EventTarget {
|
|
|
366
367
|
let id, urlString, navigation;
|
|
367
368
|
if (context.navigation) {
|
|
368
369
|
id = context.navigationId;
|
|
369
|
-
urlString =
|
|
370
|
+
urlString =
|
|
371
|
+
parsedTrace.Meta.finalDisplayUrlByNavigationId.get(context.navigationId) ?? parsedTrace.Meta.mainFrameURL;
|
|
370
372
|
navigation = context.navigation;
|
|
371
373
|
}
|
|
372
374
|
else {
|
|
373
375
|
id = Types.Events.NO_NAVIGATION;
|
|
374
|
-
urlString = parsedTrace.Meta.mainFrameURL;
|
|
376
|
+
urlString = parsedTrace.Meta.finalDisplayUrlByNavigationId.get('') ?? parsedTrace.Meta.mainFrameURL;
|
|
375
377
|
}
|
|
376
378
|
const model = {};
|
|
377
379
|
for (const [name, insight] of Object.entries(TraceProcessor.getInsightRunners())) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Processor.js","sourceRoot":"","sources":["../../../../../../front_end/models/trace/Processor.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Handlers from './handlers/handlers.js';\nimport * as Helpers from './helpers/helpers.js';\nimport * as Insights from './insights/insights.js';\nimport * as Lantern from './lantern/lantern.js';\nimport * as LanternComputationData from './LanternComputationData.js';\nimport type * as Model from './ModelImpl.js';\nimport * as Types from './types/types.js';\n\nconst enum Status {\n IDLE = 'IDLE',\n PARSING = 'PARSING',\n FINISHED_PARSING = 'FINISHED_PARSING',\n ERRORED_WHILE_PARSING = 'ERRORED_WHILE_PARSING',\n}\n\nexport class TraceParseProgressEvent extends Event {\n static readonly eventName = 'traceparseprogress';\n constructor(public data: Model.TraceParseEventProgressData, init: EventInit = {bubbles: true}) {\n super(TraceParseProgressEvent.eventName, init);\n }\n}\n\n/**\n * Parsing a trace can take time. On large traces we see a breakdown of time like so:\n * - handleEvent() loop: ~20%\n * - finalize() loop: ~60%\n * - shallowClone calls: ~20%\n * The numbers below are set so we can report a progress percentage of [0...1]\n */\nconst enum ProgressPhase {\n HANDLE_EVENT = 0.2,\n FINALIZE = 0.8,\n CLONE = 1.0,\n}\nfunction calculateProgress(value: number, phase: ProgressPhase): number {\n // Finalize values should be [0.2...0.8]\n if (phase === ProgressPhase.FINALIZE) {\n return (value * (ProgressPhase.FINALIZE - ProgressPhase.HANDLE_EVENT)) + ProgressPhase.HANDLE_EVENT;\n }\n return value * phase;\n}\n\ndeclare global {\n interface HTMLElementEventMap {\n [TraceParseProgressEvent.eventName]: TraceParseProgressEvent;\n }\n}\n\nexport class TraceProcessor extends EventTarget {\n // We force the Meta handler to be enabled, so the TraceHandlers type here is\n // the model handlers the user passes in and the Meta handler.\n readonly #traceHandlers: Partial<Handlers.Types.Handlers>;\n #status = Status.IDLE;\n #modelConfiguration = Types.Configuration.defaults();\n #data: Handlers.Types.ParsedTrace|null = null;\n #insights: Insights.Types.TraceInsightSets|null = null;\n\n static createWithAllHandlers(): TraceProcessor {\n return new TraceProcessor(Handlers.ModelHandlers, Types.Configuration.defaults());\n }\n\n /**\n * This function is kept for testing with `stub`.\n */\n static getInsightRunners(): Insights.Types.InsightModelsType {\n return {...Insights.Models};\n }\n\n constructor(traceHandlers: Partial<Handlers.Types.Handlers>, modelConfiguration?: Types.Configuration.Configuration) {\n super();\n\n this.#verifyHandlers(traceHandlers);\n this.#traceHandlers = {\n Meta: Handlers.ModelHandlers.Meta,\n ...traceHandlers,\n };\n if (modelConfiguration) {\n this.#modelConfiguration = modelConfiguration;\n }\n this.#passConfigToHandlers();\n }\n\n #passConfigToHandlers(): void {\n for (const handler of Object.values(this.#traceHandlers)) {\n // Bit of an odd double check, but without this TypeScript refuses to let\n // you call the function as it thinks it might be undefined.\n if ('handleUserConfig' in handler && handler.handleUserConfig) {\n handler.handleUserConfig(this.#modelConfiguration);\n }\n }\n }\n\n /**\n * When the user passes in a set of handlers, we want to ensure that we have all\n * the required handlers. Handlers can depend on other handlers, so if the user\n * passes in FooHandler which depends on BarHandler, they must also pass in\n * BarHandler too. This method verifies that all dependencies are met, and\n * throws if not.\n **/\n #verifyHandlers(providedHandlers: Partial<Handlers.Types.Handlers>): void {\n // Tiny optimisation: if the amount of provided handlers matches the amount\n // of handlers in the Handlers.ModelHandlers object, that means that the\n // user has passed in every handler we have. So therefore they cannot have\n // missed any, and there is no need to iterate through the handlers and\n // check the dependencies.\n if (Object.keys(providedHandlers).length === Object.keys(Handlers.ModelHandlers).length) {\n return;\n }\n const requiredHandlerKeys = new Set<Handlers.Types.HandlerName>();\n for (const [handlerName, handler] of Object.entries(providedHandlers)) {\n requiredHandlerKeys.add(handlerName as Handlers.Types.HandlerName);\n const deps = 'deps' in handler ? handler.deps() : [];\n for (const depName of deps) {\n requiredHandlerKeys.add(depName);\n }\n }\n\n const providedHandlerKeys = new Set(Object.keys(providedHandlers));\n // We always force the Meta handler to be enabled when creating the\n // Processor, so if it is missing from the set the user gave us that is OK,\n // as we will have enabled it anyway.\n requiredHandlerKeys.delete('Meta');\n\n for (const requiredKey of requiredHandlerKeys) {\n if (!providedHandlerKeys.has(requiredKey)) {\n throw new Error(`Required handler ${requiredKey} not provided.`);\n }\n }\n }\n\n reset(): void {\n if (this.#status === Status.PARSING) {\n throw new Error('Trace processor can\\'t reset while parsing.');\n }\n\n const handlers = Object.values(this.#traceHandlers);\n for (const handler of handlers) {\n handler.reset();\n }\n\n this.#data = null;\n this.#insights = null;\n this.#status = Status.IDLE;\n }\n\n async parse(traceEvents: readonly Types.Events.Event[], options: Types.Configuration.ParseOptions): Promise<void> {\n if (this.#status !== Status.IDLE) {\n throw new Error(`Trace processor can't start parsing when not idle. Current state: ${this.#status}`);\n }\n\n options.logger?.start('total');\n try {\n this.#status = Status.PARSING;\n options.logger?.start('parse');\n await this.#computeParsedTrace(traceEvents, options);\n options.logger?.end('parse');\n if (this.#data && !options.isCPUProfile) { // We do not calculate insights for CPU Profiles.\n options.logger?.start('insights');\n this.#computeInsights(this.#data, traceEvents, options);\n options.logger?.end('insights');\n }\n this.#status = Status.FINISHED_PARSING;\n } catch (e) {\n this.#status = Status.ERRORED_WHILE_PARSING;\n throw e;\n } finally {\n options.logger?.end('total');\n }\n }\n\n /**\n * Run all the handlers and set the result to `#data`.\n */\n async #computeParsedTrace(traceEvents: readonly Types.Events.Event[], options: Types.Configuration.ParseOptions):\n Promise<void> {\n /**\n * We want to yield regularly to maintain responsiveness. If we yield too often, we're wasting idle time.\n * We could do this by checking `performance.now()` regularly, but it's an expensive call in such a hot loop.\n * `eventsPerChunk` is an approximated proxy metric.\n * But how big a chunk? We're aiming for long tasks that are no smaller than 100ms and not bigger than 200ms.\n * It's CPU dependent, so it should be calibrated on oldish hardware.\n * Illustration of a previous change to `eventsPerChunk`: https://imgur.com/wzp8BnR\n */\n const eventsPerChunk = 50_000;\n // Convert to array so that we are able to iterate all handlers multiple times.\n const sortedHandlers = [...sortHandlers(this.#traceHandlers).entries()];\n\n // Reset.\n for (const [, handler] of sortedHandlers) {\n handler.reset();\n }\n\n options.logger?.start('parse:handleEvent');\n\n // Handle each event.\n for (let i = 0; i < traceEvents.length; ++i) {\n // Every so often we take a break just to render.\n if (i % eventsPerChunk === 0 && i) {\n // Take the opportunity to provide status update events.\n const percent = calculateProgress(i / traceEvents.length, ProgressPhase.HANDLE_EVENT);\n this.dispatchEvent(new TraceParseProgressEvent({percent}));\n // TODO(paulirish): consider using `scheduler.yield()` or `scheduler.postTask(() => {}, {priority: 'user-blocking'})`\n await new Promise(resolve => setTimeout(resolve, 0));\n }\n const event = traceEvents[i];\n for (let j = 0; j < sortedHandlers.length; ++j) {\n const [, handler] = sortedHandlers[j];\n handler.handleEvent(event);\n }\n }\n\n options.logger?.end('parse:handleEvent');\n\n // Finalize.\n for (let i = 0; i < sortedHandlers.length; i++) {\n const [name, handler] = sortedHandlers[i];\n if (handler.finalize) {\n options.logger?.start(`parse:${name}:finalize`);\n // Yield to the UI because finalize() calls can be expensive\n // TODO(jacktfranklin): consider using `scheduler.yield()` or `scheduler.postTask(() => {}, {priority: 'user-blocking'})`\n await new Promise(resolve => setTimeout(resolve, 0));\n await handler.finalize(options);\n options.logger?.end(`parse:${name}:finalize`);\n }\n const percent = calculateProgress(i / sortedHandlers.length, ProgressPhase.FINALIZE);\n this.dispatchEvent(new TraceParseProgressEvent({percent}));\n }\n\n // Handlers that depend on other handlers do so via .data(), which used to always\n // return a shallow clone of its internal data structures. However, that pattern\n // easily results in egregious amounts of allocation. Now .data() does not do any\n // cloning, and it happens here instead so that users of the trace processor may\n // still assume that the parsed data is theirs.\n // See: crbug/41484172\n const shallowClone = (value: unknown, recurse = true): unknown => {\n if (value instanceof Map) {\n return new Map(value);\n }\n if (value instanceof Set) {\n return new Set(value);\n }\n if (Array.isArray(value)) {\n return [...value];\n }\n if (typeof value === 'object' && value && recurse) {\n const obj: Record<string, unknown> = {};\n for (const [key, v] of Object.entries(value)) {\n obj[key] = shallowClone(v, false);\n }\n return obj;\n }\n return value;\n };\n\n options.logger?.start('parse:clone');\n const parsedTrace = {};\n for (const [name, handler] of Object.entries(this.#traceHandlers)) {\n const data = shallowClone(handler.data());\n Object.assign(parsedTrace, {[name]: data});\n }\n options.logger?.end('parse:clone');\n\n this.dispatchEvent(new TraceParseProgressEvent({percent: ProgressPhase.CLONE}));\n\n this.#data = parsedTrace as Handlers.Types.ParsedTrace;\n }\n\n get parsedTrace(): Handlers.Types.ParsedTrace|null {\n if (this.#status !== Status.FINISHED_PARSING) {\n return null;\n }\n\n return this.#data;\n }\n\n get insights(): Insights.Types.TraceInsightSets|null {\n if (this.#status !== Status.FINISHED_PARSING) {\n return null;\n }\n\n return this.#insights;\n }\n\n #createLanternContext(\n parsedTrace: Handlers.Types.ParsedTrace, traceEvents: readonly Types.Events.Event[], frameId: string,\n navigationId: string, options: Types.Configuration.ParseOptions): Insights.Types.LanternContext|undefined {\n // Check for required handlers.\n if (!parsedTrace.NetworkRequests || !parsedTrace.Workers || !parsedTrace.PageLoadMetrics) {\n return;\n }\n if (!parsedTrace.NetworkRequests.byTime.length) {\n throw new Lantern.Core.LanternError('No network requests found in trace');\n }\n\n const navStarts = parsedTrace.Meta.navigationsByFrameId.get(frameId);\n const navStartIndex = navStarts?.findIndex(n => n.args.data?.navigationId === navigationId);\n if (!navStarts || navStartIndex === undefined || navStartIndex === -1) {\n throw new Lantern.Core.LanternError('Could not find navigation start');\n }\n\n const startTime = navStarts[navStartIndex].ts;\n const endTime = navStartIndex + 1 < navStarts.length ? navStarts[navStartIndex + 1].ts : Number.POSITIVE_INFINITY;\n const boundedTraceEvents = traceEvents.filter(e => e.ts >= startTime && e.ts < endTime);\n\n // Lantern.Types.TraceEvent and Types.Events.Event represent the same\n // object - a trace event - but one is more flexible than the other. It should be safe to cast between them.\n const trace: Lantern.Types.Trace = {\n traceEvents: boundedTraceEvents as unknown as Lantern.Types.TraceEvent[],\n };\n\n const requests = LanternComputationData.createNetworkRequests(trace, parsedTrace, startTime, endTime);\n const graph = LanternComputationData.createGraph(requests, trace, parsedTrace);\n const processedNavigation = LanternComputationData.createProcessedNavigation(parsedTrace, frameId, navigationId);\n\n const networkAnalysis = Lantern.Core.NetworkAnalyzer.analyze(requests);\n if (!networkAnalysis) {\n return;\n }\n\n const lanternSettings: Lantern.Types.Simulation.Settings = {\n // TODO(crbug.com/372674229): if devtools throttling was on, does this network analysis capture\n // that? Do we need to set 'devtools' throttlingMethod?\n networkAnalysis,\n throttlingMethod: 'provided',\n ...options.lanternSettings,\n };\n const simulator: Lantern.Simulation.Simulator<Types.Events.SyntheticNetworkRequest> =\n Lantern.Simulation.Simulator.createSimulator(lanternSettings);\n\n const computeData = {graph, simulator, processedNavigation};\n const fcpResult = Lantern.Metrics.FirstContentfulPaint.compute(computeData);\n const lcpResult = Lantern.Metrics.LargestContentfulPaint.compute(computeData, {fcpResult});\n const interactiveResult = Lantern.Metrics.Interactive.compute(computeData, {lcpResult});\n const tbtResult = Lantern.Metrics.TotalBlockingTime.compute(computeData, {fcpResult, interactiveResult});\n const metrics = {\n firstContentfulPaint: fcpResult,\n interactive: interactiveResult,\n largestContentfulPaint: lcpResult,\n totalBlockingTime: tbtResult,\n };\n\n return {graph, simulator, metrics};\n }\n\n /**\n * Sort the insight models based on the impact of each insight's estimated savings, additionally weighted by the\n * worst metrics according to field data (if present).\n */\n sortInsightSet(\n insights: Insights.Types.TraceInsightSets, insightSet: Insights.Types.InsightSet,\n metadata: Types.File.MetaData|null): void {\n // The initial order of the insights is alphabetical, based on `front_end/models/trace/insights/Models.ts`.\n // The order here provides a baseline that groups insights in a more logical way.\n const baselineOrder: Record<keyof Insights.Types.InsightModels, null> = {\n InteractionToNextPaint: null,\n LCPPhases: null,\n LCPDiscovery: null,\n CLSCulprits: null,\n RenderBlocking: null,\n NetworkDependencyTree: null,\n ImageDelivery: null,\n DocumentLatency: null,\n FontDisplay: null,\n Viewport: null,\n DOMSize: null,\n ThirdParties: null,\n DuplicateJavaScript: null,\n SlowCSSSelector: null,\n ForcedReflow: null,\n };\n\n // Determine the weights for each metric based on field data, utilizing the same scoring curve that Lighthouse uses.\n const weights = Insights.Common.calculateMetricWeightsForSorting(insightSet, metadata);\n\n // Normalize the estimated savings to a single number, weighted by its relative impact\n // to the page experience based on the same scoring curve that Lighthouse uses.\n const observedLcp = Insights.Common.getLCP(insights, insightSet.id)?.value;\n const observedCls = Insights.Common.getCLS(insights, insightSet.id).value;\n\n // INP is special - if users did not interact with the page, we'll have no INP, but we should still\n // be able to prioritize insights based on this metric. When we observe no interaction, instead use\n // a default value for the baseline INP.\n const observedInp = Insights.Common.getINP(insights, insightSet.id)?.value ?? 200;\n\n const observedLcpScore =\n observedLcp !== undefined ? Insights.Common.evaluateLCPMetricScore(observedLcp) : undefined;\n const observedInpScore = Insights.Common.evaluateINPMetricScore(observedInp);\n const observedClsScore = Insights.Common.evaluateCLSMetricScore(observedCls);\n\n const insightToSortingRank = new Map<string, number>();\n for (const [name, model] of Object.entries(insightSet.model)) {\n const lcp = model.metricSavings?.LCP ?? 0;\n const inp = model.metricSavings?.INP ?? 0;\n const cls = model.metricSavings?.CLS ?? 0;\n\n const lcpPostSavings = observedLcp !== undefined ? Math.max(0, observedLcp - lcp) : undefined;\n const inpPostSavings = Math.max(0, observedInp - inp);\n const clsPostSavings = Math.max(0, observedCls - cls);\n\n let score = 0;\n if (weights.lcp && lcp && observedLcpScore !== undefined && lcpPostSavings !== undefined) {\n score += weights.lcp * (Insights.Common.evaluateLCPMetricScore(lcpPostSavings) - observedLcpScore);\n }\n if (weights.inp && inp && observedInpScore !== undefined) {\n score += weights.inp * (Insights.Common.evaluateINPMetricScore(inpPostSavings) - observedInpScore);\n }\n if (weights.cls && cls && observedClsScore !== undefined) {\n score += weights.cls * (Insights.Common.evaluateCLSMetricScore(clsPostSavings) - observedClsScore);\n }\n\n insightToSortingRank.set(name, score);\n }\n\n // Now perform the actual sorting.\n const baselineOrderKeys = Object.keys(baselineOrder);\n const orderedKeys = Object.keys(insightSet.model);\n orderedKeys.sort((a, b) => {\n const a1 = baselineOrderKeys.indexOf(a);\n const b1 = baselineOrderKeys.indexOf(b);\n if (a1 >= 0 && b1 >= 0) {\n return a1 - b1;\n }\n if (a1 >= 0) {\n return -1;\n }\n if (b1 >= 0) {\n return 1;\n }\n return 0;\n });\n orderedKeys.sort((a, b) => (insightToSortingRank.get(b) ?? 0) - (insightToSortingRank.get(a) ?? 0));\n\n const newModel = {} as Insights.Types.InsightModels;\n for (const key of orderedKeys as Array<keyof Insights.Types.InsightModels>) {\n const model = insightSet.model[key];\n // @ts-expect-error Maybe someday typescript will be powerful enough to handle this.\n newModel[key] = model;\n }\n insightSet.model = newModel;\n }\n\n #computeInsightSet(\n insights: Insights.Types.TraceInsightSets, parsedTrace: Handlers.Types.ParsedTrace,\n context: Insights.Types.InsightSetContext, options: Types.Configuration.ParseOptions): void {\n let id, urlString, navigation;\n if (context.navigation) {\n id = context.navigationId;\n urlString = context.navigation.args.data?.documentLoaderURL ?? parsedTrace.Meta.mainFrameURL;\n navigation = context.navigation;\n } else {\n id = Types.Events.NO_NAVIGATION;\n urlString = parsedTrace.Meta.mainFrameURL;\n }\n\n const model = {} as Insights.Types.InsightSet['model'];\n\n for (const [name, insight] of Object.entries(TraceProcessor.getInsightRunners())) {\n let insightResult;\n try {\n options.logger?.start(`insights:${name}`);\n insightResult = insight.generateInsight(parsedTrace, context);\n insightResult.frameId = context.frameId;\n const navId = context.navigation?.args.data?.navigationId;\n if (navId) {\n insightResult.navigationId = navId;\n }\n } catch (err) {\n insightResult = err;\n } finally {\n options.logger?.end(`insights:${name}`);\n }\n Object.assign(model, {[name]: insightResult});\n }\n\n let url;\n try {\n url = new URL(urlString);\n } catch {\n // We're pretty sure this only happens for our test fixture: missing-url.json.gz. Shouldn't\n // happen for real traces.\n return;\n }\n\n const insightSet: Insights.Types.InsightSet = {\n id,\n url,\n navigation,\n frameId: context.frameId,\n bounds: context.bounds,\n model,\n };\n insights.set(insightSet.id, insightSet);\n this.sortInsightSet(insights, insightSet, options.metadata ?? null);\n }\n\n /**\n * Run all the insights and set the result to `#insights`.\n */\n #computeInsights(\n parsedTrace: Handlers.Types.ParsedTrace, traceEvents: readonly Types.Events.Event[],\n options: Types.Configuration.ParseOptions): void {\n this.#insights = new Map();\n\n const navigations = parsedTrace.Meta.mainFrameNavigations.filter(\n navigation => navigation.args.frame && navigation.args.data?.navigationId);\n\n // Check if there is a meaningful chunk of work happening prior to the first navigation.\n // If so, we run the insights on that initial bounds.\n // Otherwise, there are no navigations and we do a no-navigation insights pass on the entire trace.\n if (navigations.length) {\n const bounds = Helpers.Timing.traceWindowFromMicroSeconds(parsedTrace.Meta.traceBounds.min, navigations[0].ts);\n // When using \"Record and reload\" option, it typically takes ~5ms. So use 50ms to be safe.\n const threshold = Helpers.Timing.milliToMicro(50 as Types.Timing.Milli);\n if (bounds.range > threshold) {\n const context: Insights.Types.InsightSetContext = {\n bounds,\n frameId: parsedTrace.Meta.mainFrameId,\n };\n this.#computeInsightSet(this.#insights, parsedTrace, context, options);\n }\n // If threshold is not met, then the very beginning of the trace is ignored by the insights engine.\n } else {\n const context: Insights.Types.InsightSetContext = {\n bounds: parsedTrace.Meta.traceBounds,\n frameId: parsedTrace.Meta.mainFrameId,\n };\n this.#computeInsightSet(this.#insights, parsedTrace, context, options);\n }\n\n // Now run the insights for each navigation in isolation.\n for (const [i, navigation] of navigations.entries()) {\n // The above filter guarantees these are present.\n const frameId = navigation.args.frame;\n const navigationId = navigation.args.data?.navigationId as string;\n\n // The lantern sub-context is optional on InsightSetContext, so not setting it is OK.\n // This is also a hedge against an error inside Lantern resulting in breaking the entire performance panel.\n // Additionally, many trace fixtures are too old to be processed by Lantern.\n let lantern;\n try {\n options.logger?.start('insights:createLanternContext');\n lantern = this.#createLanternContext(parsedTrace, traceEvents, frameId, navigationId, options);\n } catch (e) {\n // Don't allow an error in constructing the Lantern graphs to break the rest of the trace processor.\n // Log unexpected errors, but suppress anything that occurs from a trace being too old.\n // Otherwise tests using old fixtures become way too noisy.\n const expectedErrors = [\n 'mainDocumentRequest not found',\n 'missing metric scores for main frame',\n 'missing metric: FCP',\n 'missing metric: LCP',\n 'No network requests found in trace',\n 'Trace is too old',\n ];\n if (!(e instanceof Lantern.Core.LanternError)) {\n // If this wasn't a managed LanternError, the stack trace is likely needed for debugging.\n console.error(e);\n } else if (!expectedErrors.some(err => e.message === err)) {\n // To reduce noise from tests, only print errors that are not expected to occur because a trace is\n // too old (for which there is no single check).\n console.error(e);\n }\n } finally {\n options.logger?.end('insights:createLanternContext');\n }\n\n const min = navigation.ts;\n const max = i + 1 < navigations.length ? navigations[i + 1].ts : parsedTrace.Meta.traceBounds.max;\n const bounds = Helpers.Timing.traceWindowFromMicroSeconds(min, max);\n const context: Insights.Types.InsightSetContext = {\n bounds,\n frameId,\n navigation,\n navigationId,\n lantern,\n };\n\n this.#computeInsightSet(this.#insights, parsedTrace, context, options);\n }\n }\n}\n\n/**\n * Some Handlers need data provided by others. Dependencies of a handler handler are\n * declared in the `deps` field.\n * @returns A map from trace event handler name to trace event handler whose entries\n * iterate in such a way that each handler is visited after its dependencies.\n */\nexport function sortHandlers(traceHandlers: Partial<{[key in Handlers.Types.HandlerName]: Handlers.Types.Handler}>):\n Map<Handlers.Types.HandlerName, Handlers.Types.Handler> {\n const sortedMap = new Map<Handlers.Types.HandlerName, Handlers.Types.Handler>();\n const visited = new Set<Handlers.Types.HandlerName>();\n const visitHandler = (handlerName: Handlers.Types.HandlerName): void => {\n if (sortedMap.has(handlerName)) {\n return;\n }\n if (visited.has(handlerName)) {\n let stackPath = '';\n for (const handler of visited) {\n if (stackPath || handler === handlerName) {\n stackPath += `${handler}->`;\n }\n }\n stackPath += handlerName;\n throw new Error(`Found dependency cycle in trace event handlers: ${stackPath}`);\n }\n visited.add(handlerName);\n const handler = traceHandlers[handlerName];\n if (!handler) {\n return;\n }\n const deps = handler.deps?.();\n if (deps) {\n deps.forEach(visitHandler);\n }\n sortedMap.set(handlerName, handler);\n };\n\n for (const handlerName of Object.keys(traceHandlers)) {\n visitHandler(handlerName as Handlers.Types.HandlerName);\n }\n return sortedMap;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Processor.js","sourceRoot":"","sources":["../../../../../../front_end/models/trace/Processor.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Handlers from './handlers/handlers.js';\nimport * as Helpers from './helpers/helpers.js';\nimport * as Insights from './insights/insights.js';\nimport * as Lantern from './lantern/lantern.js';\nimport * as LanternComputationData from './LanternComputationData.js';\nimport type * as Model from './ModelImpl.js';\nimport * as Types from './types/types.js';\n\nconst enum Status {\n IDLE = 'IDLE',\n PARSING = 'PARSING',\n FINISHED_PARSING = 'FINISHED_PARSING',\n ERRORED_WHILE_PARSING = 'ERRORED_WHILE_PARSING',\n}\n\nexport class TraceParseProgressEvent extends Event {\n static readonly eventName = 'traceparseprogress';\n constructor(public data: Model.TraceParseEventProgressData, init: EventInit = {bubbles: true}) {\n super(TraceParseProgressEvent.eventName, init);\n }\n}\n\n/**\n * Parsing a trace can take time. On large traces we see a breakdown of time like so:\n * - handleEvent() loop: ~20%\n * - finalize() loop: ~60%\n * - shallowClone calls: ~20%\n * The numbers below are set so we can report a progress percentage of [0...1]\n */\nconst enum ProgressPhase {\n HANDLE_EVENT = 0.2,\n FINALIZE = 0.8,\n CLONE = 1.0,\n}\nfunction calculateProgress(value: number, phase: ProgressPhase): number {\n // Finalize values should be [0.2...0.8]\n if (phase === ProgressPhase.FINALIZE) {\n return (value * (ProgressPhase.FINALIZE - ProgressPhase.HANDLE_EVENT)) + ProgressPhase.HANDLE_EVENT;\n }\n return value * phase;\n}\n\ndeclare global {\n interface HTMLElementEventMap {\n [TraceParseProgressEvent.eventName]: TraceParseProgressEvent;\n }\n}\n\nexport class TraceProcessor extends EventTarget {\n // We force the Meta handler to be enabled, so the TraceHandlers type here is\n // the model handlers the user passes in and the Meta handler.\n readonly #traceHandlers: Partial<Handlers.Types.Handlers>;\n #status = Status.IDLE;\n #modelConfiguration = Types.Configuration.defaults();\n #data: Handlers.Types.ParsedTrace|null = null;\n #insights: Insights.Types.TraceInsightSets|null = null;\n\n static createWithAllHandlers(): TraceProcessor {\n return new TraceProcessor(Handlers.ModelHandlers, Types.Configuration.defaults());\n }\n\n /**\n * This function is kept for testing with `stub`.\n */\n static getInsightRunners(): Insights.Types.InsightModelsType {\n return {...Insights.Models};\n }\n\n constructor(traceHandlers: Partial<Handlers.Types.Handlers>, modelConfiguration?: Types.Configuration.Configuration) {\n super();\n\n this.#verifyHandlers(traceHandlers);\n this.#traceHandlers = {\n Meta: Handlers.ModelHandlers.Meta,\n ...traceHandlers,\n };\n if (modelConfiguration) {\n this.#modelConfiguration = modelConfiguration;\n }\n this.#passConfigToHandlers();\n }\n\n #passConfigToHandlers(): void {\n for (const handler of Object.values(this.#traceHandlers)) {\n // Bit of an odd double check, but without this TypeScript refuses to let\n // you call the function as it thinks it might be undefined.\n if ('handleUserConfig' in handler && handler.handleUserConfig) {\n handler.handleUserConfig(this.#modelConfiguration);\n }\n }\n }\n\n /**\n * When the user passes in a set of handlers, we want to ensure that we have all\n * the required handlers. Handlers can depend on other handlers, so if the user\n * passes in FooHandler which depends on BarHandler, they must also pass in\n * BarHandler too. This method verifies that all dependencies are met, and\n * throws if not.\n **/\n #verifyHandlers(providedHandlers: Partial<Handlers.Types.Handlers>): void {\n // Tiny optimisation: if the amount of provided handlers matches the amount\n // of handlers in the Handlers.ModelHandlers object, that means that the\n // user has passed in every handler we have. So therefore they cannot have\n // missed any, and there is no need to iterate through the handlers and\n // check the dependencies.\n if (Object.keys(providedHandlers).length === Object.keys(Handlers.ModelHandlers).length) {\n return;\n }\n const requiredHandlerKeys = new Set<Handlers.Types.HandlerName>();\n for (const [handlerName, handler] of Object.entries(providedHandlers)) {\n requiredHandlerKeys.add(handlerName as Handlers.Types.HandlerName);\n const deps = 'deps' in handler ? handler.deps() : [];\n for (const depName of deps) {\n requiredHandlerKeys.add(depName);\n }\n }\n\n const providedHandlerKeys = new Set(Object.keys(providedHandlers));\n // We always force the Meta handler to be enabled when creating the\n // Processor, so if it is missing from the set the user gave us that is OK,\n // as we will have enabled it anyway.\n requiredHandlerKeys.delete('Meta');\n\n for (const requiredKey of requiredHandlerKeys) {\n if (!providedHandlerKeys.has(requiredKey)) {\n throw new Error(`Required handler ${requiredKey} not provided.`);\n }\n }\n }\n\n reset(): void {\n if (this.#status === Status.PARSING) {\n throw new Error('Trace processor can\\'t reset while parsing.');\n }\n\n const handlers = Object.values(this.#traceHandlers);\n for (const handler of handlers) {\n handler.reset();\n }\n\n this.#data = null;\n this.#insights = null;\n this.#status = Status.IDLE;\n }\n\n async parse(traceEvents: readonly Types.Events.Event[], options: Types.Configuration.ParseOptions): Promise<void> {\n if (this.#status !== Status.IDLE) {\n throw new Error(`Trace processor can't start parsing when not idle. Current state: ${this.#status}`);\n }\n\n options.logger?.start('total');\n try {\n this.#status = Status.PARSING;\n options.logger?.start('parse');\n await this.#computeParsedTrace(traceEvents, options);\n options.logger?.end('parse');\n if (this.#data && !options.isCPUProfile) { // We do not calculate insights for CPU Profiles.\n options.logger?.start('insights');\n this.#computeInsights(this.#data, traceEvents, options);\n options.logger?.end('insights');\n }\n this.#status = Status.FINISHED_PARSING;\n } catch (e) {\n this.#status = Status.ERRORED_WHILE_PARSING;\n throw e;\n } finally {\n options.logger?.end('total');\n }\n }\n\n /**\n * Run all the handlers and set the result to `#data`.\n */\n async #computeParsedTrace(traceEvents: readonly Types.Events.Event[], options: Types.Configuration.ParseOptions):\n Promise<void> {\n /**\n * We want to yield regularly to maintain responsiveness. If we yield too often, we're wasting idle time.\n * We could do this by checking `performance.now()` regularly, but it's an expensive call in such a hot loop.\n * `eventsPerChunk` is an approximated proxy metric.\n * But how big a chunk? We're aiming for long tasks that are no smaller than 100ms and not bigger than 200ms.\n * It's CPU dependent, so it should be calibrated on oldish hardware.\n * Illustration of a previous change to `eventsPerChunk`: https://imgur.com/wzp8BnR\n */\n const eventsPerChunk = 50_000;\n // Convert to array so that we are able to iterate all handlers multiple times.\n const sortedHandlers = [...sortHandlers(this.#traceHandlers).entries()];\n\n // Reset.\n for (const [, handler] of sortedHandlers) {\n handler.reset();\n }\n\n options.logger?.start('parse:handleEvent');\n\n // Handle each event.\n for (let i = 0; i < traceEvents.length; ++i) {\n // Every so often we take a break just to render.\n if (i % eventsPerChunk === 0 && i) {\n // Take the opportunity to provide status update events.\n const percent = calculateProgress(i / traceEvents.length, ProgressPhase.HANDLE_EVENT);\n this.dispatchEvent(new TraceParseProgressEvent({percent}));\n // TODO(paulirish): consider using `scheduler.yield()` or `scheduler.postTask(() => {}, {priority: 'user-blocking'})`\n await new Promise(resolve => setTimeout(resolve, 0));\n }\n const event = traceEvents[i];\n for (let j = 0; j < sortedHandlers.length; ++j) {\n const [, handler] = sortedHandlers[j];\n handler.handleEvent(event);\n }\n }\n\n options.logger?.end('parse:handleEvent');\n\n // Finalize.\n for (let i = 0; i < sortedHandlers.length; i++) {\n const [name, handler] = sortedHandlers[i];\n if (handler.finalize) {\n options.logger?.start(`parse:${name}:finalize`);\n // Yield to the UI because finalize() calls can be expensive\n // TODO(jacktfranklin): consider using `scheduler.yield()` or `scheduler.postTask(() => {}, {priority: 'user-blocking'})`\n await new Promise(resolve => setTimeout(resolve, 0));\n await handler.finalize(options);\n options.logger?.end(`parse:${name}:finalize`);\n }\n const percent = calculateProgress(i / sortedHandlers.length, ProgressPhase.FINALIZE);\n this.dispatchEvent(new TraceParseProgressEvent({percent}));\n }\n\n // Handlers that depend on other handlers do so via .data(), which used to always\n // return a shallow clone of its internal data structures. However, that pattern\n // easily results in egregious amounts of allocation. Now .data() does not do any\n // cloning, and it happens here instead so that users of the trace processor may\n // still assume that the parsed data is theirs.\n // See: crbug/41484172\n const shallowClone = (value: unknown, recurse = true): unknown => {\n if (value instanceof Map) {\n return new Map(value);\n }\n if (value instanceof Set) {\n return new Set(value);\n }\n if (Array.isArray(value)) {\n return [...value];\n }\n if (typeof value === 'object' && value && recurse) {\n const obj: Record<string, unknown> = {};\n for (const [key, v] of Object.entries(value)) {\n obj[key] = shallowClone(v, false);\n }\n return obj;\n }\n return value;\n };\n\n options.logger?.start('parse:clone');\n const parsedTrace = {};\n for (const [name, handler] of Object.entries(this.#traceHandlers)) {\n const data = shallowClone(handler.data());\n Object.assign(parsedTrace, {[name]: data});\n }\n options.logger?.end('parse:clone');\n\n this.dispatchEvent(new TraceParseProgressEvent({percent: ProgressPhase.CLONE}));\n\n this.#data = parsedTrace as Handlers.Types.ParsedTrace;\n }\n\n get parsedTrace(): Handlers.Types.ParsedTrace|null {\n if (this.#status !== Status.FINISHED_PARSING) {\n return null;\n }\n\n return this.#data;\n }\n\n get insights(): Insights.Types.TraceInsightSets|null {\n if (this.#status !== Status.FINISHED_PARSING) {\n return null;\n }\n\n return this.#insights;\n }\n\n #createLanternContext(\n parsedTrace: Handlers.Types.ParsedTrace, traceEvents: readonly Types.Events.Event[], frameId: string,\n navigationId: string, options: Types.Configuration.ParseOptions): Insights.Types.LanternContext|undefined {\n // Check for required handlers.\n if (!parsedTrace.NetworkRequests || !parsedTrace.Workers || !parsedTrace.PageLoadMetrics) {\n return;\n }\n if (!parsedTrace.NetworkRequests.byTime.length) {\n throw new Lantern.Core.LanternError('No network requests found in trace');\n }\n\n const navStarts = parsedTrace.Meta.navigationsByFrameId.get(frameId);\n const navStartIndex = navStarts?.findIndex(n => n.args.data?.navigationId === navigationId);\n if (!navStarts || navStartIndex === undefined || navStartIndex === -1) {\n throw new Lantern.Core.LanternError('Could not find navigation start');\n }\n\n const startTime = navStarts[navStartIndex].ts;\n const endTime = navStartIndex + 1 < navStarts.length ? navStarts[navStartIndex + 1].ts : Number.POSITIVE_INFINITY;\n const boundedTraceEvents = traceEvents.filter(e => e.ts >= startTime && e.ts < endTime);\n\n // Lantern.Types.TraceEvent and Types.Events.Event represent the same\n // object - a trace event - but one is more flexible than the other. It should be safe to cast between them.\n const trace: Lantern.Types.Trace = {\n traceEvents: boundedTraceEvents as unknown as Lantern.Types.TraceEvent[],\n };\n\n const requests = LanternComputationData.createNetworkRequests(trace, parsedTrace, startTime, endTime);\n const graph = LanternComputationData.createGraph(requests, trace, parsedTrace);\n const processedNavigation = LanternComputationData.createProcessedNavigation(parsedTrace, frameId, navigationId);\n\n const networkAnalysis = Lantern.Core.NetworkAnalyzer.analyze(requests);\n if (!networkAnalysis) {\n return;\n }\n\n const lanternSettings: Lantern.Types.Simulation.Settings = {\n // TODO(crbug.com/372674229): if devtools throttling was on, does this network analysis capture\n // that? Do we need to set 'devtools' throttlingMethod?\n networkAnalysis,\n throttlingMethod: 'provided',\n ...options.lanternSettings,\n };\n const simulator: Lantern.Simulation.Simulator<Types.Events.SyntheticNetworkRequest> =\n Lantern.Simulation.Simulator.createSimulator(lanternSettings);\n\n const computeData = {graph, simulator, processedNavigation};\n const fcpResult = Lantern.Metrics.FirstContentfulPaint.compute(computeData);\n const lcpResult = Lantern.Metrics.LargestContentfulPaint.compute(computeData, {fcpResult});\n const interactiveResult = Lantern.Metrics.Interactive.compute(computeData, {lcpResult});\n const tbtResult = Lantern.Metrics.TotalBlockingTime.compute(computeData, {fcpResult, interactiveResult});\n const metrics = {\n firstContentfulPaint: fcpResult,\n interactive: interactiveResult,\n largestContentfulPaint: lcpResult,\n totalBlockingTime: tbtResult,\n };\n\n return {graph, simulator, metrics};\n }\n\n /**\n * Sort the insight models based on the impact of each insight's estimated savings, additionally weighted by the\n * worst metrics according to field data (if present).\n */\n sortInsightSet(\n insights: Insights.Types.TraceInsightSets, insightSet: Insights.Types.InsightSet,\n metadata: Types.File.MetaData|null): void {\n // The initial order of the insights is alphabetical, based on `front_end/models/trace/insights/Models.ts`.\n // The order here provides a baseline that groups insights in a more logical way.\n const baselineOrder: Record<keyof Insights.Types.InsightModels, null> = {\n InteractionToNextPaint: null,\n LCPPhases: null,\n LCPDiscovery: null,\n CLSCulprits: null,\n RenderBlocking: null,\n NetworkDependencyTree: null,\n ImageDelivery: null,\n DocumentLatency: null,\n FontDisplay: null,\n Viewport: null,\n DOMSize: null,\n ThirdParties: null,\n DuplicatedJavaScript: null,\n SlowCSSSelector: null,\n ForcedReflow: null,\n UseCache: null,\n };\n\n // Determine the weights for each metric based on field data, utilizing the same scoring curve that Lighthouse uses.\n const weights = Insights.Common.calculateMetricWeightsForSorting(insightSet, metadata);\n\n // Normalize the estimated savings to a single number, weighted by its relative impact\n // to the page experience based on the same scoring curve that Lighthouse uses.\n const observedLcp = Insights.Common.getLCP(insights, insightSet.id)?.value;\n const observedCls = Insights.Common.getCLS(insights, insightSet.id).value;\n\n // INP is special - if users did not interact with the page, we'll have no INP, but we should still\n // be able to prioritize insights based on this metric. When we observe no interaction, instead use\n // a default value for the baseline INP.\n const observedInp = Insights.Common.getINP(insights, insightSet.id)?.value ?? 200;\n\n const observedLcpScore =\n observedLcp !== undefined ? Insights.Common.evaluateLCPMetricScore(observedLcp) : undefined;\n const observedInpScore = Insights.Common.evaluateINPMetricScore(observedInp);\n const observedClsScore = Insights.Common.evaluateCLSMetricScore(observedCls);\n\n const insightToSortingRank = new Map<string, number>();\n for (const [name, model] of Object.entries(insightSet.model)) {\n const lcp = model.metricSavings?.LCP ?? 0;\n const inp = model.metricSavings?.INP ?? 0;\n const cls = model.metricSavings?.CLS ?? 0;\n\n const lcpPostSavings = observedLcp !== undefined ? Math.max(0, observedLcp - lcp) : undefined;\n const inpPostSavings = Math.max(0, observedInp - inp);\n const clsPostSavings = Math.max(0, observedCls - cls);\n\n let score = 0;\n if (weights.lcp && lcp && observedLcpScore !== undefined && lcpPostSavings !== undefined) {\n score += weights.lcp * (Insights.Common.evaluateLCPMetricScore(lcpPostSavings) - observedLcpScore);\n }\n if (weights.inp && inp && observedInpScore !== undefined) {\n score += weights.inp * (Insights.Common.evaluateINPMetricScore(inpPostSavings) - observedInpScore);\n }\n if (weights.cls && cls && observedClsScore !== undefined) {\n score += weights.cls * (Insights.Common.evaluateCLSMetricScore(clsPostSavings) - observedClsScore);\n }\n\n insightToSortingRank.set(name, score);\n }\n\n // Now perform the actual sorting.\n const baselineOrderKeys = Object.keys(baselineOrder);\n const orderedKeys = Object.keys(insightSet.model);\n orderedKeys.sort((a, b) => {\n const a1 = baselineOrderKeys.indexOf(a);\n const b1 = baselineOrderKeys.indexOf(b);\n if (a1 >= 0 && b1 >= 0) {\n return a1 - b1;\n }\n if (a1 >= 0) {\n return -1;\n }\n if (b1 >= 0) {\n return 1;\n }\n return 0;\n });\n orderedKeys.sort((a, b) => (insightToSortingRank.get(b) ?? 0) - (insightToSortingRank.get(a) ?? 0));\n\n const newModel = {} as Insights.Types.InsightModels;\n for (const key of orderedKeys as Array<keyof Insights.Types.InsightModels>) {\n const model = insightSet.model[key];\n // @ts-expect-error Maybe someday typescript will be powerful enough to handle this.\n newModel[key] = model;\n }\n insightSet.model = newModel;\n }\n\n #computeInsightSet(\n insights: Insights.Types.TraceInsightSets, parsedTrace: Handlers.Types.ParsedTrace,\n context: Insights.Types.InsightSetContext, options: Types.Configuration.ParseOptions): void {\n let id, urlString, navigation;\n if (context.navigation) {\n id = context.navigationId;\n urlString =\n parsedTrace.Meta.finalDisplayUrlByNavigationId.get(context.navigationId) ?? parsedTrace.Meta.mainFrameURL;\n navigation = context.navigation;\n } else {\n id = Types.Events.NO_NAVIGATION;\n urlString = parsedTrace.Meta.finalDisplayUrlByNavigationId.get('') ?? parsedTrace.Meta.mainFrameURL;\n }\n\n const model = {} as Insights.Types.InsightSet['model'];\n\n for (const [name, insight] of Object.entries(TraceProcessor.getInsightRunners())) {\n let insightResult;\n try {\n options.logger?.start(`insights:${name}`);\n insightResult = insight.generateInsight(parsedTrace, context);\n insightResult.frameId = context.frameId;\n const navId = context.navigation?.args.data?.navigationId;\n if (navId) {\n insightResult.navigationId = navId;\n }\n } catch (err) {\n insightResult = err;\n } finally {\n options.logger?.end(`insights:${name}`);\n }\n Object.assign(model, {[name]: insightResult});\n }\n\n let url;\n try {\n url = new URL(urlString);\n } catch {\n // We're pretty sure this only happens for our test fixture: missing-url.json.gz. Shouldn't\n // happen for real traces.\n return;\n }\n\n const insightSet: Insights.Types.InsightSet = {\n id,\n url,\n navigation,\n frameId: context.frameId,\n bounds: context.bounds,\n model,\n };\n insights.set(insightSet.id, insightSet);\n this.sortInsightSet(insights, insightSet, options.metadata ?? null);\n }\n\n /**\n * Run all the insights and set the result to `#insights`.\n */\n #computeInsights(\n parsedTrace: Handlers.Types.ParsedTrace, traceEvents: readonly Types.Events.Event[],\n options: Types.Configuration.ParseOptions): void {\n this.#insights = new Map();\n\n const navigations = parsedTrace.Meta.mainFrameNavigations.filter(\n navigation => navigation.args.frame && navigation.args.data?.navigationId);\n\n // Check if there is a meaningful chunk of work happening prior to the first navigation.\n // If so, we run the insights on that initial bounds.\n // Otherwise, there are no navigations and we do a no-navigation insights pass on the entire trace.\n if (navigations.length) {\n const bounds = Helpers.Timing.traceWindowFromMicroSeconds(parsedTrace.Meta.traceBounds.min, navigations[0].ts);\n // When using \"Record and reload\" option, it typically takes ~5ms. So use 50ms to be safe.\n const threshold = Helpers.Timing.milliToMicro(50 as Types.Timing.Milli);\n if (bounds.range > threshold) {\n const context: Insights.Types.InsightSetContext = {\n bounds,\n frameId: parsedTrace.Meta.mainFrameId,\n };\n this.#computeInsightSet(this.#insights, parsedTrace, context, options);\n }\n // If threshold is not met, then the very beginning of the trace is ignored by the insights engine.\n } else {\n const context: Insights.Types.InsightSetContext = {\n bounds: parsedTrace.Meta.traceBounds,\n frameId: parsedTrace.Meta.mainFrameId,\n };\n this.#computeInsightSet(this.#insights, parsedTrace, context, options);\n }\n\n // Now run the insights for each navigation in isolation.\n for (const [i, navigation] of navigations.entries()) {\n // The above filter guarantees these are present.\n const frameId = navigation.args.frame;\n const navigationId = navigation.args.data?.navigationId as string;\n\n // The lantern sub-context is optional on InsightSetContext, so not setting it is OK.\n // This is also a hedge against an error inside Lantern resulting in breaking the entire performance panel.\n // Additionally, many trace fixtures are too old to be processed by Lantern.\n let lantern;\n try {\n options.logger?.start('insights:createLanternContext');\n lantern = this.#createLanternContext(parsedTrace, traceEvents, frameId, navigationId, options);\n } catch (e) {\n // Don't allow an error in constructing the Lantern graphs to break the rest of the trace processor.\n // Log unexpected errors, but suppress anything that occurs from a trace being too old.\n // Otherwise tests using old fixtures become way too noisy.\n const expectedErrors = [\n 'mainDocumentRequest not found',\n 'missing metric scores for main frame',\n 'missing metric: FCP',\n 'missing metric: LCP',\n 'No network requests found in trace',\n 'Trace is too old',\n ];\n if (!(e instanceof Lantern.Core.LanternError)) {\n // If this wasn't a managed LanternError, the stack trace is likely needed for debugging.\n console.error(e);\n } else if (!expectedErrors.some(err => e.message === err)) {\n // To reduce noise from tests, only print errors that are not expected to occur because a trace is\n // too old (for which there is no single check).\n console.error(e);\n }\n } finally {\n options.logger?.end('insights:createLanternContext');\n }\n\n const min = navigation.ts;\n const max = i + 1 < navigations.length ? navigations[i + 1].ts : parsedTrace.Meta.traceBounds.max;\n const bounds = Helpers.Timing.traceWindowFromMicroSeconds(min, max);\n const context: Insights.Types.InsightSetContext = {\n bounds,\n frameId,\n navigation,\n navigationId,\n lantern,\n };\n\n this.#computeInsightSet(this.#insights, parsedTrace, context, options);\n }\n }\n}\n\n/**\n * Some Handlers need data provided by others. Dependencies of a handler handler are\n * declared in the `deps` field.\n * @returns A map from trace event handler name to trace event handler whose entries\n * iterate in such a way that each handler is visited after its dependencies.\n */\nexport function sortHandlers(traceHandlers: Partial<{[key in Handlers.Types.HandlerName]: Handlers.Types.Handler}>):\n Map<Handlers.Types.HandlerName, Handlers.Types.Handler> {\n const sortedMap = new Map<Handlers.Types.HandlerName, Handlers.Types.Handler>();\n const visited = new Set<Handlers.Types.HandlerName>();\n const visitHandler = (handlerName: Handlers.Types.HandlerName): void => {\n if (sortedMap.has(handlerName)) {\n return;\n }\n if (visited.has(handlerName)) {\n let stackPath = '';\n for (const handler of visited) {\n if (stackPath || handler === handlerName) {\n stackPath += `${handler}->`;\n }\n }\n stackPath += handlerName;\n throw new Error(`Found dependency cycle in trace event handlers: ${stackPath}`);\n }\n visited.add(handlerName);\n const handler = traceHandlers[handlerName];\n if (!handler) {\n return;\n }\n const deps = handler.deps?.();\n if (deps) {\n deps.forEach(visitHandler);\n }\n sortedMap.set(handlerName, handler);\n };\n\n for (const handlerName of Object.keys(traceHandlers)) {\n visitHandler(handlerName as Handlers.Types.HandlerName);\n }\n return sortedMap;\n}\n"]}
|