I made a benchmark to measure how fast it is to call DOM APIs by passing DOM objects as exnternref
s to a Wasm function. This is the function to measure (written in Rust and compiled by rustc 1.55.0):
#[wasm_bindgen]
pub fn append_and_remove(elem: web_sys::Element) {
let doc = web_sys::window().unwrap().document().unwrap();
let child = &doc.create_element("br").unwrap();
elem.append_with_node_1(child).unwrap();
let _ = elem.remove_child(child).unwrap();
}
(See https://github.com/igrep/wasm-reference-types-examples for the entire code)
I compared two Wasm modules (and their JS wrappers) and the equivalent JavaScript code: one (the "With reference types" version) is preprocessed with wasm-bindgen --reference-types
, and another (the "NO Reference Types" version) is preprocessed just with wasm-bindgen
.
And here is the result when running them one million times:
Browser | Label | Time (ms) |
---|---|---|
Firefox 94.0.1 | NO reference types | 2167 |
With reference types | 2687 | |
Only JavaScript | 637 | |
Chrome 95.0.4638.69 | NO reference types | 3432 |
With reference types | 4129 | |
Only JavaScript | 1039 | |
Edge 95.0.1020.44 | NO reference types | 3416 |
With reference types | 3858 | |
Only JavaScript | 1187 |
(Both browsers are the 64bit version, on Windows 10)
According to the result above, the "NO reference types" version was faster than the "With reference types" version by approximately 20% in the three browsers. Even though the "With reference types" version was wrapped by smaller JavaScript, why was it defeated by the "NO reference types" version? What overhead did the Reference Types introduced?