I guess it was just a matter of implementing it, no real issues with performance once I did the basic obvious optimisation.
That's more of an Advent of Code problem (derogatory) than a Project Euler problem.
It was fairly fast, but not fast enough to be run many times during puzzle generation without taking like a minute to generate a puzzle.
I might have to settle for locally pregenerated puzzles, which I think is the usual tradeoff everyone else makes.
Sudoku.js made another tradeoff, but a horrible one that completely compromises the reliability of the algorithm, seems pointless.
Or maybe I could just improve the algorithm, I could do more, for instance I didn't use any complex Sudoku strategies before I started guessing.
Someone in the forum posted some more difficult puzzles, and my algorithm is way slower on those.
But it seems like there's still room to improve.
I also didn't use much memory because I just wanted to get something that worked even if it was slow.