First, let me start with all the reasons why I prefer this over other famous JAVASCRIPT tech stacks..
I hate "Javascript for everything" trend.. Yea.. Javascript can do pretty much anything at this point.. BUTT, is it effective in doing that?
Let's take an example of a very intensive CPU bound task. This is a code sample that simulates CPU intensive task. And let's see how Javascript performs.
Reason 1: Javascript sucks at CPU bound tasks!
setTimeout(function() {
console.log("Hello world")
}, 1000)
const startTime = Date.now();
while (Date.now() - startTime < 3000) {} //Simulating a long CPU intensive main thread task..
console.log("End")
So, what do we have here? Me, as a user of JAVASCRIPT would expect to see
"hello world"
printed out after 1 second.. And guess what. It dosen't. It spits out"hello world"
after 3 seconds..Why does this happen? To understand this, we need to understand how event loop in browsers and node js works. In simple terms, the event loop checks the call stack and the callback queues at the same time. The callback function that we pass in the
setTimeout()
will get into the callback queue once the timer is done with 1000ms.But guess what... The callstack is not empty when the timer is done with it's work.. Its still busy performing the 3 seconds CPU intensive task we wrote(Yea.. Its a simulation.. Not a real world dumb program that takes 3 seconds to do whatever its intending to do).
So, the callback functions in the callback queue and the microtask queue would starve.. Poor callback functions. They only get the chance to get into the callstack after 3 seconds.. And that's the reason why we see the
"hello world"
being printed out after 3 seconds even tho I specified 1000ms.
Yea. This is a random image of the event loop I downloaded from the web.. Cool Image.
Let's take a Go code that does the excat same..
package main
import (
"fmt"
"time"
)
func main() {
time.AfterFunc(1*time.Second, func() {
fmt.Println("Hello world")
})
// Simulating a long CPU-intensive main thread task
startTime := time.Now()
for time.Since(startTime) < 3*time.Second {
}
print("End")
}
Here, the "hello world"
gets printed out after 1 second.. How? Because the AfterFunc()
is running on its own GoRoutine which has no business in interfering with the main GoRoutine..
Reason 2: I personally hate client side rendering..
Let's talk about reactJS. It pushes the javascript components to the client and shoves the client's throat with so many things that the clients start to throttle..
Imagine a low end PC making a request for some static HTML file, and you get a bunch load of react component shits.. How would the client feel? It gets slow.. The browser has to parse the javascript, execute the virtual DOM, generate the HTML out of it.. And what not..
The browser is doing all the work that the server has to do..
Remember the NATURAL FLOW OF WEB?
First load the HTML, only then load the javascript? Why? To make the initial paint as fast as possible.. Remember the days when we load the javascript in the footer of the HTML documemt?
React just made the entire flow upside down.
And in result, the client has to stare at a blank white screen for a solid amount of time..
With the reasons being said..
- I am choosing 2 languages that shines in their own world..
Go
The thing that straight up impressed me was that Go is a compiled language and is statically typed.. You can blindly say, Go is super fast and is a lot faster than javascript..
It has inbuild light weight threads called "GoRoutines" which is a lot faster than actual OS threads as the Go threads are light weight.
Go can be used to build RESTful endpoints or can be used for any backend service..
BUTT, I cannot use Go for SSR.. PHP shines in that.. In my stack, Go will be heavily used for CPU intensive API's or any backend service.
PHP
PHP is the best thing I ever used for SSR. Simple and very straight forward. Creates a process for each client.. Makes it kind of slow. But still these processes are independent of each other unlike threads that will share the same process memory space and is bad for race conditions and a lot other thread related issues..
PHP is also tightly coupled with the web in my opinion.. The straight out of the box superGlobal variables like
$_GET
,$_SERVER
, etc.. which makes it easier to work with the web in general..The session management in PHP is just too good.. Comes with the language itself.. And is too easy to manage the sessions..
Conclusion:
PHP can be purely used for SSR. And session management. I can't trust PHP for doing CPU intensive tasks as it sucks in that. Why? Its an interpreted language and its also not multithreaded..
So, I offload all the CPU intensive calls to Go.
Best of two worlds.. PHP for SSR, so that the client wouldn't suffer and Go for CPU intensive tasks because it can do concurrency so well...
Top comments (0)