The answer what is the most user-friendly is always it depends.
Depends on a lot of factors the main one is who is your target audience? What is their knowledge and mental models.
For this example, as I have no idea about the context of the action, I would recommend thinking about few things:
- What action that user took? (action)
- What did they expect to happen? (knowledge)
- Is their expectation different from the system behaviour (gap)
- Close the gap by providing feedback to the user (understanding)
For your example
[click]↖ => [click] ↖⚙ - Mouse cursor changes to system busy spinner cursor
[click] => ⚙ - Busy spinner replaces button entirely
- Why did the button disappear?
[click] => [ ⚙ ] - Busy spinner replaces button text
- This to me seems like an ok solution, though this is only my opinion. Also this approach assumes that the user will know what this spinning thing means.
[click] => [click ⚙] - Busy spinner appears inside button
- Can the user click the button again? What will happen if they will?
[click] => [click] ⚙ - Busy spinner appears outside button
- Can the user click the button again? What will happen if they will?
[click] => [⚙ please wait...] - Busy spinner replaces button text, accompanied by text
- Good solution as the user has feedback that something is happening and they need to wait. Can they click the button at this point? What will happen if they will?
[click] => ⚙ please wait... - Busy spinner replaces button entirely, accompanied by text
- Where did the button go? Did I break it? Oh yeah I need to wait...
In my opinion the 3rd and 6th options are the best, but I would suggest either finding some studies about this or performing a usability testing and seeing how your users react to these different approaches.