chrome-devtools-frontend 1.0.1539972 → 1.0.1541552

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.
Files changed (106) hide show
  1. package/eslint.config.mjs +167 -151
  2. package/front_end/Tests.js +5 -1
  3. package/front_end/core/common/Revealer.ts +5 -0
  4. package/front_end/core/common/Settings.ts +106 -95
  5. package/front_end/core/host/InspectorFrontendHost.ts +10 -10
  6. package/front_end/core/sdk/NetworkManager.ts +16 -11
  7. package/front_end/core/sdk/sdk-meta.ts +0 -35
  8. package/front_end/entrypoints/main/MainImpl.ts +15 -7
  9. package/front_end/entrypoints/shell/shell.ts +1 -0
  10. package/front_end/entrypoints/trace_app/trace_app.ts +1 -0
  11. package/front_end/foundation/README.md +10 -0
  12. package/front_end/foundation/Universe.ts +29 -0
  13. package/front_end/foundation/foundation.ts +7 -0
  14. package/front_end/generated/InspectorBackendCommands.ts +6 -3
  15. package/front_end/generated/SupportedCSSProperties.js +13 -0
  16. package/front_end/generated/protocol.ts +58 -2
  17. package/front_end/models/ai_assistance/BuiltInAi.ts +2 -1
  18. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +44 -34
  19. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +121 -56
  20. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +104 -62
  21. package/front_end/models/ai_assistance/performance/AIQueries.ts +56 -2
  22. package/front_end/{panels/issues → models/issues_manager}/IssueAggregator.ts +83 -65
  23. package/front_end/models/issues_manager/issues_manager.ts +2 -0
  24. package/front_end/models/trace/Processor.ts +5 -4
  25. package/front_end/models/trace/insights/types.ts +1 -1
  26. package/front_end/models/trace/types/TraceEvents.ts +1 -1
  27. package/front_end/models/workspace/IgnoreListManager.ts +41 -47
  28. package/front_end/models/workspace/workspace-meta.ts +40 -0
  29. package/front_end/panels/ai_assistance/components/MarkdownRendererWithCodeBlock.ts +1 -1
  30. package/front_end/panels/ai_assistance/components/PerformanceAgentMarkdownRenderer.ts +1 -1
  31. package/front_end/panels/animation/AnimationTimeline.ts +4 -4
  32. package/front_end/panels/animation/AnimationUI.ts +28 -34
  33. package/front_end/panels/elements/ElementsTreeElement.ts +37 -9
  34. package/front_end/panels/elements/LayoutPane.ts +2 -2
  35. package/front_end/panels/elements/components/AdornerManager.ts +9 -9
  36. package/front_end/panels/elements/layoutPane.css +5 -9
  37. package/front_end/panels/event_listeners/EventListenersView.ts +1 -1
  38. package/front_end/panels/explain/components/ConsoleInsight.ts +498 -449
  39. package/front_end/panels/issues/AffectedResourcesView.ts +3 -4
  40. package/front_end/panels/issues/CorsIssueDetailsView.ts +1 -2
  41. package/front_end/panels/issues/IssueView.ts +1 -1
  42. package/front_end/panels/issues/IssuesPane.ts +12 -15
  43. package/front_end/panels/issues/issues.ts +0 -2
  44. package/front_end/panels/network/NetworkDataGridNode.ts +2 -1
  45. package/front_end/panels/network/RequestConditionsDrawer.ts +149 -46
  46. package/front_end/panels/network/RequestTimingView.ts +13 -8
  47. package/front_end/panels/network/network-meta.ts +11 -0
  48. package/front_end/panels/settings/emulation/components/userAgentClientHintsForm.css +1 -1
  49. package/front_end/panels/sources/DebuggerPlugin.ts +1 -1
  50. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +1 -1
  51. package/front_end/panels/sources/breakpointsView.css +1 -1
  52. package/front_end/panels/sources/sourcesPanel.css +2 -2
  53. package/front_end/panels/timeline/TimelineFlameChartView.ts +3 -3
  54. package/front_end/panels/timeline/TimelinePanel.ts +3 -3
  55. package/front_end/panels/timeline/components/LayoutShiftDetails.ts +16 -10
  56. package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +2 -0
  57. package/front_end/panels/timeline/overlays/components/EntryLabelOverlay.ts +4 -1
  58. package/front_end/third_party/chromium/README.chromium +1 -1
  59. package/front_end/third_party/puppeteer/README.chromium +2 -2
  60. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkManager.d.ts.map +1 -1
  61. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkManager.js +3 -1
  62. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkManager.js.map +1 -1
  63. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +2 -2
  64. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +2 -2
  65. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  66. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  67. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +4 -4
  68. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkManager.d.ts.map +1 -1
  69. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkManager.js +3 -1
  70. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkManager.js.map +1 -1
  71. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +2 -2
  72. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +2 -2
  73. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  74. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  75. package/front_end/third_party/puppeteer/package/package.json +1 -1
  76. package/front_end/third_party/puppeteer/package/src/cdp/NetworkManager.ts +3 -1
  77. package/front_end/third_party/puppeteer/package/src/revisions.ts +2 -2
  78. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  79. package/front_end/ui/components/markdown_view/MarkdownView.ts +6 -6
  80. package/front_end/ui/components/snackbars/Snackbars.docs.ts +46 -0
  81. package/front_end/ui/{components/docs/context_menu/basic.ts → legacy/ContextMenu.docs.ts} +58 -25
  82. package/front_end/ui/legacy/UIUtils.ts +2 -1
  83. package/front_end/ui/legacy/components/inline_editor/BezierEditor.ts +1 -1
  84. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +148 -125
  85. package/front_end/ui/legacy/components/perf_ui/TimelineOverviewPane.ts +3 -3
  86. package/front_end/ui/legacy/components/perf_ui/pieChart.css +1 -1
  87. package/front_end/ui/legacy/components/utils/Linkifier.ts +1 -1
  88. package/front_end/ui/legacy/inspectorCommon.css +3 -2
  89. package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
  90. package/mcp/mcp.ts +16 -0
  91. package/package.json +2 -1
  92. package/front_end/ui/components/docs/context_menu/basic.html +0 -45
  93. package/front_end/ui/components/docs/linkifier/simple-url.html +0 -25
  94. package/front_end/ui/components/docs/linkifier/simple-url.ts +0 -25
  95. package/front_end/ui/components/docs/panel_feedback/basic.html +0 -25
  96. package/front_end/ui/components/docs/panel_feedback/basic.ts +0 -21
  97. package/front_end/ui/components/docs/panel_feedback/button.html +0 -25
  98. package/front_end/ui/components/docs/panel_feedback/button.ts +0 -19
  99. package/front_end/ui/components/docs/panel_introduction_steps/basic.html +0 -25
  100. package/front_end/ui/components/docs/panel_introduction_steps/basic.ts +0 -28
  101. package/front_end/ui/components/docs/perf_piechart/basic-with-legend.html +0 -20
  102. package/front_end/ui/components/docs/perf_piechart/basic-with-legend.ts +0 -20
  103. package/front_end/ui/components/docs/perf_piechart/basic-without-legend.html +0 -20
  104. package/front_end/ui/components/docs/perf_piechart/basic-without-legend.ts +0 -18
  105. package/front_end/ui/components/docs/snackbars/basic.html +0 -17
  106. package/front_end/ui/components/docs/snackbars/basic.ts +0 -50
