Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions bridge/core/html/html_image_element.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,26 @@ AtomicString HTMLImageElement::src() const {
}

void HTMLImageElement::setSrc(const AtomicString& value, ExceptionState& exception_state) {
SetBindingProperty(binding_call_methods::ksrc, NativeValueConverter<NativeTypeString>::ToNativeValue(ctx(), value),
exception_state);
// Queue a UI command rather than going through the sync bridge path:
//
// * `src` is fire-and-forget — JS never reads anything synchronously
// out of the setter, the actual network load is async on Dart, and
// any subsequent `img.src` getter / `getProperty` call calls
// `FlushUICommand` internally before its sync read so it still sees
// the value just written.
// * The sync path forced a per-write FlushUICommand, which during
// React commit + image-load swap bursts triggered cascading
// styleRecalc walks (~2k recalcs per insert in profiles). Folding
// these writes into the next natural flush eliminates the
// amplification.
//
// The HTMLImageElement attribute mirror is unchanged: `attributes_` is
// only kept in sync for `WidgetElement`, and the WidgetElement-only
// branch in `BindingObject::SetBindingProperty` is preserved by the
// remaining sync setters that need it.
SetBindingPropertyAsync(binding_call_methods::ksrc,
NativeValueConverter<NativeTypeString>::ToNativeValue(ctx(), value),
exception_state);
if (!value.IsEmpty() && !keep_alive) {
KeepAlive();
keep_alive = true;
Expand Down
Loading