Nginx was starting to get popular and overtake Apache on installs, and people were enamored with its performance and idea of “no blocking, ever” and “callbacks for everything”, which the nginx codebase sorta takes to the extreme. The c10k problem and all that.
When JavaScript got a good engine in v8, Node was lauded as this way to do what nginx was doing, but automatically and by default: you simply couldn’t write blocking code so waiting on I/O will never bottleneck your incoming connections. Maximum concurrency because your web server could go right back to serving the next request concurrently while any I/O was happening. But no “real” multithreading so you didn’t have to worry about mutexes or anything. I remember being slightly jealous of that as a Rails developer, because webrick/unicorn/etc had a worker pool and every worker could only handle one request at a time, and fixing that could only happen if everything was async, which it basically wasn’t.
JavaScript becoming a popular language in its own right due to frontend was certainly the most important factor, but it wasn’t the only one.