Bun, czyli alternatywa typu drop-in dla Node.js, w ostatnich tygodniach zalewa wszystkie frontendowe newslettery. Twórcy obiecują niesamowity skok wydajności – pytanie tylko czy rzeczywiście jego osiągnięcie jest tak blisko jak sugerują autorzy.
1. Bun – alternatywa typu drop-in dla Node.js i Deno
Muszę przyznać, że kiedy informacja o wydaniu Bun po raz pierwszy obiegła internet świadomie postanowiłem ją zignorować. Uznałem, że to po prostu kolejny projekt ciekawostka, który nie ma szans przebić się do produkcyjnych aplikacji. Nadal zdania nie zmieniłem (co nie przeszkadza mi trzymać za projekt kciuków), ale wokół narzędzia wyrosło w ostatnich tygodniach tyle artykułów i dyskusji, że po prostu jestem zmuszony Wam o nim opowiedzieć.
Bun to alternatywa typu drop-in dla Node.js i Deno. O ile Deno swój marketing skupia na rozwiązywaniu problemów Node.js, to Bun stawia nacisk na wydajność. Jeśli wierzyć benchmarkom opublikowanym przez autora, to naprawdę wygląda to imponująco.
Wydajność Buna wynika z dwóch czynników. Po pierwsze w odróżnieniu od konkurencji jest on napisany nie w C++, a w języku Zig. Jeśli jeszcze o nim nie słyszeliście, to nie macie się czym martwić, bo nadal jest on dosyć niszową alternatywą dla C++ i Rust.
Drugim czynnikiem wpływającym na wydajność Buna jest wykorzystanie silnika JavaScriptCore od Apple. Próbowałem znaleźć w sieci benchmarki potwierdzające to stwierdzenie i niewiele udało mi się znaleźć. Natrafiłem natomiast na film Chris Hey, w którym porównał on wydajność Node, Deno i Bun, ale również czystego V8 i JavaScriptCore. Jak się okazuje, JavaScriptCore rzeczywiście jest szybszy od V8. Różnica jest natomiast stosunkowo niewielka i to nie z niej wynikają główne różnice w wydajności między Node i Bun.
W ten oto sposób dochodzimy do (moim zdaniem) clue zarówno imponującej wydajności jak i do powodu dla którego przed Bun jeszcze długa i wyboista droga. Obecnie Bun implementuje około 90% Node API. Jak głosi jedna ze słynnych zasad projektów informatycznych ostatnie 10% pracy kosztuje 80% pracy. Jak głosi inna zasada projektów informatycznych, cykl życia biblioteki zaczyna się od małego wydajnego projektu, następnie odbudowywany on jest w kolejne zależności, aby ostatecznie stać się ociężałym i doczekać się małej i wydajnej alternatywy. Biorąc pod uwagę te dwie prawdy programistyczne, przed Bun jeszcze długa droga na końcu której benchmarki wydajności mogą wyglądać zupełnie inaczej.
O tym jak Bun radzi sobie w produkcyjnym środowisku postanowił przekonać się autor kilku książek na temat Node.js – David Herron. Jak słusznie zwraca on uwagę, proste benchmarki prawie nigdy nie oddają realiów produkcyjnych aplikacji. Dlatego postanowił on uruchomić rozwijaną przez siebie bibliotekę CMS przy użyciu Buna.
Jak się pewnie domyślacie przedsięwzięcie zakończyło się fiaskiem. Brakujące 10% funkcjonalności uniemożliwiło trywialną migrację. Z sukcesem udało się natomiast uruchomić kilka podmodułów aplikacji. Wyniki okazały się niejednoznaczne. W części modułów wydajność znacząco wzrosła, a w części właściwie nie uległa zmianie.
//Source: https://techsparx.com/nodejs/bun/speed-test.html
$ npm run bench
> bench@1.0.0 bench
> npm-run-all render:node render:bun
> bench@1.0.0 render:node
> node render-node.mjs
cpu: Intel(R) Core(TM) i7-5600U CPU @ 2.60GHz
runtime: node v18.6.0 (x64-linux)
benchmark time (avg) (min … max)
-------------------------------------------------------
literal 133.73 ns/iter (119.76 ns … 661.32 ns)
liquid-join 30.26 µs/iter (18.04 µs … 3.66 ms)
cheerio 130.17 µs/iter (78.42 µs … 5.04 ms)
> bench@1.0.0 render:bun
> bun render-bun.js
cpu: Intel(R) Core(TM) i7-5600U CPU @ 2.60GHz
runtime: bun 0.1.4 (x64-linux)
benchmark time (avg) (min … max)
------------------------------------------------------------
literal 129.64 ns/iter (107.87 ns … 534.11 ns)
liquid-list 125.84 µs/iter (87.41 µs … 2.12 ms)
cheerio 68.81 µs/iter (43.25 µs … 2.09 ms)
David Gerron w swoim blogpoście zwraca również uwagę na konsekwencje dla całego środowiska jakie może przynieść rozwój Buna. W ekosystemie Javy rozwijanych jest wiele implementacji JVM, a do weryfikacji ich kompatybilności wykorzystywany jest zestaw testów nazywanych TCK. Do tej pory nie doczekaliśmy się odpowiednika takich testów dla Node, ale z dużym prawdopodobieństwem testy tworzone na potrzeby Buna będą świetnym zalążkiem do dalszej pracy. Kto wie, może za kilka lat w środowisku Node.js będziemy mieć taką samą różnorodność środowisk uruchomieniowych z jaką mamy do czynienia teraz w Javie.
Mam wrażenie, że agresywny marketing wokół wydajności odbił się Bun trochę czkawką. Pod przykrywką alternatywy dla Node.js wprowadza on bowiem całkiem sporo usprawnień. Podobnie jak w przypadku Deno, TypeScript jest natywnie wspieranym językiem. Bun jest też alternatywą dla NPM, która jest nawet do 100x szybsza. To sprawia, że bez problemu może stawać w szranki chociażby z pnpm. Bun udostępnia też API do tworzenia makr, czyli kodu generowanego podczas kompilacji z dostępem do drzewa AST i metadanych typów. Do pakowania aplikacji Bun wykorzystuje niesamowicie szybkiego esbuild skompilowanego przy użyciu Ziga. Szczerze mówiąc ,wszystkie te funkcjonalności brzmią dużo ciekawiej niż pusty slogan: szybszy Node.js.
Źródła:
https://bun.sh/
https://techsparx.com/nodejs/bun/1st-trial.html
https://techsparx.com/nodejs/bun/speed-test.html
https://www.lunasec.io/docs/blog/bun-first-look/
https://www.youtube.com/watch?v=8wTulvlllGQ
Zainstaluj teraz i czytaj tylko dobre teksty!
2. Discord na Androidzie został przepisany do React Native
W minionym tygodniu Discord ogłosił, że ich aplikacja na Androida została przepisana do React Native. Do tej pory wersja komunikatora dla systemu Android była tą, która pod względem funkcjonalności pozostawała w tyle. Dzięki migracji do React Native niezależnie od urządzenia, użytkownicy wreszcie będą mogli cieszyć się spójnym doświadczeniem.
Decyzja o migracji została podjęta przede wszystkim ze względu na potencjalną możliwość współdzielenia sporej części kodu pomiędzy różnymi wersjami aplikacji. Wersja Discord na iOS używa React Native właściwie od pierwszego wydania tego narzędzia. Wersja desktopowa jest aplikacją webową zapakowaną w Electrona. Oznacza to, że wszystkie wersje Discorda oparte są aktualnie o JavaScript.
Na koniec warto podkreślić jeszcze, że zespół Discorda nie zdecydował się całkowicie uwspólnić aplikacji na iOS i Androida. Taka architektura ma pozwolić na optymalne wykorzystanie możliwości jakie daje konkretny system operacyjny.
Źródła:
https://discord.com/blog/android-react-native-framework-update
https://www.theverge.com/2022/8/1/23286860/discord-react-native-android-new-app-ios-new-updates-features
3. Lepsza enkapsulacja `transform` dostępna już we wszystkich przeglądarkach
Wydany początkiem miesiąca Chrome 104 dostarczył funkcjonalność umożliwiającą rozdzielenie jednego `transform` na 3 osobne właściwości – `scale`, `rotate` i `translate`. Tym samym funkcjonalność ta dostępna jest już we wszystkich popularnych przeglądarkach i bez obaw możemy zacząć używać jej w naszych aplikacjach.
Z nowej funkcjonalności skorzystamy przede wszystkim przy tworzeniu animacji. Do tej pory jeśli chcieliśmy do animacji wykorzystać kilka właściwości to należało wyliczyć ich stan we wszystkich klatkach kluczowych. Teraz dzięki możliwości rozdzielenia właściwości wymagane będzie zadeklarowanie tylko tych, które podlegać będą zmianie. Jeśli tłumaczę to zbyt zawile, to przykład poniżej powinien rozwiać Wasze wątpliwości.
/* Old syntax */
@keyframes anim {
0% { transform: translateX(0%); }
5% { transform: translateX(5%) rotate(90deg) scale(1.2); }
10% { transform: translateX(10%) rotate(180deg) scale(1.2); }
90% { transform: translateX(90%) rotate(180deg) scale(1.2); }
95% { transform: translateX(95%) rotate(270deg) scale(1.2); }
100% { transform: translateX(100%) rotate(360deg); }
}
.target {
animation: anim 2s;
animation-fill-mode: forwards;
}
/* New syntax */
@keyframes anim {
0% { translate: 0% 0; }
100% { translate: 100% 0; }
0%, 100% { scale: 1; }
5%, 95% { scale: 1.2; }
0% { rotate: 0deg; }
10%, 90% { rotate: 180deg; }
100% { rotate: 360deg; }
}
.target {
animation: anim 2s;
animation-fill-mode: forwards;
}
Źródła:
https://web.dev/css-individual-transform-properties/
Zainstaluj teraz i czytaj tylko dobre teksty!
4. Docusaurus 2.0
Docusaurus to narzędzie do tworzenia rozbudowanych dokumentacji.O ile o samym projekcie mogliście do tej pory nie słyszeć, to na pewno mieliście już okazję korzystać z opartych o niego stron. Wśród najpopularniejszych bibliotek wykorzystujących Docusaurus znajdziemy bowiem między innymi Prettiera, Babela, React Native czy Ionica.
W minionym tygodniu po 4 latach rozwoju wreszcie doczekaliśmy się kolejnej wersji narzędzia oznaczonej numerkiem 2.0. Wśród nowości znajdziemy między innymi:
- Wsparcie dla MDX, czyli formatu który umożliwia wzbogacenie Markdownu o Reactowe komponenty. Dzięki temu możliwe będzie szybkie i wygodne tworzenie interaktywnej dokumentacji.
- Wzorem Next.js i Remix, również Docusaurus będzie opierał swoją nawigację o strukturę plików.
- Docusaurus z architektury monolitycznej przemigrowany został na znacznie bardziej elastyczna architekturę modularną. Od teraz każda funkcjonalność taka jak dokumentacja, blog czy wyszukiwarka ma swój osobny plugin. Rewolucja pod względem architektury zwiastuje również rychły napływ wtyczek od społeczności.
- Jeśli otworzycie obok siebie kilka dokumentacji opartych o Docusaurus 1.0 to szybko zorientujecie się, że wyglądają one właściwie identycznie. Docusaurus 2.0 udostępnia publiczne API do stylowania, które umożliwi wyczekiwaną od dawna personalizację.
Na zakończenie ciekawostka: wersje alfa i beta Docusaurusa były publicznie dostępne już od ponad dwóch lat. Znalazło się też sporo śmiałków, którzy zdecydowali się zmigrować do wersji 2.0 jeszcze przed wydaniem stabilnej wersji. Jak chwalą się twórcy, już w połowie 2020 roku wersja 2.0 przerosła popularnością stabilną wersję 1.0.
Jeśli zastanawiacie się dlaczego wersja druga tak długo tkwiła we wczesnym dostępie to nie jesteście jedyni. Jak tłumaczą autorzy narzędzia, największym wyzwaniem było przygotowanie stabilnego i publicznego API do stylowania. Do tej pory takie API nie istniało, a wielu klientów do stylowania swoich dokumentacji wykorzystywało wewnętrzne zależności. Jak to zwykle bywa w takich przypadkach, dla takich klientów migracja była bardzo trudna. Z perspektywy zespołu rozwijającego bibliotekę trudne było natomiast rozdzielenie API publicznego od niepublicznego oraz odpowiednie uporządkowanie tego pierwszego. Jak zapowiadają twórcy, od teraz kolejnych dużych wydań możemy spodziewać się co 2-4 miesiące.
Źródła:
https://docusaurus.io/blog/2022/08/01/announcing-docusaurus-2.0