diff --git a/Libraries/LibWeb/HTML/HTMLSelectElement.cpp b/Libraries/LibWeb/HTML/HTMLSelectElement.cpp
index 42070623503..34207d6c88d 100644
--- a/Libraries/LibWeb/HTML/HTMLSelectElement.cpp
+++ b/Libraries/LibWeb/HTML/HTMLSelectElement.cpp
@@ -2,6 +2,7 @@
* Copyright (c) 2020, the SerenityOS developers.
* Copyright (c) 2021-2022, Andreas Kling
* Copyright (c) 2023, Bastiaan van der Plaat
+ * Copyright (c) 2025, Shannon Booth
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@@ -292,9 +293,36 @@ i32 HTMLSelectElement::default_tab_index_value() const
return 0;
}
+bool HTMLSelectElement::can_skip_children_changed_selectedness_update(ChildrenChangedMetadata const& metadata) const
+{
+ // If the following criteria are met, there is no need to re-run the selectedness algorithm.
+ // FIXME: We can tighten up these conditions and skip even more work!
+ if (metadata.type != ChildrenChangedMetadata::Type::Inserted)
+ return false;
+
+ if (auto* option = as_if(*metadata.node)) {
+ if (option->selected())
+ return false;
+
+ if (m_cached_number_of_selected_options >= 2)
+ return false;
+
+ if (display_size() == 1 && m_cached_number_of_selected_options == 0)
+ return false;
+
+ return true;
+ }
+
+ return false;
+}
+
void HTMLSelectElement::children_changed(ChildrenChangedMetadata const* metadata)
{
Base::children_changed(metadata);
+
+ if (metadata && can_skip_children_changed_selectedness_update(*metadata))
+ return;
+
update_cached_list_of_options();
update_selectedness();
}
diff --git a/Libraries/LibWeb/HTML/HTMLSelectElement.h b/Libraries/LibWeb/HTML/HTMLSelectElement.h
index 9f563200acf..ddea134edaf 100644
--- a/Libraries/LibWeb/HTML/HTMLSelectElement.h
+++ b/Libraries/LibWeb/HTML/HTMLSelectElement.h
@@ -110,6 +110,7 @@ private:
virtual void computed_properties_changed() override;
virtual void children_changed(ChildrenChangedMetadata const*) override;
+ bool can_skip_children_changed_selectedness_update(ChildrenChangedMetadata const& metadata) const;
void update_cached_list_of_options() const;
void show_the_picker_if_applicable();