perf(handler): centralize HTML attribute writing in ResponseWriter - #467
Merged
Mohamed Mansour (mohamedmansour) merged 2 commits intoAug 24, 2026
Conversation
Add hidden `write_attribute`/`write_boolean_attribute` methods to `ResponseWriter` with `write()`-based defaults, plus centralized append helpers and macros that let buffered hosts emit attributes with a direct buffer append instead of five virtual dispatches. Adopt the macros across every buffered host writer, removing six duplicated `ResponseWriter` implementations in webui-ffi, webui-python, webui-press, webui-cli, webui-wasm, webui, webui-node, and the demo server. Streaming and callback writers override the methods directly so their flush and forwarding semantics are preserved. Output is byte-identical: the default trait methods emit the same sequence as before, and the macro-generated methods write the same bytes without routing through `write()`. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Mohamed Mansour (mohamedmansour)
requested review from
Bang Lee (Qusic),
Akrosh Gandhi (akroshg),
Jane Chu (janechu) and
mcritzjam
and
a lite review from Copilot
August 24, 2026 18:05
Copilot started reviewing on behalf of
Mohamed Mansour (mohamedmansour)
August 24, 2026 18:06
View session
Contributor
There was a problem hiding this comment.
Pull request overview
This PR centralizes HTML attribute emission in webui-handler by adding hidden ResponseWriter methods for quoted and boolean attributes, plus shared append helpers and macro generators to let buffered hosts inline optimized attribute writing and reduce virtual dispatch overhead in the render pipeline.
Changes:
- Added
ResponseWriter::write_attribute/write_boolean_attribute(hidden, defaulted) and switched handler attribute emission to call the new method. - Introduced centralized attribute append helpers +
macro_rules!generators, and migrated multiple buffered host writers to macro-generated implementations. - Updated streaming/callback writers (streaming, WASM, Node) to implement the hidden attribute methods directly to preserve flushing/forwarding semantics; added/updated benches and tests and updated
DESIGN.md.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| examples/demo/server/src/shell.rs | Replaces a local ResponseWriter impl with a macro-defined string writer. |
| DESIGN.md | Documents the new attribute-writing contract and when to override hidden methods. |
| crates/webui/src/streaming.rs | Implements optimized attribute methods for StreamingWriter while preserving flush behavior. |
| crates/webui/src/server.rs | Replaces an internal MemWriter with a macro-defined string writer. |
| crates/webui/benches/contact_book_bench.rs | Fixes bench command docs and adds macro-generated attribute methods to bench writer. |
| crates/webui-wasm/src/handler.rs | Uses macro-defined string writer and adds optimized attribute methods to CallbackWriter. |
| crates/webui-python/src/lib.rs | Replaces bytes writer impl with macro-defined bytes writer and updates construction callsite. |
| crates/webui-press/src/build.rs | Replaces local string writer impl with a macro-defined string writer. |
| crates/webui-node/src/lib.rs | Replaces buffered writer impl with macro-defined writer and adds optimized attribute methods to callback writer. |
| crates/webui-handler/src/streaming/owned.rs | Adds optimized attribute methods to BufferSink. |
| crates/webui-handler/src/streaming/mod.rs | Adds optimized attribute methods to StreamingSink, including buffered component-opening handling. |
| crates/webui-handler/src/response_writer.rs | New module providing append helpers and macros for defining/augmenting buffered writers. |
| crates/webui-handler/src/lib.rs | Wires in the new module/exports, adds hidden trait methods, switches write_attr to call them, and adds a regression test. |
| crates/webui-handler/benches/streaming_hydration_bench.rs | Adds macro-generated attribute methods to bench writer. |
| crates/webui-handler/benches/handler_bench.rs | Adds macro-generated attribute methods to bench writer. |
| crates/webui-handler/benches/bootstrap_state_bench.rs | Adds macro-generated attribute methods to bench writer. |
| crates/webui-ffi/src/lib.rs | Replaces local string writer impl with macro-defined writer and updates construction callsite. |
| crates/webui-cli/src/commands/serve.rs | Replaces local in-memory writer impl with macro-defined writer and adjusts ownership of output buffer. |
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Move `use metafile::write_atomic;` into the contiguous import block so the `define_string_response_writer!` invocation, which defines the `MemoryWriter` type, sits after all imports instead of between them. Addresses PR microsoft#467 review feedback. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: bfb1dbef-d6a7-4d85-93c4-90d9b61cfc3c
Jane Chu (janechu)
approved these changes
Aug 24, 2026
Mohamed Mansour (mohamedmansour)
merged commit Aug 24, 2026
39c263e
into
microsoft:main
24 checks passed
Mohamed Mansour (mohamedmansour)
deleted the
mohamedmansour-split-performance-prs
branch
August 24, 2026 19:15
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds hidden
write_attribute/write_boolean_attributemethods to theResponseWritertrait, backed by centralized append helpers and fourmacro_rules!generators in a newcrates/webui-handler/src/response_writer.rs.Buffered hosts adopt the macros and drop their hand-written writer implementations. Six duplicated
ResponseWriterimpls are removed (webui-ffi,webui-python,webui-press,webui-cli,webui-wasm,webui, pluswebui-node'sBufferedWriterand the demo server's shell writer).Writers with distinct semantics —
StreamingSink,BufferSink,StreamingWriter, and the NodeCallbackWriter— implement the methods directly so threshold flushing and stream forwarding are preserved.Why
Emitting one HTML attribute previously cost five
write()calls through adyn ResponseWritervtable (" ", name,"=\"", value,"\""). For a buffered host, all five collapse into a directpush_stron the backingString/Vec<u8>.This is the structural prerequisite for the later handler render-pipeline layers, which are attribute-bound.
Evidence
Correctness — byte-identical output (deterministic)
A temporary harness rendered a mixed protocol (component attrs, attribute templates, boolean attrs, nested
forloop with a per-item attribute) at 10 / 100 / 2,000 items, on the merge base and on this branch, using a generic writer that implements onlywrite():write()callsorigin/main489c33c436b03492489c33c436b03492origin/maine48fab1207c9a292e48fab1207c9a292origin/mainec91d5c009de1b8aec91d5c009de1b8aIdentical hash, byte count, and call count — the
write()-based defaults are behaviorally indistinguishable from the previous inline code, so externalResponseWriterimplementors are unaffected.Dispatch reduction — the actual change (deterministic)
Same render, generic writer vs. a macro-generated writer, output asserted equal:
write()callswrite()callsExactly 5 virtual dispatches removed per attribute (2,002 attributes × 5 = 10,010 at the 2,000-item scale).
Wall-clock — no claim made
Commands:
Ran 3 interleaved base/branch cycles with prebuilt binaries at high priority (24-core dev machine, ~22% background load). The measurements are not usable: run-to-run spread across identical repeated runs of the same binary reached 31%, exceeding every observed between-variant delta (max 13%).
contact_book_protocol_parse— pure protobuf decode, untouched by this PR — "regressed" 43% on one pass, confirming the noise floor.No performance improvement is claimed from timing data. The deterministic dispatch counts above are the evidence for this PR. Wall-clock benchmarking should be repeated on a quiet machine in the layer where it is load-bearing.
Allocation behavior is unchanged: no new allocations are introduced on any path, and the macro writers append into the caller's existing buffer.
Tests
generated_string_writer_methods_preserve_exact_attribute_outputasserts exact output (" data-id=\"42\" disabled") through the macro path.cargo test -p microsoft-webui-handler— 428 + 29 passing.cargo xtask check:license-headers,fmt,clippy,proto,deny,test,build,build (wasm),build (examples),bench (validate)all pass.docsstep fails withPROJ-C013: Adapter module graph is incomplete or inconsistentfrom the esbuild projection adapter. This reproduces identically on a pristineorigin/maincheckout and is unrelated to this PR, which changes no JavaScript.Notes
ResponseWritergains only#[doc(hidden)]methods with defaults — no breaking change for external implementors.DESIGN.mddocuments the macro contract and when a host should implement the methods directly.Cargo.lock, orpnpm-lock.yamlchanges.