htmx icon indicating copy to clipboard operation
htmx copied to clipboard

Way too many `oobAfterSwap` events being dispatched?

Open collinthefarmer opened this issue 2 years ago • 2 comments

Hi HTMX, long time listener, first time caller.

I noticed some weird behavior when trying to process a lot of OOB swaps where the triggerEvent function seems to be getting called way too many times.

// htmx.js

/**
         *
         * @param {string} oobValue
         * @param {HTMLElement} oobElement
         * @param {*} settleInfo
         * @returns
         */
        function oobSwap(oobValue, oobElement, settleInfo) {
           ...
            if (targets) {
                forEach(
                    targets,
                    function (target) {
                        ...
                        forEach(settleInfo.elts, function (elt) { // <<< here
                            triggerEvent(elt, 'htmx:oobAfterSwap', beforeSwapDetails);
                        });
                    }
                    ...
}

I ran some tests, and for a single request containing 1,000 unique OOB swaps triggerEvent is being called over 500K times, with the majority of those calls dispatching events for the same elements. This winds up taking a massive amount of time for each swap and definitely doesn't seem like the intended behavior for anyone trying to listen for the event itself.

I set up a repo to quickly demonstrate this behavior here.

But the gist is:

<-- index.html -->

<button hx-swap="none" hx-get="/update" hx-trigger="click">
    swap
</button>
<div id="i1"></div>
<div id="i2"></div>
...
<div id="i1000"></div>

swapping in:

<-- update.html -->

<div hx-swap-oob="true" id="i1"></div>
<div hx-swap-oob="true" id="i2"></div>
<div hx-swap-oob="true" id="i3"></div>
...
<div id="i1000"></div>

causes the behavior I've described.

collinthefarmer avatar Sep 19 '23 03:09 collinthefarmer