Connect: read the whole app from app.sab instead of component by component

Saves the app on the device, reads app.sab and fills the Sox cache with the tree,
config and links in one go: 8 s instead of 116 s for 230 components on a P-ION,
0.9 s instead of 16 s for 194 on an Orion. Sox keeps the cache current from
there as before. On any failure, or when app.sab does not match the running
tree, it falls back to lazy loading. A sheet's first open reads only runtime
values; a tree expand with nothing to load no longer rebuilds the DOM.

bench_sab_seed.py times both ways against a device.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-11 14:01:32 +03:00
co-authored by Claude Opus 5.5
parent db7b6632af
commit cb0196caa7
4 changed files with 277 additions and 8 deletions
+10 -1
View File
@@ -2953,7 +2953,8 @@ def _on_connected(ds, root_comp):
menu_device.entryconfig("Download to SAX...", state="normal")
menu_app_info.entryconfig("Get with Files...", state="normal")
menu_app_info.entryconfig("Put with Files...", state="normal")
app_state.set_status(f"Connected to {app_state.device_host}:{app_state.device_port}")
app_state.set_status(f"Connected to {app_state.device_host}:{app_state.device_port}"
f" ({ds.seed_info})")
sax_root = ds.build_dom_tree(root_comp)
app_state.xml_root_element = sax_root
@@ -3097,6 +3098,14 @@ def _live_tree_expand(comp_id, tree_item_id, select=True, on_loaded=None):
if ds is None or not ds.is_connected:
return
# Every child already in the tree (app.sab gave the whole app, or it was opened
# before): nothing to load, and rebuilding the DOM would only cost the undo steps.
elem = app_state.tree_element_map.get(tree_item_id)
if elem is not None and all(c.get("name") != "..." for c in elem.findall("comp")):
if on_loaded is not None:
on_loaded(tree_item_id)
return
app_state.set_status("Loading children...")
def _bg():