Updating the visible property leads to sequential appearance of widgets

Hi,

I have written a small bokeh example which consists of 25 Select widgets and a Button that toggles all widgets between visible/invisible. When clicking on the button, I would expect that all widgets disappear/appear simulatenously, but, indeed the widgets disappear/appear sequentially one after the other.

Interestingly, when I toggle the widgets by setting the children property of the column layout, then the widgets disappear/appear simultaneously.

My question is: why is this the case?

Here is a code snipped that allows to reproduce the sequential behavior when running with the bokeh server. When you set the variable toggle_type=2 you can see that the widgets disappear /appear simultaneously.

from bokeh.models import Select, Button
from bokeh.layouts import row, column
from bokeh.io import show, curdoc

# Switch toggle type: 1 = change visibility of each widget, 2 = change children variable of column layout
toggle_type = 1

# Create a set of widgets
widgets = [Select(value=f'W{i}', options=[f'W{i}']) for i in range(25)]
toggle  = Button(label='Toggle_visibility')

# Create a column layout with a toggle and a nested column with all widgets
widget_layout = column(widgets)
layout        = column(toggle, widget_layout)

# Create 2 different types of widget toggling
def toggle_visibility():
    # toggle the visibility property of widgets
    for widget in widgets:
        widget.update(visible=not widget.visible)

def toggle_children():
    # toggle the children property of the column
    if len(widget_layout.children) > 0:
        widget_layout.children = []
    else:
        widget_layout.children = [widget for widget in widgets]

if toggle_type == 1:
    toggle.on_click(toggle_visibility)
else:
    toggle.on_click(toggle_children)

# Add layout to current document
curdoc().add_root(layout)

Property changes generate individual events, which are handled individually in sequence. So that’s the differenced between 25 updates to individual .visible properties vs one update to one .children property.

You might try curdoc().hold("combine") to coalesce multiple events into one, but that may not help supress multiple re-draws in this case.