Because rendering in a Node process is more complicated when async state is involved - using a browser eliminates that complexity. For simpler apps without any async state (AJAX or WebSockets), a Node process may suffice.
For example: you load the app in your headless browser and let it load as would in any browser. The browser fires some events and XHR/WebSocket requests and you can cleanly wait for them to finish as opposed to doing something like this: https://techbrunch.gousto.co.uk/2016/10/10/isomorphic-react-... which requires you to do some extra configuration in your app to help support a Node environment.
TL;DR: ReactDOMServer.renderToString won't wait for your async requests to finish, you need them to execute and finish before you call renderToString
If you care about performance you should design an architecture where it's possible to determine exactly which parts should and can be executed on the server.