Alpine: Problems using x-for and sorting

Created on 26 Jan 2020  路  7Comments  路  Source: alpinejs/alpine

I'm probably missing something here: https://codepen.io/jespr/pen/qBEvMQW

But if you click on Name, then age, then Name, then Age rapidly after each other the whole page ends up hanging and there's a message in the console about setTimeout internally in Alpine.js taking XXX amount of ms:

[Violation] 'setTimeout' handler took 149ms

What am I doing wrong? :)

Most helpful comment

Most likely at some point, let鈥檚 allow some time for them to talk over the right solution - you can use the version of alpine SimoTod is using in the codepen @Wulfheart until this gets merged

All 7 comments

It looks like an unexpected side effect of the x-for directive combined to the Alpine implementation for the proxy handler.

Since each element of your array is an object, accessing the property doesn't return the element but it returns a proxy instance wrapping the element itself.

Sort "gets" all the elements (which are now wrapped in proxy objects), compares them and builds a new sorted array using proxies rather than the original objects. Once done, the JS engine replaces the original array with the new one so, after the first iteration, the array doesn't contain simple objects but proxy-wrapped objects.

At each call, since a proxy is an object, Alpine wraps them inside other proxies and go on. It means that, at each access, the function becomes slower, heavier in memory and it eventually will be flagged as an error by your browsers.

We should try to understand if a property is already an object at https://github.com/alpinejs/alpine/blob/cfb5548be847e281084bc38212f40b81f870a91c/src/component.js#L103 and simply return it but the fix won't be straight forward since, by specs, it's not possible to tell a proxy apart from the object it contains.

Any ideas?

cc @calebporzio

A flag to signal if the data is already a proxy, it's already being done for $refs with isRefsProxy.

Yeah, I'm not sure I like that workaround but, without a better alternative, I opted for something similar.

Magic property names probably need fixing (not sure about the preferred syntax) ~and I couldn't write a regression test for it (same reason, it's hard to identify a proxy object) but it should fix the issue~ (I remembered that the test suite runs in node and I managed to write a regression test as well).

I've patched the set trap because I think we should prevent proxy objects from being set by mistake rather then fixing the next access.

Here's a codepen using the updated version which seems to work: https://codepen.io/SimoTod/pen/yLywwNN

That seems to fixe the issues, great @SimoTod :)

Will this solution get merged?

Most likely at some point, let鈥檚 allow some time for them to talk over the right solution - you can use the version of alpine SimoTod is using in the codepen @Wulfheart until this gets merged

Fix is available in v1.9.7 Thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

BernhardBaumrock picture BernhardBaumrock  路  3Comments

andruu picture andruu  路  3Comments

adinata-id picture adinata-id  路  4Comments

mikemartin picture mikemartin  路  3Comments

aolko picture aolko  路  5Comments