From 05351dfe45e3b7eb4c4d0a0ee69ebaf185571bdc Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Mon, 27 Jan 2025 09:00:02 +0000 Subject: [PATCH] LibWeb: Return wall time from PerformanceTiming interface This matches the behavior of other browsers. --- Libraries/LibWeb/DOM/Document.h | 12 +++--- .../NavigationTiming/PerformanceTiming.cpp | 20 ++++++++-- .../NavigationTiming/PerformanceTiming.h | 38 +++++++++++++++---- 3 files changed, 52 insertions(+), 18 deletions(-) diff --git a/Libraries/LibWeb/DOM/Document.h b/Libraries/LibWeb/DOM/Document.h index f0c86cc8222..72affa78d2f 100644 --- a/Libraries/LibWeb/DOM/Document.h +++ b/Libraries/LibWeb/DOM/Document.h @@ -54,17 +54,17 @@ struct DocumentLoadTimingInfo { // https://html.spec.whatwg.org/multipage/dom.html#navigation-start-time double navigation_start_time { 0 }; // https://html.spec.whatwg.org/multipage/dom.html#dom-interactive-time - double dom_interactive_time { 0 }; + HighResolutionTime::DOMHighResTimeStamp dom_interactive_time { 0 }; // https://html.spec.whatwg.org/multipage/dom.html#dom-content-loaded-event-start-time - double dom_content_loaded_event_start_time { 0 }; + HighResolutionTime::DOMHighResTimeStamp dom_content_loaded_event_start_time { 0 }; // https://html.spec.whatwg.org/multipage/dom.html#dom-content-loaded-event-end-time - double dom_content_loaded_event_end_time { 0 }; + HighResolutionTime::DOMHighResTimeStamp dom_content_loaded_event_end_time { 0 }; // https://html.spec.whatwg.org/multipage/dom.html#dom-complete-time - double dom_complete_time { 0 }; + HighResolutionTime::DOMHighResTimeStamp dom_complete_time { 0 }; // https://html.spec.whatwg.org/multipage/dom.html#load-event-start-time - double load_event_start_time { 0 }; + HighResolutionTime::DOMHighResTimeStamp load_event_start_time { 0 }; // https://html.spec.whatwg.org/multipage/dom.html#load-event-end-time - double load_event_end_time { 0 }; + HighResolutionTime::DOMHighResTimeStamp load_event_end_time { 0 }; }; // https://html.spec.whatwg.org/multipage/dom.html#document-unload-timing-info diff --git a/Libraries/LibWeb/NavigationTiming/PerformanceTiming.cpp b/Libraries/LibWeb/NavigationTiming/PerformanceTiming.cpp index 7b9740ac9ba..d3ba7753132 100644 --- a/Libraries/LibWeb/NavigationTiming/PerformanceTiming.cpp +++ b/Libraries/LibWeb/NavigationTiming/PerformanceTiming.cpp @@ -1,14 +1,15 @@ /* * Copyright (c) 2021, Andreas Kling + * Copyright (c) 2025, Tim Ledbetter * * SPDX-License-Identifier: BSD-2-Clause */ #include +#include #include namespace Web::NavigationTiming { - GC_DEFINE_ALLOCATOR(PerformanceTiming); PerformanceTiming::PerformanceTiming(JS::Realm& realm) @@ -24,13 +25,24 @@ void PerformanceTiming::initialize(JS::Realm& realm) WEB_SET_PROTOTYPE_FOR_INTERFACE(PerformanceTiming); } -DOM::DocumentLoadTimingInfo const& PerformanceTiming::document_load_timing_info() const +DOM::DocumentLoadTimingInfo const& PerformanceTiming::document_load_timing_info(JS::Object const& global_object) const { - auto& global_object = HTML::relevant_global_object(*this); VERIFY(is(global_object)); - auto& window = static_cast(global_object); + auto& window = static_cast(global_object); auto document = window.document(); return document->load_timing_info(); } +u64 PerformanceTiming::monotonic_timestamp_to_wall_time_milliseconds(Function selector) const +{ + auto& global_object = HTML::relevant_global_object(*this); + auto timestamp = selector(document_load_timing_info(global_object)); + if (timestamp == 0) + return 0; + + auto wall_time = timestamp - HighResolutionTime::estimated_monotonic_time_of_the_unix_epoch(); + auto coarsened_time = HighResolutionTime::coarsen_time(wall_time); + return static_cast(coarsened_time); +} + } diff --git a/Libraries/LibWeb/NavigationTiming/PerformanceTiming.h b/Libraries/LibWeb/NavigationTiming/PerformanceTiming.h index 6159824fd6a..493755bb0ab 100644 --- a/Libraries/LibWeb/NavigationTiming/PerformanceTiming.h +++ b/Libraries/LibWeb/NavigationTiming/PerformanceTiming.h @@ -20,7 +20,10 @@ public: ~PerformanceTiming(); - u64 navigation_start() { return document_load_timing_info().navigation_start_time; } + u64 navigation_start() + { + return monotonic_timestamp_to_wall_time_milliseconds([](auto& load_info) { return load_info.navigation_start_time; }); + } u64 unload_event_start() { return 0; } u64 unload_event_end() { return 0; } u64 redirect_start() { return 0; } @@ -35,17 +38,36 @@ public: u64 response_start() { return 0; } u64 response_end() { return 0; } u64 dom_loading() { return 0; } - u64 dom_interactive() { return document_load_timing_info().dom_interactive_time; } - u64 dom_content_loaded_event_start() { return document_load_timing_info().dom_content_loaded_event_start_time; } - u64 dom_content_loaded_event_end() { return document_load_timing_info().dom_content_loaded_event_end_time; } - u64 dom_complete() { return document_load_timing_info().dom_complete_time; } - u64 load_event_start() { return document_load_timing_info().load_event_start_time; } - u64 load_event_end() { return document_load_timing_info().load_event_end_time; } + u64 dom_interactive() + { + return monotonic_timestamp_to_wall_time_milliseconds([](auto& load_info) { return load_info.dom_interactive_time; }); + } + u64 dom_content_loaded_event_start() + { + return monotonic_timestamp_to_wall_time_milliseconds([](auto& load_info) { return load_info.dom_content_loaded_event_start_time; }); + } + u64 dom_content_loaded_event_end() + { + return monotonic_timestamp_to_wall_time_milliseconds([](auto& load_info) { return load_info.dom_content_loaded_event_end_time; }); + } + u64 dom_complete() + { + return monotonic_timestamp_to_wall_time_milliseconds([](auto& load_info) { return load_info.dom_complete_time; }); + } + u64 load_event_start() + { + return monotonic_timestamp_to_wall_time_milliseconds([](auto& load_info) { return load_info.load_event_start_time; }); + } + u64 load_event_end() + { + return monotonic_timestamp_to_wall_time_milliseconds([](auto& load_info) { return load_info.load_event_end_time; }); + } private: explicit PerformanceTiming(JS::Realm&); - DOM::DocumentLoadTimingInfo const& document_load_timing_info() const; + DOM::DocumentLoadTimingInfo const& document_load_timing_info(JS::Object const& global_object) const; + u64 monotonic_timestamp_to_wall_time_milliseconds(Function selector) const; virtual void initialize(JS::Realm&) override; };