docs(dom_widget_dev_guide): clarify dynamic resizing and add performance note

- Add performance note explaining that providing `getMinHeight` and `getHeight` via `options` avoids expensive DOM measurements
- Expand dynamic resizing section with detailed update sequence and common scenarios table
- Update LoraPoolSummaryView.vue with `min-height: 0` to allow flex shrinking
- Update main.ts to provide `getMinHeight` via options and adjust `computeLayoutSize` for performance
This commit is contained in:
Will Miao
2026-01-12 09:22:18 +08:00
parent 7a5f4514f3
commit 9719dd4d07
5 changed files with 53 additions and 18 deletions

View File

@@ -93,6 +93,8 @@ Whether in Canvas Mode or Vue Mode, the underlying logic model (`LGraphNode`) ca
It is recommended to use the `options` parameter to define height behavior.
**Performance Note:** providing `getMinHeight` and `getHeight` via `options` allows the system to skip expensive DOM measurements (`getComputedStyle`) during rendering loop. This significantly improves performance and prevents FPS drops during node resizing.
**Method 1: Using `options` (Recommended)**
```javascript
@@ -134,14 +136,32 @@ widget.computeLayoutSize = (targetNode) => {
### 4.4 Dynamic Resizing
If your widget's content changes dynamically (e.g., expanding sections, loading images), you must manually trigger a node resize:
If your widget's content changes dynamically (e.g., expanding sections, loading images, or CSS changes), the DOM element will resize, but the Canvas-rendered Node background and Slots will not automatically follow. You must manually trigger a synchronization.
**The Update Sequence:**
Whenever the **actual rendering height** of your DOM element changes, execute the following "three-step combo":
```javascript
// Execute after internal size changes:
node.setSize(node.computeSize());
node.setDirtyCanvas(true, true); // Force redraw
// 1. Calculate the new optimal size for the node based on current widget requirements
const newSize = node.computeSize();
// 2. Apply the new size to the node model (updates bounding box and slot positions)
node.setSize(newSize);
// 3. Mark the canvas as dirty to trigger a redraw in the next animation frame
node.setDirtyCanvas(true, true);
```
**Common Scenarios:**
| Scenario | Actual Height Change? | Update Required? |
| :--- | :--- | :--- |
| **Expand/Collapse content** | **Yes** | ✅ **Yes**. Prevents widget from overflowing node boundaries. |
| **Image/Video finished loading** | **Yes** | ✅ **Yes**. Initial height might be 0 until the media loads. |
| **Changing `minHeight`** | **Maybe** | ❓ **Only if** the change causes the element's actual height to shift. |
| **Changing font size/styles** | **Yes** | ✅ **Yes**. Text reflow often changes the total height. |
| **User dragging node corner** | **Yes** | ❌ **No**. LiteGraph handles this internally. |
---
## 5. State Persistence (Serialization)

View File

@@ -127,5 +127,7 @@ defineEmits<{
overflow-y: auto;
padding-right: 4px;
margin-right: -4px;
/* Allow flex item to shrink below content size */
min-height: 0;
}
</style>

View File

@@ -34,7 +34,12 @@ function createLoraPoolWidget(node) {
widget.onSetValue(v)
}
},
serialize: true
serialize: true,
// Per dev guide: providing getMinHeight via options allows the system to
// skip expensive DOM measurements during rendering loop, improving performance
getMinHeight() {
return 700
}
}
)
@@ -55,6 +60,13 @@ function createLoraPoolWidget(node) {
vueApp.mount(container)
vueApps.set(node.id, vueApp)
widget.computeLayoutSize = () => {
const minWidth = 500
const minHeight = 700
return { minHeight, minWidth }
}
widget.onRemove = () => {
const vueApp = vueApps.get(node.id)
if (vueApp) {
@@ -63,11 +75,6 @@ function createLoraPoolWidget(node) {
}
}
widget.computeLayoutSize = () => ({
minHeight: 600,
minWidth: 500
})
return { widget }
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long