Solid: Why ES6 Proxies?

Created on 6 Oct 2018  路  3Comments  路  Source: ryansolid/solid

Could it be achieved with accessors, and therefore compatible with older browsers? Windows 10 still ships with IE 11, and I bet plenty of people are still not on IE 11.

Is there something specific that they are needed for?

Vue for example, uses getters/setters to make POJO-like simplicity.

question

Most helpful comment

Yeah I'm conscious of that. Mostly that I started this project with the concept of pushing the boundaries of what Proxies can do. I assumed I'd never be IE compatible, and even if it is officially supported until 2025 by Microsoft it would be mostly unusable by 2020. Keep in mind this was 2016 and I admit I was being a bit too optimistic. To me IE and Flash in browsers have a lot in common(everyone knew they were on the way out since ~2012). Although MobX 5 has moved to Proxies too (although they support Getters/Setters as well)

Getters and Setters have a real cost, mostly in handling dynamic properties and arrays. Ironically as my solution moved on most of things that made using Getters and Setters impossible (not polyfillable or extraordinarily unperformant) are no longer in use. Still arrays are a big one and my ImmutableState implementation which admittedly might get deprecated wouldn't work without Proxies (it actually proxies over a completely different data structure than data that is being returned). Truthfully I think I could probably get something working there, but it hasn't been a priority as a single developer working on this project.

Mostly in that I wanted to prove the performance characteristics of Proxies. Solid and Surplus actually have a lot of the same underpinnings in S.js and all the data reconciliation and data mapping and it's only a slight rendering improvement I recently made inspired by DomC/Stage0 that makes it any different. You can technically use Solid renderer without the State object with S.js signals and it would be more performant (and be hard to tell apart from Surplus), so in that sense it's opt in. I actually use Getters on the State object itself, so it's only nested objects that are Proxied. That way I don't need to at the time of set go through every nested object and create Getters. Instead all the work is done at request time if accessed, and with Proxies it's a single handler instead of one per property. Proxies have a real cost but it's the experience I was going for with the API. So Getters and Setters compromise that some and the Cost could be even more so.

Small note on Setters, I actually chose not to have complete POJO like simplicity. And this is obviously an opinion of mine and it would be trivial to make a State version that did. But simple property assignment on deeply mapped data like this can lead to unexpected mutations. From years of developing with KnockoutJS I learned that this is a terrible thing to leave open. MobX also has this problem and introduced Actions and strict mode to prevent it. I didn't want that API overhead and don't have their legacy so I do all changes at the State root object via a function to enforce strict control. It means 2 way binding isn't really a thing possible here for example (I mean yes it's technically possible but would require a fairly convoluted syntax). I think it's a good thing but I can easily understand why people wouldn't just get it. Even though it is based on mutable internals I wanted people to think of the State as immutable and exposed the update API very similar to ImmutableJS. It actually ended up removing the overhead of using Proxy Setters and meant that I could also only need to even use proxies under Gets that were being tracked in Computations. That's a significant overhead reduction and a big part of Solid's performance.

All 3 comments

Yeah I'm conscious of that. Mostly that I started this project with the concept of pushing the boundaries of what Proxies can do. I assumed I'd never be IE compatible, and even if it is officially supported until 2025 by Microsoft it would be mostly unusable by 2020. Keep in mind this was 2016 and I admit I was being a bit too optimistic. To me IE and Flash in browsers have a lot in common(everyone knew they were on the way out since ~2012). Although MobX 5 has moved to Proxies too (although they support Getters/Setters as well)

Getters and Setters have a real cost, mostly in handling dynamic properties and arrays. Ironically as my solution moved on most of things that made using Getters and Setters impossible (not polyfillable or extraordinarily unperformant) are no longer in use. Still arrays are a big one and my ImmutableState implementation which admittedly might get deprecated wouldn't work without Proxies (it actually proxies over a completely different data structure than data that is being returned). Truthfully I think I could probably get something working there, but it hasn't been a priority as a single developer working on this project.

Mostly in that I wanted to prove the performance characteristics of Proxies. Solid and Surplus actually have a lot of the same underpinnings in S.js and all the data reconciliation and data mapping and it's only a slight rendering improvement I recently made inspired by DomC/Stage0 that makes it any different. You can technically use Solid renderer without the State object with S.js signals and it would be more performant (and be hard to tell apart from Surplus), so in that sense it's opt in. I actually use Getters on the State object itself, so it's only nested objects that are Proxied. That way I don't need to at the time of set go through every nested object and create Getters. Instead all the work is done at request time if accessed, and with Proxies it's a single handler instead of one per property. Proxies have a real cost but it's the experience I was going for with the API. So Getters and Setters compromise that some and the Cost could be even more so.

Small note on Setters, I actually chose not to have complete POJO like simplicity. And this is obviously an opinion of mine and it would be trivial to make a State version that did. But simple property assignment on deeply mapped data like this can lead to unexpected mutations. From years of developing with KnockoutJS I learned that this is a terrible thing to leave open. MobX also has this problem and introduced Actions and strict mode to prevent it. I didn't want that API overhead and don't have their legacy so I do all changes at the State root object via a function to enforce strict control. It means 2 way binding isn't really a thing possible here for example (I mean yes it's technically possible but would require a fairly convoluted syntax). I think it's a good thing but I can easily understand why people wouldn't just get it. Even though it is based on mutable internals I wanted people to think of the State as immutable and exposed the update API very similar to ImmutableJS. It actually ended up removing the overhead of using Proxy Setters and meant that I could also only need to even use proxies under Gets that were being tracked in Computations. That's a significant overhead reduction and a big part of Solid's performance.

Thanks for that insight!

That brings up the other discussion I was gonna open: https://github.com/ryansolid/solid/issues/3

This comment while conveying the same idealogical truth is now out of date with how it works in 0.3.x and above. People should refer to current documentation.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jcuenod picture jcuenod  路  7Comments

trusktr picture trusktr  路  5Comments

tehdarthvid picture tehdarthvid  路  5Comments

Yakulu picture Yakulu  路  4Comments

praneybehl picture praneybehl  路  6Comments