Problems changing the value of a reactive signal returned from a function

I was testing what would happen if I changed the entire value of the board, not the squares but the entire board, in case at some point I want to change the board. And I saw that if I change the value of the board, the anonymous function "loadBoard.get("chess_standard_8x8")();" is executed again. But I don't understand why this happens or how to solve it.
38 Replies
SleepPolar
SleepPolarOP8mo ago
I tried creating a constant outside the component and calling it inside. And now it works correctly. But I don't understand why, could someone explain to me?
REEEEE
REEEEE8mo ago
Reading signals inside functions can create derived signals For example,
const [count, setCount] = createSignal(0)

const doubleCount = () => count() * 2

createEffect(() => {
console.log(doubleCount())
})
const [count, setCount] = createSignal(0)

const doubleCount = () => count() * 2

createEffect(() => {
console.log(doubleCount())
})
Now, if you read doubleCount in a reactive scope and count is updated, doubleCount will also be updated. In the example, the createEffect will log whenever the count changes In this case, I'm not too sure why it's rerunning but I would untrack your reads of board in addPiece
SleepPolar
SleepPolarOP8mo ago
I understand, and that solution I found also works, or would it be something bad? Do you know if we could untrack the addPiece function that I returned. It's just that I'm not convinced that it does an untrack every time the addPiece is called, it would be good if the addPiece was already untrackable
edygar
edygar8mo ago
I found createStore to be very convenient for handling these kind nested signals. Like (sorry, the code is a bit messy) here: https://github.com/edygar/minesweeper https://github.com/edygar/puzzle
GitHub
GitHub - edygar/minesweeper: Simple minesweeper
Simple minesweeper. Contribute to edygar/minesweeper development by creating an account on GitHub.
GitHub
GitHub - edygar/puzzle: A simple puzzle made using solidjs+tailwind
A simple puzzle made using solidjs+tailwind. Contribute to edygar/puzzle development by creating an account on GitHub.
SleepPolar
SleepPolarOP8mo ago
Good projects, I liked the minesweeper one. Although I didn't understand what createStore does. And why should I use it in my case?
edygar
edygar8mo ago
It's up to you, but I find it easier to let the store handle the whole matrix, while reading, you are spared from calling the signals such as board[0](), if board was a store, all it would take would be board[0]. Also, the update function has a lot of useful things like: update members of an array with a filter function; a range and things like that; you can read more on https://docs.solidjs.com/concepts/stores#path-syntax-flexibility Summing up, the code is more concise, and still have the read / write segregation
SleepPolar
SleepPolarOP8mo ago
I tried to create the Store in my case, but I couldn't 😅
REEEEE
REEEEE8mo ago
You can untrack basically everything
SleepPolar
SleepPolarOP8mo ago
I tried to untrack the function but it gave me an error, maybe I did it wrong.
REEEEE
REEEEE8mo ago
You do it the same way you did before. Just don't forget to add the return so that your createAddPiece actually returns something
SleepPolar
SleepPolarOP8mo ago
But I realized something. I can return the board without it being a Signal, and the returned board I convert to a Signal, and there is no need to untrack.
REEEEE
REEEEE8mo ago
Yeah that works too
SleepPolar
SleepPolarOP8mo ago
this?
REEEEE
REEEEE8mo ago
Close Just wrap what you had originally in untrack(()=>
SleepPolar
SleepPolarOP8mo ago
I don't get it
REEEEE
REEEEE8mo ago
return untrack(() => function(piece, [i, j]){
...
}
return untrack(() => function(piece, [i, j]){
...
}
SleepPolar
SleepPolarOP8mo ago
I had tried that, but it doesn't seem to work because it keeps tracking it. Maybe you can't untrack a function 🤔
SleepPolar
SleepPolarOP8mo ago
@edygar I have managed to create the 'Storage'. I decided to use CreateMutable because I find it easier and more convenient to change object variables. Although on the internet they recommend using CreateStorage more, but I guess CreateMutable is not bad.
No description
SleepPolar
SleepPolarOP8mo ago
this is how it looks 😁
edygar
edygar8mo ago
In general there’s a performance gap in between them both, but let’s be real, the difference is waaaay to small for you to concern, it’s still orders of magnitude faster than React And the code is very readable now The only downside for createMutable is that in an application, passing around this ref is exposing your state to 3rd party components that my mutate your state without you knowing about it, but that’s on a large scale app
SleepPolar
SleepPolarOP8mo ago
I don't understand it, can you give me a small example? That's true 😅
edygar
edygar8mo ago
Imagine now you grab a 3rd party component and pass the board as property. If they mutate your board, it will update the screen, but how are you going to reason about it other than looking the component’s code?
SleepPolar
SleepPolarOP8mo ago
I am new at this. What does a third-party component mean? I think I understood, with third-party component you mean like a library to add to my project, and that this library has a component and that if I pass the board as a parameter, if it modifies the value of the board from the other component, it would be modifying the state of my current component? Is that?
edygar
edygar8mo ago
Exactly, the worst part is not knowing what’s causing some update. Again, in your case I don’t think it will ever be the case
SleepPolar
SleepPolarOP8mo ago
It's good to keep that in mind Regarding this message, it mentions a performance gap between the two, just out of curiosity which one would have better performance and why? I try to search on the internet but I didn't find any performance comparison.
SleepPolar
SleepPolarOP8mo ago
I think I understood: Solid/store, both createMutable and createStore, resort to wrapping the object/array with a Proxy, and that has an additional performance cost. This is because the Proxy intercepts read and write operations, executing additional code each time a property is accessed or modified, which introduces overhead. And the overhead depends on the code that is executed in the Proxy's setter and getter interceptors. But even though it has an overhead, you said it was very little, and with the benefit it has in terms of ease of use, it is better to use createStore and createMutable instead of using a createSignal (for cases like this) Regarding the benchmark, I did not understand the information very well, I do not see the part in which the performance of both is compared 😅. (It doesn't matter though, I was just curious.)
edygar
edygar8mo ago
No description
No description
edygar
edygar8mo ago
Vanilla is the most optimized way, solid createSignal gets reaaaaaaally close to it, with store you lose just a bit, but when you compare to react, there’s no reason for concerns
SleepPolar
SleepPolarOP8mo ago
Thanks for the images, now I understand it better. One last question. Can you recommend me a page where I can do a benchmark, there are many and I don't know if all of them are good, or how do you do the benchmarks? I wanted to make a benchmark of: this.data[byte] |= 1 << bitIndex; //The maximum bitIndex value would be 8 (1byte) this.data[byte] |= BIT_MASKS[bitIndex]; //The maximum bitIndex value would be 8 (1byte). BIT_MASKS is a Uint8Array I know that probably if there is a difference, the difference will be very small, but since the bot will have to do a lot of iterations, I wanted to do a test to see.
edygar
edygar8mo ago
The problem with benchmarks is not what we measure but rather what we miss to measure. xD So besides the CPU time, you should measure the pressure on the GC. Having that said, xD I've no idea, the benchmark I usually do is just the DevTools' ones, Lighthouse+memory snapshots.
SleepPolar
SleepPolarOP8mo ago
I tried iterating both to see how long they lasted. And it was faster: "this.data[byte] |= 1 << bitIndex;". But it seems strange to me that this is faster than using a MASK, if from what I saw on the internet the MASK is used to avoid the "1 << bitIndex", perhaps it is that since the bit offset is up to where bitIndex says, and the maximum value of bitIndex is 8 (1 byte) so it is faster than accessing the MASK element. I have no idea 🤣
peerreynders
peerreynders8mo ago
Hypothetically bit operations can be done directly in a CPU register which is the fastest operation there is (“hypothetically” because … JS). Using BIT_MASKS forces a memory lookup which is comparatively slow. ref Data-Oriented Design (Or Why You Might Be Shooting Yourself in The Foot With OOP) (2009)
No description
SleepPolar
SleepPolarOP8mo ago
That's what I assumed, thanks for confirming it. And About Data-Oriented Design. It's something like this?
const person = {
name: 'Mary',
age: 25
};

function printInformation(person) {
console.log(`Name: ${person.name}, Age: ${person.age}`);
}

printInformation(person);
const person = {
name: 'Mary',
age: 25
};

function printInformation(person) {
console.log(`Name: ${person.name}, Age: ${person.age}`);
}

printInformation(person);
peerreynders
peerreynders8mo ago
The problem goes a lot deeper than that and given that JS has no control over memory layout it's not an issue that can be addressed within its purview. The closest to the metal you can get is the JS runtime (V8, JavaScriptCore, SpiderMonkey) and the Web API; so the goal is to have as little JavaScript between what you are trying to accomplish and the JS engine; so every dependency better earn its keep. If you want to benefit from ECS you'd likely have to choose a systems language compiling to WASM which comes with it's own, unique set of problems just to get the potential benefit of staying within the same cache line.
Medium
Entities, components and systems
What you need to know about ECS and game development
tree-shaking, the horticulturally misguided algorithm — wingolog
wingolog: article: tree-shaking, the horticulturally misguided algorithm
What's wrong?
What's wrong?
SleepPolar
SleepPolarOP8mo ago
Thank you for the explanation. I see that it has potential benefits in terms of performance and memory, although I believe that in my case it would be better to keep my BitBoard in JavaScript. Currently, I don't have practical knowledge about those topics, and it could be a significant challenge to implement them correctly. If in the future I find it to be too slow and I want to improve it even further, I will try to take it into account.
peerreynders
peerreynders8mo ago
The point wasn't to dissuade you from using JS.
Both JavaScript and WebAssembly have the same peak performance. They are equally fast. But it is much easier to stay on the fast path with WebAssembly than it is with JavaScript. …
https://youtu.be/njt-Qzw0mVY?t=1064 You may like Proxx (github) related content https://web.dev/articles/proxx-announce https://youtu.be/TsTt7Tja30Q
Chrome for Developers
YouTube
WebAssembly for Web Developers (Google I/O ’19)
WebAssembly is often hailed as a performance tool for critical tasks or to bring existing C++ code bases to the web – such as games. But WebAssembly is so much more. You can use WebAssembly as a puzzle piece to give the web platform the few missing capability that you are missing or to surgically replace a JavaScript bottleneck. Watch more #io1...
PROXX — a game of proximity
PROXX — a game of proximity
Help your crew navigate space by marking out the black holes using proxx, your proximity scanner.
web.dev
Introducing PROXX  |  Articles  |  web.dev
PROXX as a minesweeper-like game built as a PWA. It works on a vast variety of devices and progressively enhances the visual appearance the more capable the device is.
Jamstack TV
YouTube
Jake Archibald & Surma - Setting up a static render in 30 minutes
In this session, Surma & Jake will take a JS-driven app and give it a static render, massively improving the time to first render, and time to interactive. They'll go through the useful build tools, and show how to avoid all the gotchas. Recorded at JAMstack_conf_london 2019. Learn about upcoming dates and locations at https://www.jamstackconf.com
SleepPolar
SleepPolarOP8mo ago
With that video it became clearer to me.
Want results from more Discord servers?
Add your server