Powrót do strony głównej

Dart backend: benchmarki i problemy z pamięcią

Programista przetestował Dart jako zamiennik Node.js w SaaS. Benchmarki ujawniły problemy: latencja 9.5s p95, pamięć nie jest zwracana w K8s. Ekosystem jest słaby, VM jest zoptymalizowana pod Flutter.

Dlaczego Dart jest gorszy od Node.js na serwerze: testy RPS i GC
Advertisement 728x90

# Dart na serwerze: dlaczego nie sprostał obciążeniu w produkcji

Programista SaaS zdecydował się zastąpić Node.js przez Dart, by zmniejszyć zużycie pamięci. Oczekiwano 10 MB zamiast 80 MB na starcie, kompilacja AOT i statyczne typowanie. Zamiast tego — dwa tygodnie rozwoju, własny framework i benchmarki pokazujące gorsze wyniki. Lekcja: zawsze przeprowadzaj surowe benchmarki na scenariuszach produkcyjnych przed migracją.

Serwis autoryzacji (OAuth2, Redis ORM) posłużył jako poligon testowy. Node.js zużywał 500 MB na szczycie, ale oddawał pamięć. Setki instancji po 80 MB na starcie — to główne zmartwienie.

Ekosystem: brak narzędzi dla backendu

Dart jest skierowany na Flutter. Brak odpowiedników NestJS, klientów Redis na poziomie ioredis jest mało. Shelf to prymitywny router, Serverpod — dla full-stack Flutter.

Google AdInline article slot

Trzeba było budować framework od zera:

  • Drzewiasty DI jak w Angularze.
  • Zakres żądania przez Zone.
  • CLI z kodogeneracją dla AOT.

Przeniesiono ts-oauth2-server i ioredis (4500 linii Dart vs 23500 TS). AI sobie poradził, ale cena wysoka: eksperymentalna flaga --enable-experiment=enhanced-parts, part 'file.g.dart' wszędzie, commit z pościelą lub generacja na CI.

Refleksja usunięta dla AOT. Type to bezużyteczny kikut, statyczne metody nie do wywołania. DI bez mirrors wymaga CLI w JIT → mirrors → generacja. W TS/Java/C# — trzy linie refleksji.

Google AdInline article slot

Język: przyjemny, ale nie do metaprogramowania

Składnia logiczna, błędy na kompilacji. Ale brak for...in po obiektach, refleksja nie istnieje. Kodogeneracja to koszmar: odwołania do .g.dart w źródłach.

AI przeniósł ioredis mechanicznie. Rezultat: +5% RPS ponad najlepszym klientem na pub.dev. Nekrolog ekosystemowi — backendowy kod na Dart nie powstaje.

Benchmarki: latencja i pamięć dobija

Scenariusz: 3 endpointy, Postgres, Redis. Surowy HTTP, bez frameworków. 100m CPU, 500 VUS.

Google AdInline article slot

| Metryka | Dart AOT | Node.js | Go |

|---------------|----------|---------|-----|

| RSS start | 3 MB | 18 MB | - |

| p95 latencja | 9,5 s | 5 s | 2,9 s |

| RPS | 2x gorzej niż Node | - | najlepszy |

| Szczyt RSS | 39-47 MB | 37 MB | - |

Dart:

  • Nie oddaje pamięci do OS (>5% po szczycie).
  • GC pod presją: pauzy dla 60fps (Flutter), nie RSS dla K8s.
  • Przy throttling rośnie do 47 MB, Node się kurczy.

Flagi GC (--dontneed_on_sweep, --use_compactor) nie pomogły. Z założenia: VM dla mobilnych. K8s widzi 40 MB/pod stale, HPA nie upakowuje nodów. Oszczędność na starcie zjadana przez dopłaty.

Na Cloud Run: Dart droższy od Node — wolniejszy + trzyma pamięć.

Co ważne:

  • Latencja p95 9,5 s vs 5 s Node — awarie w produkcji.
  • Pamięć nie wraca: dopłata za skalowanie.
  • Ekosystem martwy poza Flutterem.
  • Benchmarki w repo: manifesty k8s, profile CPU, Dockerfiles.

Podsumowanie: nisza Darta to tylko Flutter

Dwa tygodnie poszły na framework, porty, testy. Dart dobry do prostego kodu, ale server-side — klapa. Brak refleksji, VM nie dla chmury, kodogeneracja piekło. Oficjalne obietnice „skalowalnych API dla Cloud Run” nie spełnione.

Alternatywy jak Go odrzucono przez err != nil i context.Context. Node.js zostaje: pamięć oddaje, latencja lepsza.

— Editorial Team

Advertisement 728x90

Czytaj dalej