This site works best with JavaScript enabled. Please enable JavaScript to get the best experience from this site.
Client: WoW Classic — Mists of Pandaria (5.5.x). Likely relevant to any client where certain events fire in bursts within a single frame.
On some events, the client fires many redundant events within a single frame, and LibActionButton currently reacts to each one by iterating the button set and running work immediately. The worst offender in my case is toggling a form/shapeshift (Warlock Metamorphosis), which within one frame produces:
ACTIONBAR_SLOT_CHANGED
SPELL_UPDATE_ICON
ForAllButtons(Update, true)
ACTIONBAR_UPDATE_STATE
ACTIONBAR_UPDATE_USABLE
ACTIONBAR_UPDATE_COOLDOWN
SPELL_UPDATE_USABLE
SPELL_UPDATE_COOLDOWN
SPELLS_CHANGED
Update() is the heaviest function in the lib (icon/glow/cooldown, secure Execute for OnStateChanged, and the OnButtonUpdate callback that Masque and glow addons listen to), so running it 11× per frame, plus several more full sweeps for the cooldown/usable/state events, produces a visible hitch on every form toggle. scriptProfile attributed ~20 ms of Lua to the lib during the toggle on top of engine-side work.
Update()
Execute
OnStateChanged
OnButtonUpdate
scriptProfile
Coalesce these bursty events: instead of doing the work inline in OnEvent, set a flag and perform the actual update once in the next OnUpdate tick. A one-frame delay is visually imperceptible, and 11 full sweeps collapse into 1. This is a drop-in change — no API or behavior change, buttons end up in the same state, just updated once per frame instead of N times.
OnEvent
OnUpdate
Concretely:
iconUpdatePending
button.icon:SetTexture(button:GetTexture())
Update
dirtySlots
fullUpdatePending
arg1 == 0
SPELL_UPDATE_CHARGES
pendingLight[event]
SPELL_FLYOUT_UPDATE
UpdateFlyoutSpells()
If a full update runs in a given frame, the lighter pending flags for that frame are cleared, since the full Update already covers state/usable/cooldown/count/icon.
Combined with an unrelated Bartender4 fix (the button.bar = nil stall, now fixed upstream), the per-toggle freeze went from ~0.6–0.7 s down to a barely-perceptible dip. The LAB portion of the work dropped from 11 full button sweeps to 1 per frame. No visual regressions observed: icons swap correctly on form change, mana/range desaturation, cooldown swipes, and charge counts all update as before.
button.bar = nil
To post a comment, please login or register a new account.