Zadaj pytanie i otrzymaj streszczenie dokumentu, odwołując się do tej strony i wybranego dostawcy AI
Treść tej strony została przetłumaczona przy użyciu sztucznej inteligencji.
Zobacz ostatnią wersję oryginalnej treści w języku angielskimJeśli masz pomysł na ulepszenie tej dokumentacji, zachęcamy do przesłania pull requesta na GitHubie.
Link do dokumentacji na GitHubieKopiuj dokument Markdown do schowka
Czy Intlayer jest lżejszy niż Paraglide?
Tak.
Paraglide cieszy się świetną reputacją najlżejszego rozwiązania i18n na rynku, a na pierwszy rzut oka benchmark zdaje się to potwierdzać: rozmiar jego biblioteki jest bliski zeru. Jednak rozmiar biblioteki równy zero wcale nie oznacza zero wysłanych bajtów. Oznacza to jedynie, że bajty znajdują się w miejscu, którego ten wskaźnik nie bada.
Kluczowe wnioski
Rozmiar biblioteki jest ukryty, a nie usunięty:
Paraglide generuje swój runtime i funkcje komunikatów bezpośrednio w Twojej bazie kodu. Ten kod trafia do przeglądarki, ale jest liczony jako Twój kod, a nie kod biblioteki.
Brak providera to pozorny zysk:
Każde wywołanie m.my_key() samodzielnie rozpoznaje locale, odczytując plik cookie lub pamięć podręczną dla każdego renderowanego węzła, zamiast pobrać tę wartość raz z kontekstu.
Brak dynamicznego ładowania:
Paraglide importuje wszystkie wersje językowe komunikatu do Twojego bundle klienta. Intlayer z opcją importMode: 'dynamic' lub 'fetch' ładuje wyłącznie aktualnie wyświetlane locale.
Tree shaking nie jest gwarantowany:
W niektórych z naszych benchmarków deklarowany przez Paraglide tree shaking nie przyniósł oczekiwanych rezultatów. Warto zweryfikować to we własnym bundle.
Gdzie podziewa się waga Paraglide?
W raportach benchmarków metryka „rozmiar biblioteki” mierzy wielkość providera i hooków każdej biblioteki i18n w pustym komponencie, zanim dodana zostanie jakakolwiek treść.
Otwórz tabelę w oknie modalnym, aby wyraźnie zobaczyć całą zawartość
| Biblioteka (TanStack Start) | Rozmiar lib (gz) | Rozmiar lib (min) |
|---|---|---|
@inlang/paraglide-js@2.15.1 | 1.8 KB | 4.5 KB |
react-intlayer@9.5.1 | 5.0 KB | 15.2 KB |
W oderwaniu od reszty aplikacji Paraglide wygrywa. Jednak Paraglide jest kompilatorem: odczytuje pliki messages/*.json i tworzy w Twoim repozytorium folder paraglide/, zawierający plik runtime.js (wykrywanie locale, strategie cookies i storage, lokalizacja adresów URL) oraz jedną funkcję JavaScript dla każdego komunikatu.
Skopiuj kod do schowka
Ponieważ ten kod znajduje się w Twoim folderze src/ i jest importowany za pomocą ścieżki względnej, bundler przypisuje go do Twojej aplikacji, a nie do pakietu w node_modules. W kolumnie rozmiaru biblioteki nie pojawia się niemal nic, podczas gdy dokładnie ta sama logika nadal jest dostarczana w bundle Twojej strony.
Generowanie kodu samo w sobie nie jest złym pomysłem: wygenerowany runtime zawiera wyłącznie logikę wymaganą przez Twoją konfigurację (strategia prefiksów, cookie vs. local storage itp.). Intlayer osiąga ten sam cel w inny sposób: wstrzykując zmienne środowiskowe na etapie budowania, dzięki czemu bundler odrzuca gałęzie kodu, z których nie korzysta Twoja konfiguracja. Oba podejścia okazują się ostatecznie od 3 do 10 razy lżejsze niż i18next czy next-intl.
Sprawiedliwe porównanie nie dotyczy zatem rozmiaru samej biblioteki. Dotyczy kodu JavaScript faktycznie przesyłanego na stronę.
Rzeczywista waga strony
Aplikacja TanStack Start, 10 stron, pomiar na trasach en oraz fr, kompresja gzip:
Otwórz tabelę w oknie modalnym, aby wyraźnie zobaczyć całą zawartość
| Konfiguracja | Śr. JS strony (gz) | Ponad bazę | Wyciek locale | Wyciek innych stron |
|---|---|---|---|---|
| Baza (bez i18n) | 111.0 KB | - | 0.0% | 0.0% |
paraglide (dowolna strategia) | 125.1 KB | +14.1 KB | 49.7% | 0.0% |
intlayer (importMode: static) | 125.8 KB | +14.8 KB | 50.0% | 0.0% |
intlayer (importMode: dynamic) | 118.6 KB | +7.6 KB | 0.0% | 0.0% |
Next.js 16 App Router, ta sama aplikacja:
Otwórz tabelę w oknie modalnym, aby wyraźnie zobaczyć całą zawartość
| Konfiguracja | Śr. JS strony (gz) | Ponad bazę |
|---|---|---|
| Baza (bez i18n) | 141.0 KB | - |
paraglide-next | 155.3 KB | +14.3 KB |
next-intlayer | 141.3 KB | +0.3 KB |
Dynamiczne ładowanie JSON
Wczytuje tłumaczenia leniwie w czasie wykonywania
Ograniczony JSON (przestrzenie nazw)
Przestrzenie nazw tłumaczeń na stronę
Benchmark wydajności I18n
Czym jest ta metryka?
Całkowity skompresowany przez gzip rozmiar pakietu biblioteki umiędzynarodowienia. Obejmuje tylko dostawcę i logikę pobierania treści po tree-shakingu i minifikacji.
Dlaczego to jest ważne?
Mniejszy rozmiar biblioteki zmniejsza obciążenie u klienta.
Zobacz jako
Kompletne dane zawiera raport benchmarku TanStack Start oraz raport benchmarku Next.js. Każdy bundle można szczegółowo przeanalizować w repozytorium benchmarku.
Uwagę zwracają dwa fakty:
- W trybie
staticIntlayer przesyła praktycznie taką samą ilość treści jak Paraglide (125.8 KB vs 125.1 KB). Jest to w pełni zrozumiałe: oba rozwiązania dołączają wszystkie wersje językowe komunikatów używanych na stronie. - Paraglide pozostaje przy wadze 125.1 KB niezależnie od wybranej strategii, ponieważ nie oferuje trybu dynamicznego. Każdy wiersz w powyższej tabeli odpowiada ładowaniu statycznemu.
Brak Providera: pozorna zaleta o ukrytym koszcie
Paraglide nie wymaga providera. Importujesz komunikat i wywołujesz go:
Skopiuj kod do schowka
Brak kontekstu, brak komponentu otaczającego, brak hooka. Wydaje się to prostsze. Jednak informacja o wybranym języku i tak musi skądś pochodzić. Każda wygenerowana funkcja komunikatu wygląda mniej więcej tak (postać uproszczona):
Skopiuj kod do schowka
Funkcja getLocale() sprawdza po kolei skonfigurowane strategie (cookie, local storage, URL, domyślne locale), aby ustalić bieżący język. Oznacza to, że każdy renderowany węzeł tekstowy (<>{m.my_key()}</>) uruchamia własny proces rozpoznawania locale, co obejmuje odczyt document.cookie w przeglądarce. Strona z 200 przetłumaczonymi ciągami znaków wykonuje tę operację 200 razy podczas jednego renderowania, a następnie powtarza to przy każdym ponownym renderowaniu.
Biblioteka oparta na providerze odczytuje locale dokładnie raz, zapisuje je w kontekście (albo w sygnale czy store), a każdy węzeł pobiera wartość gotową już w pamięci. Provider kosztuje zaledwie kilkaset bajtów. Rezygnacja z niego kosztuje cykle procesora przy każdym renderze, co wyraźnie widać w wynikach benchmarku: czasy ładowania strony i przełączania języków w Paraglide na TanStack Start wyraźnie ustępują Intlayerowi (22.1 ms vs 14.6 ms przy ładowaniu strony, 4.3 ms vs 3.2 ms w reaktywności E2E).
Doświadczenie programisty (DX)
Źródłem prawdy w Paraglide jest format JSON, ale programista nigdy nie importuje plików JSON bezpośrednio. Importuje wygenerowany plik .js:
Skopiuj kod do schowka
Skopiuj kod do schowka
Skopiuj kod do schowka
Skopiuj kod do schowka
Skopiuj kod do schowka
Taki cykl pracy wiąże się z niedogodnościami:
- Każda zmiana w pliku JSON wymaga ponownej generacji, zanim import zostanie rozpoznany lub zaktualizują się typy.
- Wygenerowany folder
paraglide/musi być zatwierdzany w gicie (co prowadzi do konfliktów scalania w wygenerowanych plikach przy każdym PR zmieniającym teksty) albo ignorowany (co wymaga kroku generowania przed każdym sprawdzaniem typów, testem i zadaniem CI). - Każdy ciąg znaków staje się wywołaniem funkcji. Stałe zamieniają się w
m.key()w całym kodzie, nawet tam, gdzie w zupełności wystarczyłaby zwykła wartość tekstowa.
Tree Shaking: sprawdź swój bundle
Główną zaletą promowaną przez Paraglide jest to, że nieużywane komunikaty są usuwane przez tree shaking, ponieważ każdy komunikat stanowi niezależny eksport. W benchmarku Svelte + Vite rozwiązanie to działa zgodnie z zapowiedziami.
W innych środowiskach tak się jednak nie stało. W naszych testach Next.js strony Paraglide ważyły o 14 KB więcej niż aplikacja bazowa, podczas gdy next-intlayer dodał zaledwie 0.3 KB. Wcześniejsze pomiary na TanStack Start wykazały także, że komunikaty z innych podstron trafiały do bundle bieżącej trasy.
Skuteczność tree shakingu zależy od używanego bundlera (Turbopack, Rolldown, Rollup), sposobu importowania komunikatów (import { m } vs import * as m) oraz analizy efektów ubocznych. Wybierając Paraglide ze względu na rozmiar, warto otworzyć wizualizator bundle i sprawdzić, jak zachowuje się on w Twojej aplikacji.
Brak dynamicznego ładowania
Oto fundamentalne ograniczenie architektoniczne. Paraglide nie udostępnia mechanizmu ładowania jednego języka na raz: każda funkcja komunikatu statycznie importuje implementację każdego języka, co sprawia, że wszystkie wersje językowe trafiają do bundle klienta.
Przy 2 językach marnuje się połowa przesyłanych danych tłumaczeń, co odpowiada zmierzonemu wyżej ~50% wyciekowi locale. Przy 10 językach marnuje się 90% danych. Przy 30 językach aż 97%.
Przejście na dynamiczne ładowanie również nie rozwiązałoby problemu: przy jednej funkcji na każdy komunikat leniwe ładowanie każdej z nich generowałoby tysiące zapytań sieciowych.
Intlayer pozwala na elastyczny wybór, globalnie lub na poziomie słownika:
Skopiuj kod do schowka
Otwórz tabelę w oknie modalnym, aby wyraźnie zobaczyć całą zawartość
importMode | Co jest przesyłane do klienta | W porównaniu z Paraglide |
|---|---|---|
static | Wszystkie języki słowników używanych na stronie | Teoretycznie identyczna wielkość |
dynamic | Tylko bieżące locale, ładowane na żądanie dla słownika | N razy lżejsze przy N językach |
fetch | Tylko bieżące locale, pobierane przez Live Sync API | N razy lżejsze przy N językach |
Dzięki transformacji w trakcie budowy oraz trybowi importMode: 'static', Intlayer ładuje w teorii dokładnie tę samą zawartość co Paraglide. Z kolei przy 'dynamic' lub 'fetch' ładuje tylko to, czego potrzebuje aktualny język: w aplikacji obsługującej N języków rozmiar danych tłumaczeń jest N razy mniejszy niż w Paraglide.
Kiedy Paraglide nadal ma sens?
Jeśli Twoim stosem technologicznym jest Svelte z Vite i obsługujesz dwa lub trzy języki, tree shaking działa zgodnie z oczekiwaniami, a narzut dodatkowych języków pozostaje niewielki.
Jeśli Twój zespół aktywnie korzysta z ekosystemu inlang (Fink, Sherlock, wtyczki formatów komunikatów), Paraglide integruje się z nim natywnie.
Przetestuj na własnej aplikacji
Sprawdź wagę transferu i wycieki locale w swojej działającej aplikacji za pomocą bezpłatnego narzędzia i18n SEO Scanner:
Aby skonfigurować Intlayer:
Skopiuj kod do schowka
Przydatne materiały
Komentarze
Nie ma jeszcze komentarzy. Bądź pierwszą osobą, która podzieli się swoimi przemyśleniami.
