Resizing Performance Buff Reminder
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 50/100
- Issue type
- Refactor
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- lua
- Domain
- performance
Research direction
Start by reading Resize:_Move and the Window:SetSize path to see where each pointer move triggers a geometry cascade, then follow the Logic subscription that currently calls _Refresh. Run resize_test to see the 22 timing assertions the issue mentions and confirm the proposed next-tick timing by adding a tick after pointer moves. Done means resizing applies once per Logic tick, the 1-move-per-frame case does not regress, the tests reflect the new timing, and the double overlay sync noted in scroll.lua is checked.
Written by the indexing model from the issue text.
Description
Resize:_Move applies setRect on every ONHOLD, and Window:SetSize does a full geometry cascade each time. I counted it on your own test harness with a window that has 150 content rows and its 188 geometry resolutions per pointer move, so if the mouse outruns the frame your'e doing more cascades than there are frames to draw them. idle is completely free though, 50 ticks and zero work, so its only during a drag
this stashes the pending rect and lets the Logic tick apply it once. the cost goes flat instead of scaling with how fast you drag, at 3 moves a frame its 11280 resolutions down to 3760 and at 6 its 22560 down to 3760. at 1 move a frame its identical so nothing regresses
fair warning it does change the timing, the resize lands on the next tick instead of straight away, and resize_test asserts the old timing in 22 places. I ran your suite with a tick() after each pointer move and it all passes, so I think the logic is right and only the timing moved, but that's your call not mine
the one thing I couldnt measure is how many ONHOLD events the client actually gives you per logic tick. if its exactly one this buys nothing
@@ -156,21 +156,34 @@
local dx, dy = mouse.x - drag.mouseX, mouse.y - drag.mouseY
drag.mouseX, drag.mouseY = mouse.x, mouse.y
local root, parent, edge = self.root, self.parent, edges[drag.edge]
- local nextX, width = resizeAxis(root.x, root.width, dx, edge.west, edge.east,
+ -- accumulate here, the Logic tick applies it once
+ local from = drag.pending or root
+ local nextX, width = resizeAxis(from.x, from.width, dx, edge.west, edge.east,
parent.width, self.minWidth, self.maxWidth)
- local nextY, height = resizeAxis(root.y, root.height, dy, edge.north, edge.south,
+ local nextY, height = resizeAxis(from.y, from.height, dy, edge.north, edge.south,
parent.height, self.minHeight, self.maxHeight)
- if nextX ~= root.x or nextY ~= root.y or width ~= root.width or height ~= root.height then
+ drag.pending = { x = nextX, y = nextY, width = width, height = height }
+ return false
+end
+
+function Resize:_Flush()
+ local drag = self.dragState
+ local rect = drag and drag.pending
+ if not rect then return end
+ drag.pending = nil
+ if not available(self) then return end
+ local root = self.root
+ if rect.x ~= root.x or rect.y ~= root.y or
+ rect.width ~= root.width or rect.height ~= root.height then
-- Owners may synchronously reflow their content and call Refresh again.
self.applying = true
- self.setRect(nextX, nextY, width, height)
+ self.setRect(rect.x, rect.y, rect.width, rect.height)
self.applying = false
end
- self:Refresh()
- return false
end
function Resize:Cancel()
+ self:_Flush()
self:_Clear()
self:Refresh()
return false
@@ -234,7 +247,10 @@
controllers[self] = true
if wasEmpty then
Event.Logic.Subscribe(EVENT_ID, function()
- for controller in pairs(controllers) do controller:_Refresh(false) end
+ for controller in pairs(controllers) do
+ controller:_Flush()
+ controller:_Refresh(false)
+ end
end)
end
self:Refresh()
also noticed SetSize syncs overlays after scroll:Refresh() already did one through SetScrollPosition, so thats two syncs per resize. theres a comment in scroll.lua mentioning it so you probably know already
- Dominant language
- Lua
- Stars
- 6
- Forks
- 4
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 18
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from PrettyRS/prettyui
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
Maintainers usually reply within 1 day
-
documentation
Difficulty 2/5 1-3 hours Newbie friendliness 63/100
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
All issues in PrettyRS/prettyui
Similar issues
-
bug confirmed discord guide:tyrs-watch locale:enUS navigation v0.3.2
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
fitzforge/polestar#855 · 1 comment ·
Maintainers usually reply within 1 day
-
translation
Difficulty 2/5 1-3 hours Newbie friendliness 64/100
KristanLaimon/PanelsPlus#16 ·
-
Bug
Difficulty 1/5 Under an hour Newbie friendliness 91/100
DennisRas/WeeklyKnowledge#164 ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day