1// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5module page_load_metrics.mojom;
6
7import "ui/gfx/geometry/mojom/geometry.mojom";
8import "mojo/public/mojom/base/shared_memory.mojom";
9import "mojo/public/mojom/base/time.mojom";
10import "third_party/blink/public/mojom/web_feature/web_feature.mojom";
11import
12  "third_party/blink/public/mojom/mobile_metrics/mobile_friendliness.mojom";
13import "third_party/blink/public/mojom/use_counter/css_property_id.mojom";
14import "url/mojom/origin.mojom";
15
16// TimeDeltas below relative to navigation start.
17struct DocumentTiming {
18  // Time immediately before the DOMContentLoaded event is fired.
19  mojo_base.mojom.TimeDelta? dom_content_loaded_event_start;
20
21  // Time immediately before the load event is fired.
22  mojo_base.mojom.TimeDelta? load_event_start;
23};
24
25struct LargestContentfulPaintTiming {
26  // Time when the page's largest image is painted.
27  mojo_base.mojom.TimeDelta? largest_image_paint;
28
29  // Size of the largest image of the largest image paint, by
30  // Size = Height * Width. Removed images are excluded.
31  uint64 largest_image_paint_size;
32
33  // Time when the page's largest text is painted.
34  mojo_base.mojom.TimeDelta? largest_text_paint;
35
36  // Size of the largest text of the largest text paint, by
37  // Size = Height * Width. Removed text is excluded.
38  uint64 largest_text_paint_size;
39};
40
41// TimeDeltas below relative to navigation start.
42struct PaintTiming {
43  // Time when the first paint is performed.
44  mojo_base.mojom.TimeDelta? first_paint;
45
46  // Time when the first image is painted.
47  mojo_base.mojom.TimeDelta? first_image_paint;
48
49  // Time when the first contentful thing (image, text, etc.) is painted.
50  mojo_base.mojom.TimeDelta? first_contentful_paint;
51
52  // (Experimental) Time when the page's primary content is painted.
53  mojo_base.mojom.TimeDelta? first_meaningful_paint;
54
55  // Largest contentful paint, which includes removed content.
56  LargestContentfulPaintTiming largest_contentful_paint;
57
58  // (Experimental) largest contentful paint excluding removed content.
59  LargestContentfulPaintTiming experimental_largest_contentful_paint;
60
61  // (Experimental) Time when the frame is first eligible to be painted, i.e.
62  // is first not render-throttled. Will be null if frame is throttled,
63  // unless there has already been a |first_paint|.
64  mojo_base.mojom.TimeDelta? first_eligible_to_paint;
65
66  // (Experimental) Time when first input or scroll is received, causing the
67  // largest contentful paint algorithm to stop.
68  mojo_base.mojom.TimeDelta? first_input_or_scroll_notified_timestamp;
69
70  // Time when the first paint happens after a portal activation.
71  mojo_base.mojom.TimeTicks? portal_activated_paint;
72};
73
74// TimeDeltas below represent durations of time during the page load.
75struct ParseTiming {
76  // Time that the document's parser started and stopped parsing main resource
77  // content.
78  mojo_base.mojom.TimeDelta? parse_start;
79  mojo_base.mojom.TimeDelta? parse_stop;
80
81  // Sum of times when the parser is blocked waiting on the load of a script.
82  // This duration takes place between parser_start and parser_stop, and thus
83  // must be less than or equal to parser_stop - parser_start. Note that this
84  // value may be updated multiple times during the period between parse_start
85  // and parse_stop.
86  mojo_base.mojom.TimeDelta? parse_blocked_on_script_load_duration;
87
88  // Sum of times when the parser is blocked waiting on the load of a script
89  // that was inserted from document.write. This duration must be less than or
90  // equal to parse_blocked_on_script_load_duration. Note that this value may be
91  // updated multiple times during the period between parse_start and
92  // parse_stop. Note that some uncommon cases where scripts are loaded via
93  // document.write are not currently covered by this field. See crbug/600711
94  // for details.
95  mojo_base.mojom.TimeDelta? parse_blocked_on_script_load_from_document_write_duration;
96
97  // Sum of times when the parser is executing a script.  This duration takes
98  // place between parser_start and parser_stop, and thus must be less than or
99  // equal to parser_stop - parser_start. Note that this value may be updated
100  // multiple times during the period between parse_start and parse_stop.
101  mojo_base.mojom.TimeDelta? parse_blocked_on_script_execution_duration;
102
103  // Sum of times when the parser is executing a script that was inserted from
104  // document.write. This duration must be less than or equal to
105  // parse_blocked_on_script_load_duration. Note that this value may be updated
106  // multiple times during the period between parse_start and parse_stop. Note
107  // that some uncommon cases where scripts are loaded via document.write are
108  // not currently covered by this field. See crbug/600711 for details.
109  mojo_base.mojom.TimeDelta? parse_blocked_on_script_execution_from_document_write_duration;
110};
111
112struct InteractiveTiming {
113  // Queueing Time of the first click, tap, key press, cancellable touchstart,
114  // or pointer down followed by a pointer up.
115  mojo_base.mojom.TimeDelta? first_input_delay;
116
117  // The timestamp of the event whose delay is reported by GetFirstInputDelay().
118  mojo_base.mojom.TimeDelta? first_input_timestamp;
119
120  // Queueing Time of the meaningful input event with longest delay. Meaningful
121  // input events are click, tap, key press, cancellable touchstart, or pointer
122  // down followed by a pointer up.
123  mojo_base.mojom.TimeDelta? longest_input_delay;
124
125  // The timestamp of the event whose delay is reported as longest_input_delay.
126  mojo_base.mojom.TimeDelta? longest_input_timestamp;
127
128  // The latency between user input and display update for the first scroll after
129  // a navigation.
130  mojo_base.mojom.TimeDelta? first_scroll_delay;
131
132  // The timestamp of the user's first scroll after a navigation.
133  mojo_base.mojom.TimeDelta? first_scroll_timestamp;
134
135  // The duration of event handlers processing the first input event.
136  mojo_base.mojom.TimeDelta? first_input_processing_time;
137};
138
139// PageLoadTiming contains timing metrics associated with a page load. Many of
140// the metrics here are based on the Navigation Timing spec:
141// http://www.w3.org/TR/navigation-timing/.
142struct PageLoadTiming {
143  // Time that the navigation for the associated page was initiated. Note that
144  // this field is only used for internal tracking purposes and should not be
145  // used by PageLoadMetricsObservers. This field will likely be removed in the
146  // future.
147  mojo_base.mojom.Time navigation_start;
148
149  // Time relative to navigation_start that the first byte of the response is
150  // received.
151  mojo_base.mojom.TimeDelta? response_start;
152  DocumentTiming document_timing;
153  InteractiveTiming interactive_timing;
154  PaintTiming paint_timing;
155  ParseTiming parse_timing;
156
157  // List of back-forward cache timings, one for each time a page was restored
158  // from the cache.
159  array<BackForwardCacheTiming> back_forward_cache_timings;
160
161  // Time between user input and navigation start. This is set for navigations
162  // where the input start timing is known; currently when the navigation is
163  // initiated by a link click in the renderer, or from the desktop omnibox.
164  mojo_base.mojom.TimeDelta? input_to_navigation_start;
165
166  // If you add additional members, also be sure to update page_load_timing.h.
167};
168
169// FrameIntersectionUpdate contains a frame's intersections with other elements
170// in a page load.
171struct FrameIntersectionUpdate {
172  // The frame's current intersection rect with the main frame in the main
173  // frame's coordinate system.. The intersection rect is
174  // an empty rect when there is no intersection with the main frame and
175  // returns the document size of the root document for the main frame. This
176  // is only set the first time an intersection changes and is null otherwise.
177  gfx.mojom.Rect? main_frame_intersection_rect;
178};
179
180struct FrameMetadata {
181  // These are packed blink::LoadingBehaviorFlag enums.
182  int32 behavior_flags = 0;
183
184  // The frame's intersection with page elements.
185  FrameIntersectionUpdate? intersection_update;
186};
187
188// PageLoadFeatures contains a list of features newly observed by use counter.
189// In a given page load, no PageLoadFeatures sent will contain previously seen
190// values.
191struct PageLoadFeatures {
192  // These features are defined as blink::mojom::WebFeature enums.
193  array<blink.mojom.WebFeature> features;
194  // CSS properties are defined as blink::mojom::CSSSampleId enums.
195  array<blink.mojom.CSSSampleId> css_properties;
196  array<blink.mojom.CSSSampleId> animated_css_properties;
197};
198
199// Enumeration of distinct cache types.
200enum CacheType {
201  kNotCached, // Resource came from network.
202  kHttp, // Resource was serviced by the http cache.
203  kMemory, // Resource was serviced by the Renderer's MemoryCache.
204};
205
206struct ResourceDataUpdate {
207  // The id for the resource request.
208  int32 request_id = 0;
209
210  // Network bytes received for the resource since the last timing update
211  // from renderer to browser.
212  int64 delta_bytes = 0;
213
214  // Total network bytes received for the resource across timing updates. This
215  // is the aggregate of the |delta_bytes| from each timing update.
216  int64 received_data_length = 0;
217
218  // The length of the response body for the resource before removing any
219  // content encodings. Only set for complete resources.
220  int64 encoded_body_length = 0;
221
222  // The length of the response body in bytes for the resource after decoding.
223  // Only set for complete resources.
224  int64 decoded_body_length = 0;
225
226  // Whether this resource load has completed.
227  bool is_complete;
228
229  // Compression ratio estimated from the response headers if data saver was
230  // used.
231  double data_reduction_proxy_compression_ratio_estimate;
232
233  // Whether this resource was tagged as an ad in the renderer. This flag can
234  // be set to true at any point during a resource load. A more recent
235  // ResourceDataUpdate can have a different flag than the previous update.
236  // Once this is set to true, it will be true for all future updates.
237  bool reported_as_ad_resource;
238
239  // Whether this resource was loaded in the top-level frame.
240  bool is_main_frame_resource;
241
242  // Which cache this resource originated from, if any.
243  CacheType cache_type;
244
245  // Whether this resource is the primary resource for a frame.
246  bool is_primary_frame_resource;
247
248  // Mime type for the resource found in the network response header.
249  string mime_type;
250
251  // Whether the scheme of this resource indicates a secure connection.
252  bool is_secure_scheme;
253
254  // Whether this resource was fetched via proxy.
255  bool proxy_used;
256
257  // The origin of this resource.
258  url.mojom.Origin origin;
259
260  // Whether this resource completed loading, either by network or cache, before
261  // FCP in the frame it belongs to. This flag can be set to true at any point
262  // during a resource load. A more recent ResourceDataUpdate can have a
263  // different flag than the previous update. Once this is set to true, it will
264  // be true for all future updates.
265  bool completed_before_fcp;
266};
267
268// Timestamp and layout shift score of a layout shift.
269struct LayoutShift {
270  mojo_base.mojom.TimeTicks layout_shift_time;
271  double layout_shift_score;
272};
273
274// Metrics about how a RenderFrame rendered since the last UpdateTiming call.
275struct FrameRenderDataUpdate {
276  // How much visible elements in the frame shifted (https://bit.ly/3fQz29y) since
277  // the last timing update.
278  float layout_shift_delta;
279
280  // How much visible elements in the frame shifted (https://bit.ly/3fQz29y),
281  // before a user input or document scroll, since the last timing update.
282  float layout_shift_delta_before_input_or_scroll;
283
284  // How many LayoutBlock instances were created.
285  uint32 all_layout_block_count_delta;
286
287  // How many LayoutNG-based LayoutBlock instances were created.
288  uint32 ng_layout_block_count_delta;
289
290  // How many times LayoutObject::UpdateLayout() is called.
291  uint32 all_layout_call_count_delta;
292
293  // How many times LayoutNG-based LayoutObject::UpdateLayout() is called.
294  uint32 ng_layout_call_count_delta;
295
296  // New layout shifts with timestamps.
297  array<LayoutShift> new_layout_shifts;
298};
299
300// Metrics about the time spent in tasks (cpu time) by a frame.
301struct CpuTiming {
302  // Time spent in tasks measured in wall time.
303  mojo_base.mojom.TimeDelta task_time;
304};
305
306// Metrics about the count of resources that were lazy loaded in the frame.
307struct DeferredResourceCounts {
308  // The count of frames that were deferred due to lazy load.
309  uint64 deferred_frames = 0;
310  // The count of frames that were loaded after being deferred due to lazy load.
311  uint64 frames_loaded_after_deferral = 0;
312
313  // The count of images that were deferred due to lazy load.
314  uint64 deferred_images = 0;
315  // The count of images that were loaded after being deferred due to lazy load.
316  uint64 images_loaded_after_deferral = 0;
317};
318
319// Metrics about general input delay.
320struct InputTiming {
321  // The sum of all input delay.
322  mojo_base.mojom.TimeDelta total_input_delay;
323
324  // The sum of all adjusted input delay. We adjust each input delay by
325  // subtracting a small number, currently 50ms but subject to change in the
326  // future. And if the subtraction result is negative, we will use 0ms.
327  mojo_base.mojom.TimeDelta total_adjusted_input_delay;
328
329  // The number of user interactions, including click, tap, key press,
330  // cancellable touchstart, or pointer down followed by a pointer up.
331  uint64 num_input_events = 0;
332};
333
334// Sent from renderer to browser process when the PageLoadTiming for the
335// associated frame changed.
336interface PageLoadMetrics {
337  // Called when an update is ready to be sent from renderer to browser.
338  // UpdateTiming calls are buffered, and contain all updates that have been
339  // received in the last buffer window. Some of the update data may be empty.
340  // Only called when at least one change has been observed within the frame.
341  UpdateTiming(PageLoadTiming page_load_timing,
342               FrameMetadata frame_metadata,
343               PageLoadFeatures new_features,
344               array<ResourceDataUpdate> resources,
345               FrameRenderDataUpdate render_data,
346               CpuTiming cpu_load_timing,
347               DeferredResourceCounts new_deferred_resource_data,
348               InputTiming input_timing_delta,
349               blink.mojom.MobileFriendliness mobile_friendliness);
350
351  // Set up a shared memory used to transfer smoothness data from the renderer
352  // to the browser. The structure is defined in
353  // //cc/metrics/ukm_smoothness_data.h
354  SetUpSharedMemoryForSmoothness(
355      mojo_base.mojom.ReadOnlySharedMemoryRegion shared_memory);
356};
357
358// TimeDelta below relative to the navigation start of the navigation restoring
359// page from the back- forward cache.
360struct BackForwardCacheTiming {
361  // Time when the first paint is performed after the time when the page
362  // is restored from the back-forward cache.
363  mojo_base.mojom.TimeDelta first_paint_after_back_forward_cache_restore;
364
365  // Times on requestAnimationFrame when the page is restored from the back-
366  // forward cache.
367  array<mojo_base.mojom.TimeDelta> request_animation_frames_after_back_forward_cache_restore;
368
369  // Queueing Time of the first click, tap, key press, cancellable touchstart,
370  // or pointer down followed by a pointer up after the time when the page is
371  // restored from the back-forward cache.
372  mojo_base.mojom.TimeDelta? first_input_delay_after_back_forward_cache_restore;
373};
374