diff --git a/packages/yew/Cargo.toml b/packages/yew/Cargo.toml index bd0d5164c..9e20d13c0 100644 --- a/packages/yew/Cargo.toml +++ b/packages/yew/Cargo.toml @@ -75,7 +75,7 @@ features = [ "WheelEvent", "Window", "HtmlScriptElement", - "SubmitEvent" + "SubmitEvent", ] [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] @@ -89,11 +89,7 @@ trybuild = "1" [dev-dependencies.web-sys] version = "0.3" -features = [ - "ShadowRootInit", - "ShadowRootMode", - "HtmlButtonElement" -] +features = ["ShadowRootInit", "ShadowRootMode", "HtmlButtonElement"] [features] ssr = ["dep:html-escape", "dep:base64ct", "dep:bincode"] diff --git a/packages/yew/src/dom_bundle/btag/attributes.rs b/packages/yew/src/dom_bundle/btag/attributes.rs index 7731969cd..e2f41e114 100644 --- a/packages/yew/src/dom_bundle/btag/attributes.rs +++ b/packages/yew/src/dom_bundle/btag/attributes.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use std::ops::Deref; use indexmap::IndexMap; -use wasm_bindgen::JsValue; +use wasm_bindgen::{intern, JsValue}; use web_sys::{Element, HtmlInputElement as InputElement, HtmlTextAreaElement as TextAreaElement}; use yew::AttrValue; @@ -163,9 +163,9 @@ impl Attributes { fn set(el: &Element, key: &str, value: &str, apply_as: ApplyAttributeAs) { match apply_as { - ApplyAttributeAs::Attribute => { - el.set_attribute(key, value).expect("invalid attribute key") - } + ApplyAttributeAs::Attribute => el + .set_attribute(intern(key), value) + .expect("invalid attribute key"), ApplyAttributeAs::Property => { let key = JsValue::from_str(key); let value = JsValue::from_str(value); @@ -177,7 +177,7 @@ impl Attributes { fn remove(el: &Element, key: &str, apply_as: ApplyAttributeAs) { match apply_as { ApplyAttributeAs::Attribute => el - .remove_attribute(key) + .remove_attribute(intern(key)) .expect("could not remove attribute"), ApplyAttributeAs::Property => { let key = JsValue::from_str(key); diff --git a/packages/yew/src/dom_bundle/btag/mod.rs b/packages/yew/src/dom_bundle/btag/mod.rs index 0ef481092..57afcce4a 100644 --- a/packages/yew/src/dom_bundle/btag/mod.rs +++ b/packages/yew/src/dom_bundle/btag/mod.rs @@ -4,6 +4,8 @@ mod attributes; mod listeners; use std::borrow::Cow; +use std::cell::RefCell; +use std::collections::HashMap; use std::hint::unreachable_unchecked; use std::ops::DerefMut; @@ -252,9 +254,31 @@ impl VTag { .create_element_ns(namespace, tag) .expect("can't create namespaced element for vtag") } else { - document() - .create_element(tag) - .expect("can't create element for vtag") + thread_local! { + static CACHED_ELEMENTS: RefCell> = RefCell::new(HashMap::with_capacity(32)); + } + + CACHED_ELEMENTS.with(|cache| { + let mut cache = cache.borrow_mut(); + let cached = cache.get(tag).map(|el| { + el.clone_node() + .expect("couldn't clone cached element") + .unchecked_into::() + }); + cached.unwrap_or_else(|| { + let to_be_cached = document() + .create_element(tag) + .expect("can't create element for vtag"); + cache.insert( + tag.to_string(), + to_be_cached + .clone_node() + .expect("couldn't clone node to be cached") + .unchecked_into(), + ); + to_be_cached + }) + }) } } } diff --git a/packages/yew/src/dom_bundle/subtree_root.rs b/packages/yew/src/dom_bundle/subtree_root.rs index f9c719d3a..0a9f4954b 100644 --- a/packages/yew/src/dom_bundle/subtree_root.rs +++ b/packages/yew/src/dom_bundle/subtree_root.rs @@ -8,7 +8,7 @@ use std::rc::{Rc, Weak}; use std::sync::atomic::{AtomicBool, AtomicU32, Ordering}; use wasm_bindgen::prelude::{wasm_bindgen, Closure}; -use wasm_bindgen::{JsCast, UnwrapThrowExt}; +use wasm_bindgen::{intern, JsCast, UnwrapThrowExt}; use web_sys::{ AddEventListenerOptions, Element, Event, EventTarget as HtmlEventTarget, ShadowRoot, }; @@ -157,7 +157,7 @@ impl EventListener { target .add_event_listener_with_callback_and_add_event_listener_options( - &event_type, + intern(&event_type), callback.as_ref().unchecked_ref(), &options, )