Performance issues when used with lots of DOM elements #1417
Replies: 25 comments 2 replies
-
Have you tried placing the Alpine script in the |
Beta Was this translation helpful? Give feedback.
-
Thanks @ryangjchandler for your quick reply! I updated the initial post and moved Alpine to the end of |
Beta Was this translation helpful? Give feedback.
-
It might be worth looking at the waterfall in DevTools to see which part is taking the longest. |
Beta Was this translation helpful? Give feedback.
-
It's not a request issue, the responses are back quickly. However, if Alpine is used, the diagram takes much longer to render. |
Beta Was this translation helpful? Give feedback.
-
There's no way of ignoring an element at the moment. There have been various discussions about an |
Beta Was this translation helpful? Give feedback.
-
OK, I found #395. @calebporzio writes "The issue mentions x-ignore saving resources, and this is only true for x-ignore used within an Alpine component if it's used outside of one, that DOM will never get walked anyways" - isn't that what I experience right now? It's not in an Alpine component but still gets walked. |
Beta Was this translation helpful? Give feedback.
-
Yeah, I hadn't noticed in your case you don't actually have any components at all. I'm curious now. It could be that Alpine's I didn't notice much of a difference on my MacBook between each example, but on slower machines I'm not sure. |
Beta Was this translation helpful? Give feedback.
-
Yes, I didn't see it on my Mac neither, but users complained. Now on an old Windows laptop I have 3s (without Alpine) vs. 11s (with Alpine). The problem is that I completely rebuilt an existing version of the software with Livewire/Alpine - and now it feels much slower for the user. Kinda hard to convince them that "everything is better now". Might well be the |
Beta Was this translation helpful? Give feedback.
-
can you defer alpine after the graph has shown? would it help? <script>
window.deferLoadingAlpine = function (callback) {
let modeler = new BpmnJS({
container: '#canvas',
});
axios.get('https://nanuc.io/alpine-performance/example.xml')
.then(function (response) {
modeler.importXML(response.data);
callback();
});
}
</script> |
Beta Was this translation helpful? Give feedback.
-
I don't think will make a difference, since that querySelectorAll will still run either way. |
Beta Was this translation helpful? Give feedback.
-
yeah but it will run after (hopefully) you get the response and show the graph so you won't perceive the slowness |
Beta Was this translation helpful? Give feedback.
-
Be careful using the |
Beta Was this translation helpful? Give feedback.
-
Actually for this particular use case using I will try this in the actual (and much more complex) application (with around 30 different Livewire components being active at the same time...) and see what happens there... My only other and very ugly idea is to outsource the tree diagram to an iFrame - it sends cold shivers up and down my spine just saying it... |
Beta Was this translation helpful? Give feedback.
-
I'm also seeing this, and I think closing #395 was a mistake. Having to walk a large DOM tree when you know there are no Alpine components is wasteful. |
Beta Was this translation helpful? Give feedback.
-
Sure, but the problem isn't Alpine walking the DOM. It will only do that when The performance problems appear to be coming from |
Beta Was this translation helpful? Give feedback.
-
Seems to me a
I think const rootEls = document.querySelectorAll('[x-data]');
rootEls.forEach(rootEl => {
// Detect ignore element and return if we hit one
if (rootEl.parentElement.closest('[x-ignore]:not([x-ignore=false])')) return
callback(rootEl)
}) if node has an |
Beta Was this translation helpful? Give feedback.
-
Just a quick feedback from my side: I would really like if an approach would be found to have Alpine ignore certain parts of the applications completely. Unfortunately my JavaScript skills are way to little to dive into this myself (that's why I went for Livewire and therefore Alpine initially) - but I'm absolutely willing to test. |
Beta Was this translation helpful? Give feedback.
-
@SebastianSchoeps Like I mentioned, Livewire also relies on the |
Beta Was this translation helpful? Give feedback.
-
@ryangjchandler Yes - I just thought it was worth a shot. |
Beta Was this translation helpful? Give feedback.
-
You could work around it still, using the Simply check for an existing |
Beta Was this translation helpful? Give feedback.
-
What's the latest on this? Have you been able to use In order to not overwrite other libraries attempting to defer Alpine initialisation, you could do (as per Ryan's Spruce example) <script>
const deferrer = window.deferLoadingAlpine || function (callback) { callback() }
window.deferLoadingAlpine = function (callback) {
let modeler = new BpmnJS({
container: '#canvas',
});
axios.get('https://nanuc.io/alpine-performance/example.xml')
.then(function (response) {
modeler.importXML(response.data);
deferrer(callback);
});
}
</script> If the issue is with |
Beta Was this translation helpful? Give feedback.
-
Have this issue when switching pages between a large page and small swupjs the large page takes an age 11s+ compared to 3ms without Alpinejs tried the deferLoadingAlpine without any success anyone had any other luck ? |
Beta Was this translation helpful? Give feedback.
-
What if you have a single Alpine element? Would a slow-device-user loading a page with +3k dom elements have to wait for |
Beta Was this translation helpful? Give feedback.
-
@SebastianSchoeps Two questions for you:
|
Beta Was this translation helpful? Give feedback.
-
Looks like the |
Beta Was this translation helpful? Give feedback.
-
Update after some digging of different people (thanks!) into the issue:
Just by embedding Alpine.js (without even using it) the performance gets slow when using "many" DOM elements. "Many" depends on the computer's performance - in my case the rendering took 11s (with Alpine) vs. 3s (without Alpine) for 3,000 DOM elements on an old i5-3210M I had available.
This is caused by Alpine using
querySelectorAll
and iterating over all elements.A workaround is possible by using
deferLoadingAlpine
.I run into strange issues when using Alpine with bpmn-js (https://github.com/bpmn-io/bpmn-js). Just by embedding Alpine the performance for loading a tree model goes down from 2s to 8s (on a slow computer).
I created two examples:
https://nanuc.io/alpine-performance/with-alpine.html
https://nanuc.io/alpine-performance/without-alpine.html
The only difference is that at the first example Alpine is embedded (see below).
I know that this is a very specific use case that probably no one else on this world has encountered yet... I'm reporting it anyway because it might be the case that Alpine affects the performance of other libraries too.
Unfortunately the only solution for me seems to replace Alpine by something else for now because my knowledge to dive into this and solve this is far too little.
Sebastian
Beta Was this translation helpful? Give feedback.
All reactions