[Tree widget]: change how categories handle their visibility on next#1694
Conversation
There was a problem hiding this comment.
Pull request overview
Updates tree-widget visibility computation to better account for descendant elements whose categories differ from their ancestors, and aligns model/category visibility calculations with “top-most category” semantics.
Changes:
- Always compute model visibility using only categories of top-most elements (
includeOnlyIfCategoryOfTopMostElement: true) and rely on descendant-category grouping for correctness. - Refactor always/never-drawn-based visibility to group descendant counts by the descendants’ actual categories and compute visibility per visible/hidden group.
- Update visibility tests to expect “all-visible” outcomes for cross-category descendant scenarios; adjust test cache mock behavior.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| packages/itwin/tree-widget/src/tree-widget-react/components/trees/common/internal/visibility/BaseVisibilityHelper.ts | Refactors visibility computation to use top-most categories and grouped descendant-category logic; updates change flows to account for cross-category descendants. |
| packages/itwin/tree-widget/src/test/trees/models-tree/Utils.ts | Updates fake IDs cache getDescendantsCounts mock used by tests. |
| packages/itwin/tree-widget/src/test/trees/models-tree/internal/ModelsTreeVisibilityHandler.test.ts | Updates expectations for model/category/element visibility in “child element category differs from parent’s” scenarios. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Tree-Widget Next benchmark
| Benchmark suite | Current: c4f6b1e | Previous: b618ede | Deviation | Status |
|---|---|---|---|---|
models tree 50k 3D elements search > get search paths |
1170 ms |
1207 ms |
-3.07% |
〰️ |
models tree 50k 3D elements search > get search paths (P95 of main thread blocks) |
53 ms |
58 ms |
-8.62% |
〰️ |
models tree 50k 3D elements search > load hierarchy from search paths |
104792 ms |
117082 ms |
-10.50% |
✅ |
models tree 50k 3D elements search > load hierarchy from search paths (P95 of main thread blocks) |
32 ms |
33 ms |
-3.03% |
〰️ |
models tree 50k categories > collect nodes |
2855 ms |
3016 ms |
-5.34% |
〰️ |
models tree 50k categories > collect nodes (P95 of main thread blocks) |
127 ms |
169 ms |
-24.85% |
〰️ |
models tree 50k categories > validate initial visibility |
1911 ms |
2072 ms |
-7.77% |
〰️ |
models tree 50k categories > validate initial visibility (P95 of main thread blocks) |
0 ms |
0 ms |
0% |
🟰 |
models tree 50k categories > change visibility |
217 ms |
87 ms |
149.43% |
🚨 |
models tree 50k categories > change visibility (P95 of main thread blocks) |
56 ms |
76 ms |
-26.32% |
〰️ |
models tree 50k categories > validate changed visibility |
3637 ms |
3647 ms |
-0.27% |
〰️ |
models tree 50k categories > validate changed visibility (P95 of main thread blocks) |
28 ms |
39 ms |
-28.21% |
〰️ |
models tree 50k 3D elements > collect nodes |
41176 ms |
46645 ms |
-11.72% |
✅ |
models tree 50k 3D elements > collect nodes (P95 of main thread blocks) |
69 ms |
76 ms |
-9.21% |
〰️ |
models tree 50k 3D elements > validate initial visibility |
1478 ms |
1748 ms |
-15.45% |
✅ |
models tree 50k 3D elements > validate initial visibility (P95 of main thread blocks) |
23 ms |
0 ms |
2300% |
〰️ |
models tree 50k 3D elements > change model visibility |
103 ms |
21 ms |
390.48% |
🚨 |
models tree 50k 3D elements > change model visibility (P95 of main thread blocks) |
0 ms |
0 ms |
0% |
🟰 |
models tree 50k 3D elements > validate changed model visibility |
1988 ms |
3216 ms |
-38.18% |
✅ |
models tree 50k 3D elements > validate changed model visibility (P95 of main thread blocks) |
0 ms |
24 ms |
-100% |
〰️ |
models tree 50k 3D elements > change category node visibility |
490 ms |
505 ms |
-2.97% |
〰️ |
models tree 50k 3D elements > change category node visibility (P95 of main thread blocks) |
57 ms |
59 ms |
-3.39% |
〰️ |
models tree 50k 3D elements > validate changed category visibility |
1355 ms |
1931 ms |
-29.83% |
✅ |
models tree 50k 3D elements > validate changed category visibility (P95 of main thread blocks) |
0 ms |
0 ms |
0% |
🟰 |
models tree 50k 3D elements > validate per-model category override |
1329 ms |
1874 ms |
-29.08% |
✅ |
models tree 50k 3D elements > validate per-model category override (P95 of main thread blocks) |
0 ms |
0 ms |
0% |
🟰 |
models tree 50k 3D elements > change element visibility |
33 ms |
33 ms |
0% |
🟰 |
models tree 50k 3D elements > change element visibility (P95 of main thread blocks) |
0 ms |
0 ms |
0% |
🟰 |
models tree 50k 3D elements > validate changed element visibility |
2126 ms |
2616 ms |
-18.73% |
✅ |
models tree 50k 3D elements > validate changed element visibility (P95 of main thread blocks) |
67 ms |
67 ms |
0% |
🟰 |
models tree 50k 3D child elements with different categories > collect nodes |
41435 ms |
46646 ms |
-11.17% |
✅ |
models tree 50k 3D child elements with different categories > collect nodes (P95 of main thread blocks) |
76 ms |
68 ms |
11.76% |
〰️ |
models tree 50k 3D child elements with different categories > validate initial visibility |
1447 ms |
1677 ms |
-13.71% |
✅ |
models tree 50k 3D child elements with different categories > validate initial visibility (P95 of main thread blocks) |
30 ms |
0 ms |
3000% |
〰️ |
models tree 50k 3D child elements with different categories > change visibility |
52 ms |
53 ms |
-1.89% |
〰️ |
models tree 50k 3D child elements with different categories > change visibility (P95 of main thread blocks) |
0 ms |
0 ms |
0% |
🟰 |
models tree 50k 3D child elements with different categories > validate changed visibility |
2546 ms |
3803 ms |
-33.05% |
✅ |
models tree 50k 3D child elements with different categories > validate changed visibility (P95 of main thread blocks) |
86 ms |
82 ms |
4.88% |
〰️ |
categories tree 50k subCategories search > get search paths |
1743 ms |
1888 ms |
-7.68% |
〰️ |
categories tree 50k subCategories search > get search paths (P95 of main thread blocks) |
40 ms |
44 ms |
-9.09% |
〰️ |
categories tree 50k subCategories search > load hierarchy from search paths |
5371 ms |
5657 ms |
-5.06% |
〰️ |
categories tree 50k subCategories search > load hierarchy from search paths (P95 of main thread blocks) |
51 ms |
55 ms |
-7.27% |
〰️ |
categories tree 50k subCategories > collect nodes |
5699 ms |
6112 ms |
-6.76% |
〰️ |
categories tree 50k subCategories > collect nodes (P95 of main thread blocks) |
42 ms |
49 ms |
-14.29% |
〰️ |
categories tree 50k subCategories > validate initial visibility |
1188 ms |
1190 ms |
-0.17% |
〰️ |
categories tree 50k subCategories > validate initial visibility (P95 of main thread blocks) |
26 ms |
27 ms |
-3.70% |
〰️ |
categories tree 50k subCategories > change visibility |
340 ms |
370 ms |
-8.11% |
〰️ |
categories tree 50k subCategories > change visibility (P95 of main thread blocks) |
24 ms |
37 ms |
-35.14% |
〰️ |
categories tree 50k subCategories > validate changed visibility |
1067 ms |
1083 ms |
-1.48% |
〰️ |
categories tree 50k subCategories > validate changed visibility (P95 of main thread blocks) |
32 ms |
44 ms |
-27.27% |
〰️ |
categories tree 50k categories > collect nodes |
2424 ms |
2520 ms |
-3.81% |
〰️ |
categories tree 50k categories > collect nodes (P95 of main thread blocks) |
123 ms |
136 ms |
-9.56% |
〰️ |
categories tree 50k categories > validate initial visibility |
5087 ms |
5378 ms |
-5.41% |
〰️ |
categories tree 50k categories > validate initial visibility (P95 of main thread blocks) |
128 ms |
117 ms |
9.40% |
〰️ |
categories tree 50k categories > change visibility |
772 ms |
685 ms |
12.70% |
🚨 |
categories tree 50k categories > change visibility (P95 of main thread blocks) |
62 ms |
61 ms |
1.64% |
〰️ |
categories tree 50k categories > validate changed visibility |
4865 ms |
5001 ms |
-2.72% |
〰️ |
categories tree 50k categories > validate changed visibility (P95 of main thread blocks) |
35 ms |
46 ms |
-23.91% |
〰️ |
classifications tree 50k classifications search > get search paths |
2106 ms |
2159 ms |
-2.45% |
〰️ |
classifications tree 50k classifications search > get search paths (P95 of main thread blocks) |
128 ms |
152 ms |
-15.79% |
〰️ |
classifications tree 50k classifications search > load hierarchy from search paths |
64416 ms |
73053 ms |
-11.82% |
✅ |
classifications tree 50k classifications search > load hierarchy from search paths (P95 of main thread blocks) |
0 ms |
0 ms |
0% |
🟰 |
classifications tree 50k classifications > collect nodes |
35123 ms |
39556 ms |
-11.21% |
✅ |
classifications tree 50k classifications > collect nodes (P95 of main thread blocks) |
76 ms |
93 ms |
-18.28% |
〰️ |
classifications tree 50k classifications > validate initial visibility |
3463 ms |
3821 ms |
-9.37% |
〰️ |
classifications tree 50k classifications > validate initial visibility (P95 of main thread blocks) |
66 ms |
89 ms |
-25.84% |
〰️ |
classifications tree 50k classifications > change visibility |
34 ms |
30 ms |
13.33% |
〰️ |
classifications tree 50k classifications > change visibility (P95 of main thread blocks) |
0 ms |
0 ms |
0% |
🟰 |
classifications tree 50k classifications > validate changed visibility |
3911 ms |
4151 ms |
-5.78% |
〰️ |
classifications tree 50k classifications > validate changed visibility (P95 of main thread blocks) |
101 ms |
104 ms |
-2.88% |
〰️ |
This comment was automatically generated by workflow using github-action-benchmark.
|
Did you look at the performance regressions? The following seem worth having a look at:
|
Adjusted implementation, a few things:
This improved the performance (at least in current perf tests) without adding much overhead IMO. Now performance is very similar to what it was before these changes. |
Phases 3b and 3d. of #1678.
In addition: changed model visibility to always use
includeOnlyIfCategoryOfTopMostElement: true(previously only ifisAlwaysDrawnExclusivemode), since top-most categories now correctly determine visibility of nested children in differentcategories.