@@ -1,53 +1,3 @@
1
- Title: PerformanceTraceFormatter formatCriticalRequests
2
- Content:
3
- Critical network requests:
4
-
5
- Network requests data:
6
-
7
-
8
-
9
- allUrls = [0: http://localhost:8000/, 1: https://code.jquery.com/jquery-3.7.1.js, 2: http://localhost:8000/render-blocking-stylesheet.css, 3: http://localhost:8000/render-blocking-script.js]
10
-
11
- 0;s-1803;2 ms;3 ms;576 ms;583 ms;582 ms;0.4 ms;7 ms;200;text/html;VeryHigh;VeryHigh;VeryHigh;f;http/1.0;f;;[];[Content-Length: <redacted>|Date: Fri, 07 Mar 2025 15:02:27 GMT|Content-type: text/html|Last-Modified: Fri, 07 Mar 2025 14:58:55 GMT|Server: SimpleHTTP/0.6 Python/3.9.6]
12
- 1;s-1920;581 ms;585 ms;1,943 ms;1,944 ms;1,363 ms;776 ms;1 ms;200;application/javascript;High;High;High;t;h2;f;0;[];[content-encoding: gzip|etag: <redacted>|age: 3975412|x-cache: <redacted>|date: Fri, 07 Mar 2025 15:02:28 GMT|content-type: application/javascript; charset=utf-8|vary: Accept-Encoding|x-cache-hits: <redacted>|last-modified: Fri, 18 Oct 1991 12:00:00 GMT|x-served-by: <redacted>|cache-control: public, max-age=31536000, stale-while-revalidate=604800|x-timer: <redacted>|via: 1.1 varnish, 1.1 varnish|accept-ranges: bytes|access-control-allow-origin: *|content-length: <redacted>|server: nginx]
13
- 2;s-1924;582 ms;583 ms;1,193 ms;1,193 ms;612 ms;0.2 ms;0.2 ms;200;text/css;VeryHigh;VeryHigh;VeryHigh;t;http/1.0;f;0;[];[Content-Length: <redacted>|Date: Fri, 07 Mar 2025 15:02:28 GMT|Content-type: text/css|Last-Modified: Fri, 07 Mar 2025 14:58:07 GMT|Server: SimpleHTTP/0.6 Python/3.9.6]
14
- 3;s-1922;582 ms;583 ms;1,177 ms;1,178 ms;596 ms;0.4 ms;1 ms;200;text/javascript;High;High;High;t;http/1.0;f;0;[];[Content-Length: <redacted>|Date: Fri, 07 Mar 2025 15:02:28 GMT|Content-type: text/javascript|Last-Modified: Fri, 07 Mar 2025 15:00:28 GMT|Server: SimpleHTTP/0.6 Python/3.9.6]
15
- === end content
16
-
17
- Title: PerformanceTraceFormatter formatLongestTasks
18
- Content:
19
- Longest 3 tasks:
20
- - total time: 11 ms, event: (eventKey: r-62, ts: 2297273193336)
21
- - total time: 3 ms, event: (eventKey: r-723, ts: 2297274436743)
22
- - total time: 2 ms, event: (eventKey: r-631, ts: 2297274234151)
23
- === end content
24
-
25
- Title: PerformanceTraceFormatter formatMainThreadBottomUpSummary
26
- Content:
27
- This is the bottom-up summary for the entire trace. Only the top 10 activities (sorted by self time) are shown. An activity is all the aggregated time spent on the same type of work. For example, it can be all the time spent in a specific JavaScript function, or all the time spent in a specific browser rendering stage (like layout, v8 compile, parsing html). "Self time" represents the aggregated time spent directly in an activity, across all occurrences. "Total time" represents the aggregated time spent in an activity or any of its children.
28
-
29
- - self: 186 ms, total: 193 ms, source: Compile code
30
- - self: 98 ms, total: 993 ms, source: Task
31
- - self: 56 ms, total: 70 ms, source: Compile script
32
- - self: 52 ms, total: 64 ms, source: setTimeout
33
- - self: 38 ms, total: 40 ms, source: aC (url: https://s.yimg.com/aaq/f10d509c/d1irmdsmbztlvx.js, line: 0, column: 19068)
34
- - self: 35 ms, total: 35 ms, source: Recalculate style (url: https://news.yahoo.com/, line: 57, column: 187957)
35
- - self: 34 ms, total: 34 ms, source: Layout (url: https://news.yahoo.com/, line: 57, column: 187957)
36
- - self: 31 ms, total: 34 ms, source: clearTimeout
37
- - self: 30 ms, total: 53 ms, source: Parse HTML
38
- - self: 26 ms, total: 259 ms, source: Function call
39
- === end content
40
-
41
- Title: PerformanceTraceFormatter formatThirdPartySummary
42
- Content:
43
- Third party summary:
44
- - name: Google/Doubleclick Ads, main thread time: 53 ms, network transfer size: 258.6 kB
45
- - name: Taboola, main thread time: 43 ms, network transfer size: 393.6 kB
46
- - name: Google Tag Manager, main thread time: 19 ms, network transfer size: 123.8 kB
47
- - name: AOL / Oath / Verizon Media, main thread time: 5 ms, network transfer size: 42.3 kB
48
- - name: ay.delivery, main thread time: 4 ms, network transfer size: 123 kB
49
- === end content
50
-
51
1
  Title: PerformanceTraceFormatter formatMainThreadTrackSummary
52
2
  Content:
53
3
  # Top-down main thread summary
@@ -512,7 +462,7 @@ Network throttling: none
512
462
 
513
463
  The following is a list of insight sets. An insight set covers a specific part of the trace, split by navigations. The insights within each insight set are specific to that part of the trace. Be sure to consider the insight set id and bounds when calling functions. If no specific insight set or navigation is mentioned, assume the user is referring to the first one.
514
464
 
515
- ## insight set id: 86EB5E5C401E3E17ECE461B3FC627867
465
+ ## insight set id: NAVIGATION_0
516
466
 
517
467
  URL: https://web.dev/cls/
518
468
  Bounds: {min: 1020034834921, max: 1020036087961}
@@ -554,7 +504,7 @@ Network throttling: none
554
504
 
555
505
  The following is a list of insight sets. An insight set covers a specific part of the trace, split by navigations. The insights within each insight set are specific to that part of the trace. Be sure to consider the insight set id and bounds when calling functions. If no specific insight set or navigation is mentioned, assume the user is referring to the first one.
556
506
 
557
- ## insight set id: 513BDA1E9EC088611B53BFF7A859B5DD
507
+ ## insight set id: NAVIGATION_0
558
508
 
559
509
  URL: https://news.yahoo.com/
560
510
  Bounds: {min: 157423488682, max: 157427277166}
@@ -625,7 +575,7 @@ Network throttling: Fast 3G
625
575
 
626
576
  The following is a list of insight sets. An insight set covers a specific part of the trace, split by navigations. The insights within each insight set are specific to that part of the trace. Be sure to consider the insight set id and bounds when calling functions. If no specific insight set or navigation is mentioned, assume the user is referring to the first one.
627
577
 
628
- ## insight set id: 8671F33ECE0C8DBAEFBC2F9A2D1D6107
578
+ ## insight set id: NAVIGATION_0
629
579
 
630
580
  URL: http://localhost:8080/render-blocking
631
581
  Bounds: {min: 171607579779, max: 171613750571}
@@ -649,7 +599,7 @@ Available insights:
649
599
  example question: Show me the most impactful render blocking requests that I should focus on
650
600
  example question: How can I reduce the number of render blocking requests?
651
601
 
652
- ## insight set id: 1AE2016BBCC48AA090FDAE2CBBA01900
602
+ ## insight set id: NAVIGATION_1
653
603
 
654
604
  URL: http://localhost:8080/render-blocking
655
605
  Bounds: {min: 171613750571, max: 171616667355}
@@ -685,7 +635,7 @@ Network throttling: No throttling
685
635
 
686
636
  The following is a list of insight sets. An insight set covers a specific part of the trace, split by navigations. The insights within each insight set are specific to that part of the trace. Be sure to consider the insight set id and bounds when calling functions. If no specific insight set or navigation is mentioned, assume the user is referring to the first one.
687
637
 
688
- ## insight set id: 9094E106056B51D078CE44F3356FE194
638
+ ## insight set id: NAVIGATION_0
689
639
 
690
640
  URL: http://localhost/image-delivery-cases.html
691
641
  Bounds: {min: 59728649746, max: 59734400108}
@@ -758,7 +708,7 @@ Network throttling: No throttling
758
708
 
759
709
  The following is a list of insight sets. An insight set covers a specific part of the trace, split by navigations. The insights within each insight set are specific to that part of the trace. Be sure to consider the insight set id and bounds when calling functions. If no specific insight set or navigation is mentioned, assume the user is referring to the first one.
760
710
 
761
- ## insight set id: 9094E106056B51D078CE44F3356FE194
711
+ ## insight set id: NAVIGATION_0
762
712
 
763
713
  URL: http://localhost/image-delivery-cases.html
764
714
  Bounds: {min: 59728649746, max: 59734400108}
@@ -859,6 +809,121 @@ Available insights:
859
809
  example question: Which third parties are having the largest impact on my page performance?
860
810
  === end content
861
811
 
812
+ Title: PerformanceTraceFormatter formatCriticalRequests render-blocking-requests.json.gz
813
+ Content:
814
+ # Critical network requests
815
+
816
+
817
+ Network requests data:
818
+
819
+
820
+
821
+ allUrls = [0: http://localhost:8000/, 1: https://code.jquery.com/jquery-3.7.1.js, 2: http://localhost:8000/render-blocking-stylesheet.css, 3: http://localhost:8000/render-blocking-script.js]
822
+
823
+ 0;s-1803;2 ms;3 ms;576 ms;583 ms;582 ms;0.4 ms;7 ms;200;text/html;VeryHigh;VeryHigh;VeryHigh;f;http/1.0;f;;[];[Content-Length: <redacted>|Date: Fri, 07 Mar 2025 15:02:27 GMT|Content-type: text/html|Last-Modified: Fri, 07 Mar 2025 14:58:55 GMT|Server: SimpleHTTP/0.6 Python/3.9.6]
824
+ 1;s-1920;581 ms;585 ms;1,943 ms;1,944 ms;1,363 ms;776 ms;1 ms;200;application/javascript;High;High;High;t;h2;f;0;[];[content-encoding: gzip|etag: <redacted>|age: 3975412|x-cache: <redacted>|date: Fri, 07 Mar 2025 15:02:28 GMT|content-type: application/javascript; charset=utf-8|vary: Accept-Encoding|x-cache-hits: <redacted>|last-modified: Fri, 18 Oct 1991 12:00:00 GMT|x-served-by: <redacted>|cache-control: public, max-age=31536000, stale-while-revalidate=604800|x-timer: <redacted>|via: 1.1 varnish, 1.1 varnish|accept-ranges: bytes|access-control-allow-origin: *|content-length: <redacted>|server: nginx]
825
+ 2;s-1924;582 ms;583 ms;1,193 ms;1,193 ms;612 ms;0.2 ms;0.2 ms;200;text/css;VeryHigh;VeryHigh;VeryHigh;t;http/1.0;f;0;[];[Content-Length: <redacted>|Date: Fri, 07 Mar 2025 15:02:28 GMT|Content-type: text/css|Last-Modified: Fri, 07 Mar 2025 14:58:07 GMT|Server: SimpleHTTP/0.6 Python/3.9.6]
826
+ 3;s-1922;582 ms;583 ms;1,177 ms;1,178 ms;596 ms;0.4 ms;1 ms;200;text/javascript;High;High;High;t;http/1.0;f;0;[];[Content-Length: <redacted>|Date: Fri, 07 Mar 2025 15:02:28 GMT|Content-type: text/javascript|Last-Modified: Fri, 07 Mar 2025 15:00:28 GMT|Server: SimpleHTTP/0.6 Python/3.9.6]
827
+ === end content
828
+
829
+ Title: PerformanceTraceFormatter formatCriticalRequests multiple-navigations-render-blocking.json.gz
830
+ Content:
831
+ # Critical network requests
832
+
833
+ ## insight set id: NAVIGATION_0
834
+
835
+ none
836
+
837
+ ## insight set id: NAVIGATION_1
838
+
839
+ none
840
+ === end content
841
+
842
+ Title: PerformanceTraceFormatter formatLongestTasks long-task-from-worker-thread.json.gz
843
+ Content:
844
+ # Longest tasks
845
+
846
+ - total time: 11 ms, event: (eventKey: r-62, ts: 2297273193336)
847
+ - total time: 3 ms, event: (eventKey: r-723, ts: 2297274436743)
848
+ - total time: 2 ms, event: (eventKey: r-631, ts: 2297274234151)
849
+ === end content
850
+
851
+ Title: PerformanceTraceFormatter formatLongestTasks multiple-navigations-render-blocking.json.gz
852
+ Content:
853
+ # Longest tasks
854
+
855
+ ## insight set id: NAVIGATION_0
856
+
857
+ - total time: 8 ms, event: (eventKey: r-6426, ts: 171608877757)
858
+ - total time: 7 ms, event: (eventKey: r-3609, ts: 171608164318)
859
+ - total time: 2 ms, event: (eventKey: r-6501, ts: 171608885367)
860
+
861
+ ## insight set id: NAVIGATION_1
862
+
863
+ - total time: 3 ms, event: (eventKey: r-12777, ts: 171614328028)
864
+ - total time: 0.7 ms, event: (eventKey: r-15391, ts: 171615043591)
865
+ - total time: 0.7 ms, event: (eventKey: r-15448, ts: 171615044306)
866
+ === end content
867
+
868
+ Title: PerformanceTraceFormatter formatMainThreadBottomUpSummary yahoo-news.json.gz
869
+ Content:
870
+ # Main thread bottom-up summary
871
+
872
+ This is the bottom-up summary for the entire trace. Only the top 10 activities (sorted by self time) are shown. An activity is all the aggregated time spent on the same type of work. For example, it can be all the time spent in a specific JavaScript function, or all the time spent in a specific browser rendering stage (like layout, v8 compile, parsing html). "Self time" represents the aggregated time spent directly in an activity, across all occurrences. "Total time" represents the aggregated time spent in an activity or any of its children.
873
+
874
+ - self: 186 ms, total: 193 ms, source: Compile code
875
+ - self: 98 ms, total: 990 ms, source: Task
876
+ - self: 56 ms, total: 70 ms, source: Compile script
877
+ - self: 52 ms, total: 64 ms, source: setTimeout
878
+ - self: 38 ms, total: 40 ms, source: aC (url: https://s.yimg.com/aaq/f10d509c/d1irmdsmbztlvx.js, line: 0, column: 19068)
879
+ - self: 35 ms, total: 35 ms, source: Recalculate style (url: https://news.yahoo.com/, line: 57, column: 187957)
880
+ - self: 34 ms, total: 34 ms, source: Layout (url: https://news.yahoo.com/, line: 57, column: 187957)
881
+ - self: 31 ms, total: 34 ms, source: clearTimeout
882
+ - self: 30 ms, total: 53 ms, source: Parse HTML
883
+ - self: 26 ms, total: 259 ms, source: Function call
884
+ === end content
885
+
886
+ Title: PerformanceTraceFormatter formatMainThreadBottomUpSummary multiple-navigations-render-blocking.json.gz
887
+ Content:
888
+ # Main thread bottom-up summary
889
+
890
+ This is the bottom-up summary for the entire trace. Only the top 10 activities (sorted by self time) are shown. An activity is all the aggregated time spent on the same type of work. For example, it can be all the time spent in a specific JavaScript function, or all the time spent in a specific browser rendering stage (like layout, v8 compile, parsing html). "Self time" represents the aggregated time spent directly in an activity, across all occurrences. "Total time" represents the aggregated time spent in an activity or any of its children.
891
+
892
+ ## insight set id: NAVIGATION_0
893
+
894
+ - self: 10 ms, total: 21 ms, source: Task
895
+ - self: 7 ms, total: 7 ms, source: Layout
896
+ - self: 2 ms, total: 2 ms, source: Profiling overhead
897
+
898
+ ## insight set id: NAVIGATION_1
899
+
900
+ - self: 6 ms, total: 7 ms, source: Task
901
+ === end content
902
+
903
+ Title: PerformanceTraceFormatter formatThirdPartySummary yahoo-news.json.gz
904
+ Content:
905
+ # 3rd party summary
906
+
907
+ - name: Yahoo!, main thread time: 270 ms, network transfer size: 2.4 MB
908
+ - name: Google/Doubleclick Ads, main thread time: 53 ms, network transfer size: 258.6 kB
909
+ - name: Taboola, main thread time: 43 ms, network transfer size: 393.6 kB
910
+ - name: Google Tag Manager, main thread time: 19 ms, network transfer size: 123.8 kB
911
+ - name: AOL / Oath / Verizon Media, main thread time: 5 ms, network transfer size: 42.3 kB
912
+ === end content
913
+
914
+ Title: PerformanceTraceFormatter formatThirdPartySummary multiple-navigations-render-blocking.json.gz
915
+ Content:
916
+ # 3rd party summary
917
+
918
+ ## insight set id: NAVIGATION_0
919
+
920
+ - name: localhost, main thread time: 0.8 ms, network transfer size: 22.9 kB
921
+
922
+ ## insight set id: NAVIGATION_1
923
+
924
+ - name: localhost, main thread time: 0.3 ms, network transfer size: 22.9 kB
925
+ === end content
926
+
862
927
  Title: PerformanceTraceFormatter formatNetworkRequests formats network requests that have redirects
863
928
  Content:
864
929
  ## Network request: http://localhost:3000/redirect3
@@ -17,6 +17,14 @@ export interface NetworkRequestFormatOptions {
17
17
  customTitle?: string;
18
18
  }
19
19
 
20
+ interface FormatFactByInsightSetOptions {
21
+ insights: Trace.Insights.Types.TraceInsightSets|null;
22
+ title: string;
23
+ description?: string;
24
+ empty: string;
25
+ cb: (insightSet: Trace.Insights.Types.InsightSet) => string | null;
26
+ }
27
+
20
28
  export class PerformanceTraceFormatter {
21
29
  #focus: AgentFocus;
22
30
  #parsedTrace: Trace.TraceModel.ParsedTrace;
@@ -214,21 +222,47 @@ export class PerformanceTraceFormatter {
214
222
  return parts.join('\n');
215
223
  }
216
224
 
217
- formatCriticalRequests(): string {
218
- const insightSet = this.#insightSet;
219
- const criticalRequests: Trace.Types.Events.SyntheticNetworkRequest[] = [];
225
+ #formatFactByInsightSet(options: FormatFactByInsightSetOptions): string {
226
+ const {insights, title, description, empty, cb} = options;
227
+ const lines = [`# ${title}\n`];
220
228
 
221
- const walkRequest = (node: Trace.Insights.Models.NetworkDependencyTree.CriticalRequestNode): void => {
222
- criticalRequests.push(node.request);
223
- node.children.forEach(walkRequest);
224
- };
229
+ if (description) {
230
+ lines.push(`${description}\n`);
231
+ }
225
232
 
226
- insightSet?.model.NetworkDependencyTree.rootNodes.forEach(walkRequest);
227
- if (!criticalRequests.length) {
228
- return '';
233
+ if (insights?.size) {
234
+ const multipleInsightSets = insights.size > 1;
235
+ for (const insightSet of insights.values()) {
236
+ if (multipleInsightSets) {
237
+ lines.push(`## insight set id: ${insightSet.id}\n`);
238
+ }
239
+ lines.push((cb(insightSet) ?? empty) + '\n');
240
+ }
241
+ } else {
242
+ lines.push(empty + '\n');
229
243
  }
230
244
 
231
- return 'Critical network requests:\n' + this.formatNetworkRequests(criticalRequests, {verbose: false});
245
+ return lines.join('\n');
246
+ }
247
+
248
+ formatCriticalRequests(): string {
249
+ const parsedTrace = this.#parsedTrace;
250
+ return this.#formatFactByInsightSet({
251
+ insights: parsedTrace.insights,
252
+ title: 'Critical network requests',
253
+ empty: 'none',
254
+ cb: insightSet => {
255
+ const criticalRequests: Trace.Types.Events.SyntheticNetworkRequest[] = [];
256
+
257
+ const walkRequest = (node: Trace.Insights.Models.NetworkDependencyTree.CriticalRequestNode): void => {
258
+ criticalRequests.push(node.request);
259
+ node.children.forEach(walkRequest);
260
+ };
261
+ insightSet.model.NetworkDependencyTree.rootNodes.forEach(walkRequest);
262
+
263
+ return criticalRequests.length ? this.formatNetworkRequests(criticalRequests, {verbose: false}) : null;
264
+ },
265
+ });
232
266
  }
233
267
 
234
268
  #serializeBottomUpRootNode(rootNode: Trace.Extras.TraceTree.BottomUpRootNode, limit: number): string {
@@ -265,27 +299,31 @@ export class PerformanceTraceFormatter {
265
299
  return `- self: ${millis(node.selfTime)}, total: ${millis(node.totalTime)}, source: ${source}`;
266
300
  }
267
301
 
268
- const listText = topNodes.map(node => nodeToText.call(this, node)).join('\n');
269
- const format = `This is the bottom-up summary for the entire trace. Only the top ${
302
+ return topNodes.map(node => nodeToText.call(this, node)).join('\n');
303
+ }
304
+
305
+ #getSerializeBottomUpRootNodeFormat(limit: number): string {
306
+ return `This is the bottom-up summary for the entire trace. Only the top ${
270
307
  limit} activities (sorted by self time) are shown. An activity is all the aggregated time spent on the same type of work. For example, it can be all the time spent in a specific JavaScript function, or all the time spent in a specific browser rendering stage (like layout, v8 compile, parsing html). "Self time" represents the aggregated time spent directly in an activity, across all occurrences. "Total time" represents the aggregated time spent in an activity or any of its children.`;
271
- return `${format}\n\n${listText}`;
272
308
  }
273
309
 
274
310
  formatMainThreadBottomUpSummary(): string {
275
311
  const parsedTrace = this.#parsedTrace;
276
- const insightSet = this.#insightSet;
277
-
278
- const bounds = parsedTrace.data.Meta.traceBounds;
279
- const rootNode = AIQueries.mainThreadActivityBottomUp(
280
- insightSet?.navigation?.args.data?.navigationId,
281
- bounds,
282
- parsedTrace,
283
- );
284
- if (!rootNode) {
285
- return '';
286
- }
287
-
288
- return this.#serializeBottomUpRootNode(rootNode, 10);
312
+ const limit = 10;
313
+ return this.#formatFactByInsightSet({
314
+ insights: parsedTrace.insights,
315
+ title: 'Main thread bottom-up summary',
316
+ description: this.#getSerializeBottomUpRootNodeFormat(limit),
317
+ empty: 'no activity',
318
+ cb: insightSet => {
319
+ const rootNode = AIQueries.mainThreadActivityBottomUpSingleNavigation(
320
+ insightSet.navigation?.args.data?.navigationId,
321
+ insightSet.bounds,
322
+ parsedTrace,
323
+ );
324
+ return rootNode ? this.#serializeBottomUpRootNode(rootNode, limit) : null;
325
+ },
326
+ });
289
327
  }
290
328
 
291
329
  #formatThirdPartyEntitySummaries(summaries: Trace.Extras.ThirdParties.EntitySummary[]): string {
@@ -305,43 +343,40 @@ export class PerformanceTraceFormatter {
305
343
  }
306
344
 
307
345
  formatThirdPartySummary(): string {
308
- const insightSet = this.#insightSet;
309
- if (!insightSet) {
310
- return '';
311
- }
312
-
313
- const thirdParties = insightSet.model.ThirdParties;
314
- let summaries = thirdParties.entitySummaries ?? [];
315
- if (thirdParties.firstPartyEntity) {
316
- summaries = summaries.filter(s => s.entity !== thirdParties?.firstPartyEntity || null);
317
- }
318
-
319
- const listText = this.#formatThirdPartyEntitySummaries(summaries);
320
- if (!listText) {
321
- return '';
322
- }
323
-
324
- return `Third party summary:\n${listText}`;
346
+ const parsedTrace = this.#parsedTrace;
347
+ return this.#formatFactByInsightSet({
348
+ insights: parsedTrace.insights,
349
+ title: '3rd party summary',
350
+ empty: 'no 3rd parties',
351
+ cb: insightSet => {
352
+ const thirdPartySummaries =
353
+ Trace.Extras.ThirdParties.summarizeByThirdParty(parsedTrace.data, insightSet.bounds);
354
+ return thirdPartySummaries.length ? this.#formatThirdPartyEntitySummaries(thirdPartySummaries) : null;
355
+ },
356
+ });
325
357
  }
326
358
 
327
359
  formatLongestTasks(): string {
328
360
  const parsedTrace = this.#parsedTrace;
329
- const insightSet = this.#insightSet;
330
-
331
- const bounds = parsedTrace.data.Meta.traceBounds;
332
- const longestTaskTrees =
333
- AIQueries.longestTasks(insightSet?.navigation?.args.data?.navigationId, bounds, parsedTrace, 3);
334
- if (!longestTaskTrees || longestTaskTrees.length === 0) {
335
- return 'Longest tasks: none';
336
- }
361
+ return this.#formatFactByInsightSet({
362
+ insights: parsedTrace.insights,
363
+ title: 'Longest tasks',
364
+ empty: 'none',
365
+ cb: insightSet => {
366
+ const longestTaskTrees =
367
+ AIQueries.longestTasks(insightSet.navigation?.args.data?.navigationId, insightSet.bounds, parsedTrace, 3);
368
+ if (!longestTaskTrees?.length) {
369
+ return null;
370
+ }
337
371
 
338
- const listText = longestTaskTrees
339
- .map(tree => {
340
- const time = millis(tree.rootNode.totalTime);
341
- return `- total time: ${time}, event: ${this.serializeEvent(tree.rootNode.event)}`;
342
- })
343
- .join('\n');
344
- return `Longest ${longestTaskTrees.length} tasks:\n${listText}`;
372
+ return longestTaskTrees
373
+ .map(tree => {
374
+ const time = millis(tree.rootNode.totalTime);
375
+ return `- total time: ${time}, event: ${this.serializeEvent(tree.rootNode.event)}`;
376
+ })
377
+ .join('\n');
378
+ },
379
+ });
345
380
  }
346
381
 
347
382
  #serializeRelatedInsightsForEvents(events: Trace.Types.Events.Event[]): string {
@@ -386,10 +421,16 @@ export class PerformanceTraceFormatter {
386
421
  }
387
422
 
388
423
  formatMainThreadTrackSummary(bounds: Trace.Types.Timing.TraceWindowMicro): string {
424
+ if (!this.#parsedTrace.insights) {
425
+ return 'No main thread activity found';
426
+ }
427
+
389
428
  const results = [];
390
429
 
430
+ const insightSet = this.#parsedTrace.insights?.values().find(
431
+ insightSet => Trace.Helpers.Timing.boundsIncludeTimeRange({bounds, timeRange: insightSet.bounds}));
391
432
  const topDownTree = AIQueries.mainThreadActivityTopDown(
392
- this.#insightSet?.navigation?.args.data?.navigationId,
433
+ insightSet?.navigation?.args.data?.navigationId,
393
434
  bounds,
394
435
  this.#parsedTrace,
395
436
  );
@@ -399,13 +440,14 @@ export class PerformanceTraceFormatter {
399
440
  }
400
441
 
401
442
  const bottomUpRootNode = AIQueries.mainThreadActivityBottomUp(
402
- this.#insightSet?.navigation?.args.data?.navigationId,
403
443
  bounds,
404
444
  this.#parsedTrace,
405
445
  );
406
446
  if (bottomUpRootNode) {
407
447
  results.push('# Bottom-up main thread summary');
408
- results.push(this.#serializeBottomUpRootNode(bottomUpRootNode, 20));
448
+ const limit = 20;
449
+ results.push(this.#getSerializeBottomUpRootNodeFormat(limit));
450
+ results.push(this.#serializeBottomUpRootNode(bottomUpRootNode, limit));
409
451
  }
410
452
 
411
453
  const thirdPartySummaries = Trace.Extras.ThirdParties.summarizeByThirdParty(this.#parsedTrace.data, bounds);
@@ -35,6 +35,10 @@ export class AIQueries {
35
35
 
36
36
  const threads = Trace.Handlers.Threads.threadsInTrace(parsedTrace.data);
37
37
  const thread = threads.find(thread => {
38
+ if (!thread.processIsOnMainFrame) {
39
+ return false;
40
+ }
41
+
38
42
  if (mainThreadPID && mainThreadTID) {
39
43
  return thread.pid === mainThreadPID && thread.tid === mainThreadTID;
40
44
  }
@@ -45,9 +49,9 @@ export class AIQueries {
45
49
  }
46
50
 
47
51
  /**
48
- * Returns bottom up activity for the given range.
52
+ * Returns bottom up activity for the given range (within a single navigation / thread).
49
53
  */
50
- static mainThreadActivityBottomUp(
54
+ static mainThreadActivityBottomUpSingleNavigation(
51
55
  navigationId: string|undefined, bounds: Trace.Types.Timing.TraceWindowMicro,
52
56
  parsedTrace: Trace.TraceModel.ParsedTrace): Trace.Extras.TraceTree.BottomUpRootNode|null {
53
57
  const thread = this.findMainThread(navigationId, parsedTrace);
@@ -76,6 +80,56 @@ export class AIQueries {
76
80
  });
77
81
  }
78
82
 
83
+ /**
84
+ * Returns bottom up activity for the given range (no matter the navigation / thread).
85
+ */
86
+ static mainThreadActivityBottomUp(
87
+ bounds: Trace.Types.Timing.TraceWindowMicro,
88
+ parsedTrace: Trace.TraceModel.ParsedTrace): Trace.Extras.TraceTree.BottomUpRootNode|null {
89
+ const threads: Trace.Handlers.Threads.ThreadData[] = [];
90
+ if (parsedTrace.insights) {
91
+ for (const insightSet of parsedTrace.insights?.values()) {
92
+ const thread = this.findMainThread(insightSet.navigation?.args.data?.navigationId, parsedTrace);
93
+ if (thread) {
94
+ threads.push(thread);
95
+ }
96
+ }
97
+ } else {
98
+ const navigationId = parsedTrace.data.Meta.mainFrameNavigations[0].args.data?.navigationId;
99
+ const thread = this.findMainThread(navigationId, parsedTrace);
100
+ if (thread) {
101
+ threads.push(thread);
102
+ }
103
+ }
104
+
105
+ if (threads.length === 0) {
106
+ return null;
107
+ }
108
+
109
+ const threadEvents =
110
+ [...new Set(threads)].map(thread => AICallTree.findEventsForThread({thread, parsedTrace, bounds}) ?? []);
111
+ const events = threadEvents.flat();
112
+
113
+ if (events.length === 0) {
114
+ return null;
115
+ }
116
+
117
+ // Use the same filtering as front_end/panels/timeline/TimelineTreeView.ts.
118
+ const visibleEvents = Trace.Helpers.Trace.VISIBLE_TRACE_EVENT_TYPES.values().toArray();
119
+ const filter = new Trace.Extras.TraceFilter.VisibleEventsFilter(
120
+ visibleEvents.concat([Trace.Types.Events.Name.SYNTHETIC_NETWORK_REQUEST]));
121
+
122
+ // The bottom up root node handles all the "in Tracebounds" checks we need for the insight.
123
+ const startTime = Trace.Helpers.Timing.microToMilli(bounds.min);
124
+ const endTime = Trace.Helpers.Timing.microToMilli(bounds.max);
125
+ return new Trace.Extras.TraceTree.BottomUpRootNode(events, {
126
+ textFilter: new Trace.Extras.TraceFilter.ExclusiveNameFilter([]),
127
+ filters: [filter],
128
+ startTime,
129
+ endTime,
130
+ });
131
+ }
132
+
79
133
  /**
80
134
  * Returns an AI Call Tree representing the activity on the main thread for
81
135
  * the relevant time range of the given insight.