Większość twierdzeń o wydajności w świecie narzędzi JavaScript ma termin przydatności jak u mleka. Ktoś instaluje kilka pakietów w spokojny wtorkowy poranek, przechwytuje wyjście terminala i publikuje dramatyczny wykres słupkowy. Do następnego sprintu jedno z narzędzi wydaje poprawkę, która unieważnia całe zestawienie. Wpis pozostaje jednak zaindeksowany przez wyszukiwarki. Wykres jest wciąż udostępniany. Liczby natomiast już cię okłamują.

To jest zgnilizna, która infekuje niemal wszystkie benchmarki menedżerów pakietów. To fotografia wydarzeń, podczas gdy potrzebujemy transmisji na żywo.

Projekt o nazwie depjs/canary traktuje ten problem jako odpowiedzialność maszyny, a nie zadanie z kalendarza treści. Jest to żywy benchmark, który monitoruje npm, pnpm, Yarn i dep, a następnie ponownie uruchamia cały swój zestaw testów w momencie, gdy którykolwiek z nich opublikuje nową wersję. Wyniki są publiczne, ciągłe i nieuniknione. Gdy coś się zepsuje, repozytorium pozostaje czerwone, dopóki nie zostanie naprawione. Nie ma tu wybiórczego dobierania wyników, chowania się za starym wpisem na blogu ani zakładania, że zeszłomiesięczny zwycięzca wciąż dzierży koronę.

Dlaczego twierdzenia o szybkości potrzebują daty ważności

Menedżery pakietów JavaScript nie stoją w miejscu. Przerwa między wersjami minorowymi może obejmować przepisane algorytmy rozwiązywania zależności, zmienione strategie hoistingu lub zmiany w sposobie kluczowania globalnego cache'u. Benchmark, który rejestruje npm 10.2.1 i pnpm 8.11.0, mówi ci niemal nic o tym, jak te same narzędzia zachowują się dwa wydania później. Mimo to internet jest pełen kategorycznych stwierdzeń typu „Narzędzie X jest trzy razy szybsze”, opartych właśnie na takich zamrożonych migawkach.

Co gorsza, wiele testów ignoruje warunki, które definiują realne problemy deweloperów. Menedżer pakietów może błyskawicznie przejść przez instalację w rozgrzanym, dobrze przygotowanym środowisku, a następnie ociągać się na runnerze CI, który startuje z pustym dyskiem. Bez przetestowania obu tych ekstremów, benchmark staje się informacją prasową, a nie użytecznymi danymi inżynieryjnymi.

Jak Canary automatyzuje porównania

Co dwie godziny zadanie odpytuje rejestr npm. Jeśli pojawi się nowa wersja npm, pnpm, Yarn lub dep, canary się budzi. Nie czeka na to, aż człowiek zauważy changelog. Natychmiast wykonuje pełną macierz testów, która zestawia wszystkich czterech menedżerów z pięcioma popularnymi, rzeczywistymi pakietami. Wybór obejmuje ciężką wagę, taką jak React, Next.js i Vite – bazy kodu, które prawdziwi deweloperzy instalują każdego dnia. Nie są to syntetyczne mikroprojekty zaprojektowane, by przypodobać się jednemu konkretnemu narzędziu.

To podejście wyzwalane przez wydania jest istotne, ponieważ bezpośrednio wiąże pomiar ze zmianą. Gdyby benchmark działał tylko według harmonogramu nocnego, mógłby przeoczyć popołudniowy hotfix lub przez wiele godzin ignorować regresję. Uruchamiając się konkretnie przy nowych wersjach, canary za każdym razem zadaje bezpośrednie pytanie: czy to wydanie sprawiło, że sytuacja stała się lepsza, czy gorsza?

Cztery scenariusze testujące różne aspekty

Macierz testów została zbudowana wokół czterech odrębnych konfiguracji, które odpowiadają workflow, jakie na pewno rozpoznasz.

  • Zimny cache, brak pliku lockfile. To świeże klonowanie na nowym laptopie lub pierwsza instalacja po usunięciu node_modules. Nic nie jest w cache'u. Nic nie jest przypięte. Menedżer pakietów musi rozwiązać, pobrać i zapisać wszystko od zera.
  • Ciepły cache, z plikiem lockfile. To idealna ścieżka (happy path) dla ciągłej integracji, gdy wszystko idzie zgodnie z planem. Plik lockfile istnieje lokalnie, a cache wciąż przechowuje tarballe z poprzedniego uruchomienia. Narzędzie powinno działać szybko, ponieważ większość decyzji została już podjęta.
  • Zimny cache, z plikiem lockfile. Tutaj plik lockfile jest obecny, ale cache został wyczyszczony. Menedżer może pominąć rozwiązywanie zależności, ale wciąż musi pobrać każdy bajt przez sieć. Pozwala to odizolować prędkość sieci od prędkości rozwiązywania zależności.
  • Ciepły cache, brak pliku lockfile. Cache jest rozgrzany, ale pliku lockfile brakuje. Menedżer pakietów musi ponownie rozwiązać drzewo zależności, zanim w ogóle zacznie wypakowywać pliki. Testuje to wydajność solvera i parsera metadanych w idealnych warunkach sieciowych.

Każdy scenariusz jest wykonywany pięciokrotnie, a canary zachowuje wynik medianowy. Ten jeden wybór eliminuje duży szum informacyjny. Chwilowy problem z siecią lub krótki skok opóźnienia rejestru nie mogą przejąć kontroli nad narracją. Wartości odstające są ignorowane; rejestrowane jest typowe doświadczenie.

Testy dymne (smoke tests) wygrywają z pustymi licznikami

Raw speed is easy to fake if you do not verify the outcome. A package manager could skip postinstall steps, corrupt a few symlinks, or install the wrong versions and still post an impressive timestamp. The canary refuses to stop at the timer. After the installation finishes, it actually exercises the installed code.

For example, it boots up an Express application and confirms that the server starts listening on the expected port. If the code does not run, the benchmark fails outright. The smoke test transforms the suite from a race into an audit. It answers the question that speed alone cannot: does the installation actually work?

Radical Honesty as a Feature

The author of the canary wrote three rules into the process that most benchmark authors treat as optional.

Same playing field. Flags are used to normalize behavior across tools. If one package manager hides a performance flaw behind a default setting, the benchmark exposes it rather than letting the tool look good by accident.

Genuine cold starts. Before every single repetition, not just the first one, the npm cache and the pnpm store get wiped. That word "every" is doing heavy labor. Many benchmarks clear the cache once, then run five installs in a row. The second through fifth runs are not truly cold, and the numbers inflate accordingly. The canary starts from zero each time.

Public failure states. When a new release breaks something, the repository remains in a red failure state. It sits there on the front page, ugly and unresolved, until a fix ships. There is no silent suppression to keep the dashboard looking green. This policy forces visibility. A user evaluating tools can see not just which one is fastest, but which one stayed reliable over time.

Inspectability Is Non-Negotiable

A benchmark that you cannot reproduce is a campaign slogan. The canary addresses this with a single bash script that lets anyone run any slice of the suite locally. You do not need to trust a cloud provider’s networking or a maintainer’s hand-tweaked environment. If you suspect the numbers are off, you can generate your own.

That transparency also makes the project useful for maintainers. When a regression hits, a downstream developer can pull the script, bisect the tool’s releases, and hand the upstream team a