I’ve started on a little open source passion project to make yet another online Sudoku app using client-side Blazor (WASM). I chose Blazor specifically so I can eventually integrate my Sudoku solver, which is written in C#, and because the tech intrigued me and I felt I should try to learn it. I’m avoiding server side Blazor so that I can host it as a static page on GitHub.

It’s on github here: https://github.com/dclamage/Sudoku
You can see it live here: https://dclamage.github.io/Sudoku/
Most of the code I’ve written is in Pages/Index.razor
It’s in a very early stage with basically just a few hours work at this point. All you can do is multi-select cells by clicking or dragging the mouse, and type 1-9 to fill numbers (or 0 or delete to erase them).

However, before I extend the functionality further and implement more features, I’m already experiencing some pains and want to make sure I’m taking this in the correct direction.

My main concerns are:
Performance. I’ve already noticed that things like clicking and dragging can be a bit sluggish or unresponsive. I imagine this will only get worse if I don’t nip the problem in the bud. I expect I’m doing something wrong here, where it happens to work but it’s not properly designed or idiomatic for Blazor. I especially want to make sure that the app runs well on mobile devices.

Scalability and project management. I’m not really sure where to put C# source-code but I expect I haven’t done it right, having most of it straight in a @code block in Index.razor. Any advice on how to organize the razor files, C# source, and general project structure would be nice.

I’m happy to take any general advice, code review, or even pull requests if there something that’s easier for you to do yourself.
Thanks!

Ok so I took a quick look and the key improvements you want to make are:
Move the classes to their own files, make a Models folder and just put them there, you want your logic to be separated from your models.

Move the logic from the @code block to an abstract class, it’s very simple to do, we call it “code behind” in the blazor world, and all you have to do is make a new class called index.razor.cs, make it partial, inherit from ComponentBase, add the namespace with Ctrl ., copy and paste the code from the block to your new class, boom, now you UI code is separated from your logic code.

Add @key in your for each, that’ll make it muuuuuuch more performant, because it’ll only change the elements that actually need to change instead of re-rendering all of them every time.

Follow those 3 and you should have much cleaner and faster app in an hour or 2 tops, this is very basic but it’ll do the trick for now, let me know if you have any additional questions.

Nice beard btw.
Totally agree with this. Nothing to add. Also feel the need to compliment OP’s beard.
Interested/curious to understand your reasons for #2. Why separate the code into a separate file from the UI? I’m still trying to figure our why people would want the code in a codebehind file, when to me it’s way more convenient and natural to have it all in one file (assuming you just have UI code there and move your actual logic into model classes that live elsewhere, so you don’t end up with thousand-line @code sections for a 20 line UI layout).

Thanks! I’ll try out these suggestions and see how it goes!
I’ll have to look up what @key is, because I haven’t seen that yet. Are the docs sufficient or do you have anything to add example-wise for that?
I’d turn text and rect into components and move their rendering logic to their respective classes. Actually, since a text can only appear in a rect, I’d have just one component for both. This should help cleanup the index page.

Another thing would be to create a record type that represents the game state and from which you derive all your rendering logic, this would go handy later on if you want to for example save/restore a game or add more information such as score/dashboard or whatever. Also I’d try to come up with more high level events, transforming mouse up/down events into domain events that can drive the changes in the game state.

source