1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 17:37:34 +00:00

LibWeb: Introduce Performance Timeline and its Performance functions

This commit is contained in:
Luke Wilde 2023-03-22 19:12:57 +00:00 committed by Linus Groh
parent 4c3f1481ea
commit 31b507afbf
16 changed files with 381 additions and 1 deletions

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/PerformanceTimeline/EntryTypes.h>
namespace Web::PerformanceTimeline::EntryTypes {
#define __ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE(name) FlyString name;
ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPES
#undef __ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE
ErrorOr<void> initialize_strings()
{
static bool s_initialized = false;
VERIFY(!s_initialized);
#define __ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE(name) \
name = TRY(#name##_fly_string);
ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPES
#undef __ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE
// NOTE: Special cases for attributes with dashes in them.
first_input = TRY("first-input"_fly_string);
largest_contentful_paint = TRY("largest-contentful-paint"_fly_string);
layout_shift = TRY("layout-shift"_fly_string);
s_initialized = true;
return {};
}
}

View file

@ -0,0 +1,33 @@
/*
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/FlyString.h>
namespace Web::PerformanceTimeline::EntryTypes {
// https://w3c.github.io/timing-entrytypes-registry/#registry
#define ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPES \
__ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE(element) \
__ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE(event) \
__ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE(first_input) \
__ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE(largest_contentful_paint) \
__ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE(layout_shift) \
__ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE(longtask) \
__ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE(mark) \
__ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE(measure) \
__ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE(navigation) \
__ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE(resource) \
__ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE(paint)
#define __ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE(name) extern FlyString name;
ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPES
#undef __ENUMERATE_PERFORMANCE_TIMELINE_ENTRY_TYPE
ErrorOr<void> initialize_strings();
}

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Bindings/PerformanceEntryPrototype.h>
#include <LibWeb/PerformanceTimeline/PerformanceEntry.h>
namespace Web::PerformanceTimeline {
PerformanceEntry::PerformanceEntry(JS::Realm& realm, String const& name, HighResolutionTime::DOMHighResTimeStamp start_time, HighResolutionTime::DOMHighResTimeStamp duration)
: Bindings::PlatformObject(realm)
, m_name(name)
, m_start_time(start_time)
, m_duration(duration)
{
}
PerformanceEntry::~PerformanceEntry() = default;
JS::ThrowCompletionOr<void> PerformanceEntry::initialize(JS::Realm& realm)
{
MUST_OR_THROW_OOM(Base::initialize(realm));
set_prototype(&Bindings::ensure_web_prototype<Bindings::PerformanceEntryPrototype>(realm, "PerformanceEntry"));
return {};
}
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibWeb/Bindings/PlatformObject.h>
#include <LibWeb/HighResolutionTime/DOMHighResTimeStamp.h>
namespace Web::PerformanceTimeline {
enum class AvailableFromTimeline {
No,
Yes,
};
enum class ShouldAddEntry {
No,
Yes,
};
// https://www.w3.org/TR/performance-timeline/#dom-performanceentry
class PerformanceEntry : public Bindings::PlatformObject {
WEB_PLATFORM_OBJECT(PerformanceEntry, Bindings::PlatformObject);
public:
virtual ~PerformanceEntry();
// https://www.w3.org/TR/performance-timeline/#dom-performanceentry-entrytype
virtual FlyString const& entry_type() const = 0;
String const& name() const { return m_name; }
HighResolutionTime::DOMHighResTimeStamp start_time() const { return m_start_time; }
HighResolutionTime::DOMHighResTimeStamp duration() const { return m_duration; }
// https://w3c.github.io/timing-entrytypes-registry/#dfn-should-add-entry
virtual PerformanceTimeline::ShouldAddEntry should_add_entry() const = 0;
protected:
PerformanceEntry(JS::Realm&, String const& name, HighResolutionTime::DOMHighResTimeStamp start_time, HighResolutionTime::DOMHighResTimeStamp duration);
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
private:
// https://www.w3.org/TR/performance-timeline/#dom-performanceentry-name
String m_name;
// https://www.w3.org/TR/performance-timeline/#dom-performanceentry-starttime
HighResolutionTime::DOMHighResTimeStamp m_start_time { 0.0 };
// https://www.w3.org/TR/performance-timeline/#dom-performanceentry-duration
HighResolutionTime::DOMHighResTimeStamp m_duration { 0.0 };
};
}

View file

@ -0,0 +1,11 @@
#import <HighResolutionTime/DOMHighResTimeStamp.idl>
// https://www.w3.org/TR/performance-timeline/#dom-performanceentry
[Exposed=(Window,Worker), UseNewAKString]
interface PerformanceEntry {
readonly attribute DOMString name;
readonly attribute DOMString entryType;
readonly attribute DOMHighResTimeStamp startTime;
readonly attribute DOMHighResTimeStamp duration;
[Default] object toJSON();
};

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibWeb/PerformanceTimeline/PerformanceEntry.h>
namespace Web::PerformanceTimeline {
// https://www.w3.org/TR/performance-timeline/#dfn-performance-entry-buffer-map
struct PerformanceEntryTuple {
// https://www.w3.org/TR/performance-timeline/#dfn-performance-entry-buffer
// A performance entry buffer to store PerformanceEntry objects, that is initially empty.
Vector<JS::Handle<PerformanceEntry>> performance_entry_buffer;
// https://www.w3.org/TR/performance-timeline/#dfn-maxbuffersize
// An integer maxBufferSize, initialized to the registry value for this entry type.
// NOTE: The empty state represents Infinite size.
Optional<u64> max_buffer_size;
// https://www.w3.org/TR/performance-timeline/#dfn-availablefromtimeline
// A boolean availableFromTimeline, initialized to the registry value for this entry type.
AvailableFromTimeline available_from_timeline { AvailableFromTimeline::No };
// https://www.w3.org/TR/performance-timeline/#dfn-dropped-entries-count
// An integer dropped entries count that is initially 0.
u64 dropped_entries_count { 0 };
// https://www.w3.org/TR/performance-timeline/#dfn-determine-if-a-performance-entry-buffer-is-full
bool is_full()
{
// 1. Let num current entries be the size of tuple's performance entry buffer.
auto num_current_entries = performance_entry_buffer.size();
// 2. If num current entries is less than tuples's maxBufferSize, return false.
if (!max_buffer_size.has_value() || num_current_entries < max_buffer_size.value())
return false;
// 3. Increase tuple's dropped entries count by 1.
++dropped_entries_count;
// 4. Return true.
return true;
}
};
}