Closed4

TypeScript (Node.js) vs Golang for web backend development

Taichi MasuyamaTaichi Masuyama

資料

何を知りたい?

  • いつ TS/Go を選ぶのか?
    • パフォーマンス観点
    • マイクロサービスとの相性

動画v1を見る

所感

一貫して中立で話してるけど、tRPC を推してる時の感情の入り方がすごい。それだけ tRPC の開発体験はいいってことか。
Golang はシンプルといいつつも、並列処理をいろんな書き方ができて統一感持たせるのが課題と言っている。(トレードオフととらえる)

動画内で出てきた比較表

Reference: https://youtu.be/0WRUroxYQp4

Go Backends TypeScript Backends
Pros Insane Speed Incredibly easy to develop in NextJS/TRPC make it easy and fast to build full stack apps
Lightweight Massive package ecosystem
Easy to use concurrency Prisma is incredible
Excellent Frameworks, but you can get away without one Easy to hire
Can handle far more users and traffic before needing to scale
Cons Go does not have many opinions, so you can basically do whatever you want Needs to be serverless or be ready to scale very early
GORM is much less intuitive than Prisma Much worse performance
No concurrency

Pros

  • Go は動作が軽く、並列処理が簡単にできて、スケールせずとも一定のトラフィックを捌ける。
  • TypeScript は Prisma と tRPC の開発体験が最高で、採用もしやすい

Cons

  • Go は ORM が弱い
  • TypeScript は並列処理がないのでパフォーマンスが悪くサーバーレスかスケーリングがすぐに必要になる

気になったこと

  • 動画の9:10くらいのとこで Node.js はリクエストを3つ送りたいとき直列になって500ms x3 = 1.5s かかるけど Golang だと並列で処理できるから半分になると言ってるけど、Promise.all で解決しないか?
  • 「Node.js がイベントループでシングルスレッドだから Concurrency が弱い」がまだしっくりきてない
    • 1cpu で ts と go 戦わせたら go がめっちゃ強いのなんで?
    • (うろ覚え)シングルスレッドだけどあくまで Node.js のプロセスがシングルスレッドなだけであって runtime に載ってる API は OS の機能を使って並列に処理できるからあんま関係ない的なことをふわっと思っていた
    • 🆕 動画v2の後に理解した

動画v2を見る

一貫してること

  • TypeScript は垂直にスケールできないからサーバーレス or k8s で水平スケールしないといけない
    • 逆に、Golang は垂直にもスケールできる(単体で並列処理できるから)
  • Golang はパフォーマンスで勝ってる
    • 計算や並列性が問題になる場合
    • なぜ計算?
      • CPU をゴリゴリに使うと、シングルスレッドの Node.js だと他の処理を止めてしまうが、Golang なら goroutine で簡単にそれを回避できる
        • (ただし、Node.js でも worker_threads を使えば回避できる。が、コードの複雑性は上がってしまう)
  • tRPC 激推し

v1 からちょっと雰囲気が変わったこと

  • TypeScript はサーバーで IO しないなら十分早いよと言っている (アグリー)
  • Next.js/Nuxt.js/SvelteKit とかの SSR 系フレームワークがゲームチェンジャー
    • Go or TypeScript を決めるときに、「フロントとバックをどれだけ強く結びつけたいか?」がキーになると言っている

Ben の主張

  • Standalone (Web UI からだけでなくいろんなクライアントを想定すること)の場合は Go を選ぶ
  • TypeScript でバックエンド書くなら express や NestJS の別サーバーを立てるんじゃなくて絶対 Next.js フルスタックにする
    • もっと言うと、密結合 (tight coupling) のとき、この構成になる
      • e.g. Web UI でユーザー設定を変更するとき、Web UI とバックエンドは密結合になっていて自然なのでフルスタックにする
  • こういう技術選定ってむずいトピックだよね
    • こう言う時はこうって決めつけられても、結局経験してみないとわからないよ

まとめ

どっちもやってみよう。
まずは Next.js x tRPC でどれだけ高速に開発できるか試してみることにする。
P.S. Ben Davis は今22歳...!! もう4年以上勉強していてスタートアップでの経験もあると...!! いい刺激

Taichi MasuyamaTaichi Masuyama

Off topic ~Node.js vs Golang: Concurrency Comparison~

所感

Node.js 使ってる人は全員見たほうがいいと思った。

軽いまとめ

  • Node.js で CPU を使う計算は普通に書くと Promise.all しても他の処理を止めてしまうよ
  • そこで、worker_threads を使うとスレッドを作って計算できるから止めずに計算できるよ
    • コードは少し複雑になる
  • worker-threading の使い方
    • workerData に SharedArrayBuffer を作って渡すと、メモリを共有できる
    • 共有しない場合、thread により多くのメモリを割り当てなければならない
  • worker_threads の実際のユースケース
    • サーバー上で画像やPDFを作りたい時など
  • multi-threading と fork (子プロセスの作成) は違うものだよ

さらに読みたい

https://zenn.dev/dozo13189/articles/d8b4ccb9de9edf
https://zenn.dev/dozo13189/articles/78e26ea96c5ae4
https://github.com/orgs/nodejs/discussions/44264
https://github.com/nodejs/help/issues/1920

Taichi MasuyamaTaichi Masuyama

雑メモ

  • スレッドを作るのに少し時間はかかるから、CPUバウンドだから worker thread 使っとけばいいってことではなく、ちゃんと計測したほうがいいらしい

https://zenn.dev/farstep/articles/process-thread-difference を読む

  • よくまとめられてていい
  • 共有メモリをプロセスで使う場合もスレッドセーフ的なことを考えるのかな
Taichi MasuyamaTaichi Masuyama

ここまでで TS vs Go のパフォーマンス観点は結構解像度上がったのでクローズ
別スクラップで tRPC x Next.js 触ってみる

このスクラップは2024/09/10にクローズされました