Skip to content

Commit 1a638c3

Browse files
philippjfrmattpap
andcommitted
Avoid re-appending views if order is unchanged (bokeh#14483)
* Avoid re-appending views if order is unchanged * Fix lint * Correctly determine existing order * Use enumerate() instead of for-loop --------- Co-authored-by: Mateusz Paprocki <[email protected]>
1 parent 75cb9b9 commit 1a638c3

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

bokehjs/src/lib/models/layouts/layout_dom.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {Align, Dimensions, FlowMode, SizingMode} from "core/enums"
66
import {px} from "core/dom"
77
import type {Display, CSSStyles} from "core/css"
88
import {isNumber, isArray} from "core/util/types"
9+
import {enumerate} from "core/util/iterator"
910
import type * as p from "core/properties"
1011

1112
import type {ViewStorage, IterViews} from "core/build_views"
@@ -156,15 +157,31 @@ export abstract class LayoutDOMView extends PaneView {
156157
const created = await this.build_child_views()
157158
const created_views = new Set(created)
158159

160+
// Find index up to which the order of the existing views
161+
// matches the order of the new views. This allows us to
162+
// skip re-inserting the views up to this point
163+
const current_views = Array.from(this.shadow_el.children).flatMap(el => {
164+
const view = this.child_views.find(view => view.el === el)
165+
return view === undefined ? [] : [view]
166+
})
167+
let matching_index = null
168+
for (let i = 0; i < current_views.length; i++) {
169+
if (current_views[i] === this.child_views[i]) {
170+
matching_index = i
171+
} else {
172+
break
173+
}
174+
}
175+
159176
// Since appending to a DOM node will move the node to the end if it has
160177
// already been added appending all the children in order will result in
161178
// correct ordering.
162-
for (const view of this.child_views) {
179+
for (const [view, i] of enumerate(this.child_views)) {
163180
const is_new = created_views.has(view)
164181
const target = view.rendering_target() ?? this.self_target
165182
if (is_new) {
166183
view.render_to(target)
167-
} else {
184+
} else if (matching_index === null || i > matching_index) {
168185
target.append(view.el)
169186
}
170187
}

0 commit comments

Comments
 (0)