It's complicated because it's almost impossible to come up with a good number for a results based project that isn't trivial. That would be "good" in the sense of it makes sense for both the freelancer and the person hiring you where in the end both of you are happy and want to work together again in the future.
Results oriented payments sets you up to start hating what you're doing if your estimate was a bit off where you need to work more hours than you thought. Suddenly you find yourself working much longer and it feels like "damn it, why won't this gig end already -- this is such an inefficient use of my time", or if the estimate is off in the other direction the person hiring you might feel like they overpaid (even if you slam dunked the project it's still a negative).
But hourly by itself isn't close to perfect either. Hourly sets you up to become a "wage worker" where you get punished for being a master of your craft, because if you invested a lot of time off the clock to improve then suddenly you're getting paid less because you finish your work faster.
A prime example is, let's say you have an iron clad user registration system written that you made for a side project on your own time and it took 25 hours. You have great test coverage, it works perfectly and it's pretty easy to plop it into another project and customize it.
So now a client hires you to make them an app that requires a user registration system. Now you can implement that into their code base in literally 5 minutes because you have a project skeleton to start your app off with, vs starting at ground zero.
This is where the problem starts. If you charge $100 an hour, you just "lost" $2,500 because now you finished something that took you 25 hours on your unbilled time in 5 minutes.
So what do you do? Do you hide that aspect from your client and bill them somewhere between 15-25 extra hours and then try to come off like a hero where you contact them in 3 days with a progress report with the user system in place? That 15-25 number is something you decide on the fly with a thought process of "well, I invested the time and continue to maintain this feature on my own time, I should be able to bill for that and re-use it for 5, 10 or 50 clients over the next few years".
Or do you not do that but instead drastically raise your rates but let them know you can finish things faster because you have years worth of license free personal code you've written?
What if you step back and use another example of investing 200 hours into tweaking your development environment to the point where you can actually finish real work faster than someone who didn't, so now on a 200 hour project you can legit finish things in 180 hours (a 10% increase isn't unreasonable IMO). How do you factor that in other than raising your rates?
All of these things are complicated questions. I typically go with hourly based rates but I'm also transparent with my clients when it comes to implementing things I already have code for. I let them know they are getting a huge discount by not having me implement this thing from scratch and in turn we decide on a fair figure on the spot (on a per client / per project basis).
But for things like general skills that make me faster at coding, I raise my base rates. Nothing wrong with doing that. If I can finish things faster then it's a benefit to everyone. The client gets their work done faster, I gain hours back from my life in the long run and I have an incentive to continue becoming better at my craft.