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
vue-i18n VS Intlayer: Benchmark internacjonalizacji (i18n) dla Vue
vue-i18n to referencyjna biblioteka i18n dla Vue. Intlayer to alternatywa oparta na kompilatorze, z treścią ograniczoną do komponentu, z integracją z Vue (vue-intlayer). Ten artykuł przygląda się temu, ile każda z nich kosztuje po zbudowaniu aplikacji.
Dane pochodzą z Benchmark Bloom, open-source'owego zestawu, który buduje tę samą aplikację z każdą biblioteką i rejestruje, co przeglądarka faktycznie pobiera i wykonuje.
tl;dr: Na tej samej aplikacji Vite + Vue 3vue-i18ndostarcza 134,9 KB gzipowanego JavaScriptu na stronę wobec 41,3 KB dla aplikacji bez i18n. Intlayer dostarcza 57,1 KB. Sam runtimevue-i18nważy 24,3 KB gzip (6x więcej niż 3,9 KB Intlayera), każda strona niesie 90% ciągów z innych stron, a komponent skompilowany w izolacji wciąga 196 KB, ponieważ jest związany z globalnym drzewem komunikatów. Adapter@intlayer/vue-i18nzachowuje APIvue-i18ni zmierzył 47,0 KB na stronę.
W skrócie
- vue-i18n - Faktyczny standard i18n dla Vue 2 / Vue 3 i rdzeń
@nuxtjs/i18n. Komunikaty w stylu ICU, bloki<i18n>w SFC, dyrektywav-t, formateryd()/n(), duży ekosystem. Komunikaty są rejestrowane na globalnej instancji wcreateI18n(); leniwe ładowanie per locale to ręczny wzorzecsetLocaleMessage(), a podział per trasa jest do zbudowania samodzielnie. - Intlayer - Model treści skoncentrowany na komponentach. Słowniki
.content.tsleżą obok komponentu, któremu służą, kompilator w czasie budowania (vite-intlayer) wykonuje tree-shaking i leniwe ładowanie per komponent i per locale, ścisłe typy TypeScript są generowane z treści, a brakujące tłumaczenia powodują błąd w czasie budowania. Zawiera helpery routera / SEO, Visual Editor / CMS oraz tłumaczenie wspomagane AI.
Otwórz tabelę w oknie modalnym, aby wyraźnie zobaczyć całą zawartość
Odznaki aktualizują się automatycznie. Zrzuty będą się zmieniać w czasie.
Porównanie funkcji obok siebie
Otwórz tabelę w oknie modalnym, aby wyraźnie zobaczyć całą zawartość
| Funkcja | vue-intlayer (Intlayer) | vue-i18n |
|---|---|---|
| Tłumaczenia blisko komponentów | ✅ Tak, .content.ts obok każdego komponentu | ✅ Przez bloki SFC <i18n> (opcjonalne); globalne katalogi to typowa konfiguracja |
| Integracja z TypeScript | ✅ Ścisłe typy generowane automatycznie z treści | ✅ Dobre typowania; ścisłe bezpieczeństwo kluczy wymaga typowania schematu i dyscypliny |
| Wykrywanie brakujących tłumaczeń | ✅ Błąd TypeScript + błąd/ostrzeżenie w czasie budowania | ⚠️ Fallback w runtime + ostrzeżenie w konsoli |
| Bogata treść (komponenty / Markdown) | ✅ Bezpośrednie wsparcie | ⚠️ Interpolacja komponentów <i18n-t>; Markdown przez zewnętrzne wtyczki |
| Wsparcie ICU | ⚠️ W trakcie prac | ✅ Tak |
| Formatowanie (daty, liczby, waluty) | ✅ Formatery oparte na Intl | ✅ d() / n() z datetimeFormats / numberFormats |
| Zlokalizowany routing | ✅ Helpery dla Vue Router / Nuxt, getMultilingualUrls | ⚠️ Nie w rdzeniu (@nuxtjs/i18n lub własna konfiguracja routera) |
| Helpery SEO (hreflang, sitemap, robots) | ✅ Wbudowane helpery | ❌ Nie w rdzeniu |
| Tree-shaking (dostarczanie tylko używanej treści) | ✅ Per komponent, per locale, zautomatyzowane przez kompilator | ⚠️ Ręcznie: podział katalogów, setLocaleMessage() per trasa |
| Leniwe ładowanie | ✅ importMode: 'dynamic' (jedna linia konfiguracji) | ✅ Ręczny import() + setLocaleMessage() |
| Usuwanie nieużywanej treści | ✅ Martwe słowniki są odrzucane w czasie budowania | ❌ Nie wbudowane |
| Testowanie brakujących tłumaczeń (CLI / CI) | ✅ npx intlayer content test | ⚠️ Zewnętrzne (vue-i18n-extract) |
| Tłumaczenie wspomagane AI | ✅ Wbudowane, używa własnych kluczy dostawcy | ❌ Nie |
| Visual Editor / CMS | ✅ Darmowy Visual Editor + opcjonalny CMS | ❌ Nie (zewnętrzne platformy lokalizacyjne) |
| Serwer MCP i Agent Skills | ✅ Tak | ❌ Nie |
| Ekosystem / społeczność | ⚠️ Mniejszy, ale szybko rosnący | ✅ Duży i dojrzały w ekosystemie Vue |
Benchmark
Co zmierzono
Zestaw Benchmark Bloom buduje tę samą aplikację Vite + Vue 3 z każdą biblioteką: 10 stron (home, about, blog, careers, contact, FAQ, pricing, products, settings, team), 10 locale (en, fr, es, de, it, pt, zh, ja, ko, ru), identyczne komponenty i identyczna treść. Strony są mierzone w en i fr.
Obie biblioteki testowano w konfiguracji static, tej, którą dostarcza większość projektów Vue: dla vue-i18n JSON każdego locale importowany i przekazany do createI18n({ messages }); dla Intlayera domyślny importMode: 'static'. W tym trybie Intlayer również pakuje wszystkie locale, ale kompilator nadal ogranicza treść per komponent, więc strona niesie tylko słowniki komponentów, które renderuje.
Dla każdego builda zestaw rejestruje:
- Lib size: rozmiar gzip pustego komponentu, który tylko importuje bibliotekę i18n. Stały koszt runtime'u.
- Page JS: gzipowany JavaScript pobierany na stronę, uśredniony po wszystkich stronach i locale.
- Locale leak %: udział przetłumaczonych ciągów znalezionych w pobranym JS, które należą do locale, którego użytkownik nie przegląda (fingerprint na
enifr, więc 50% oznacza „drugie mierzone locale jest w pełni obecne"; przy 10 spakowanych locale rzeczywista strata jest większa). - Page leak %: udział przetłumaczonych ciągów znalezionych w pobranym JS, które należą do strony, na której użytkownik nie jest.
- Component avg: średni rozmiar gzip każdego komponentu skompilowanego w izolacji. Pokazuje, ile runtime'u i18n i katalogu wciąga pojedynczy komponent.
- E2E reactivity: rzeczywisty czas między wybraniem nowego locale a aktualizacją
html[lang]w DOM (Playwright, 5 iteracji). - Page load:
PerformanceNavigationTiming.duration.
Poniższe liczby pochodzą z uruchomienia z dnia 2026-09-12 zvue-i18n11.4.0 iintlayer9.5.0 / 9.5.1. Aplikacja testowa jest celowo mała (kilkadziesiąt ciągów na locale), więc procenty wycieku opisują wzorzec: rosną wraz z treścią, podczas gdy koszt runtime'u pozostaje stały.
Wyniki na Vite + Vue 3
Wybierz metryki i biblioteki, które Cię interesują:
Metryka
Dynamiczne ładowanie JSON
Wczytuje tłumaczenia leniwie w czasie wykonywania
Ograniczony JSON (przestrzenie nazw)
Przestrzenie nazw tłumaczeń na stronę
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
Otwórz tabelę w oknie modalnym, aby wyraźnie zobaczyć całą zawartość
| Biblioteka | Strategia | Lib size (gz) | Lib size (min) | Page JS śr. (gz) | Locale leak | Page leak | Component śr. (gz) | Reaktywność E2E | Page load |
|---|---|---|---|---|---|---|---|---|---|
| base (bez i18n) | - | 0,0 KB | 0,0 KB | 41,3 KB | 0,0% | - | 1,1 KB | 1,8 ms | 10,8 ms |
vue-i18n | static | 24,3 KB | 83,2 KB | 134,9 KB | 50,0% | 90,0% | 196,0 KB | 2,8 ms | 13,6 ms |
vue-intlayer | static | 3,9 KB | 11,1 KB | 57,1 KB | 56,8% | 0,0% | 7,7 KB | 4,5 ms | 13,8 ms |
@intlayer/vue-i18n (compat) | static | 7,9 KB | 23,2 KB | 47,0 KB | 15,0% | 0,0% | 8,4 KB | 1,5 ms | 9,3 ms |
Kolumna page-leak aplikacji bazowej jest pusta: bez biblioteki i18n fingerprinting wyłapuje zakodowane na sztywno ciągi w współdzielonych chunkach i liczba nie ma znaczenia.
Jak to czytać
- Koszt runtime'u.
vue-i18nto jeden z najcięższych runtime'ów w całym benchmarku: 24,3 KB gzip / 83,2 KB po minifikacji dla pustego komponentu, który tylko go importuje.vue-intlayerkosztuje 3,9 KB gzip. Tę różnicę płaci się na każdej stronie niezależnie od tego, ile masz ciągów. - JavaScript na stronę. Aplikacja bez i18n waży 41,3 KB.
vue-i18nponad trzykrotnie ją zwiększa do 134,9 KB; Intlayer ląduje na 57,1 KB, +15,8 KB, z czego większość to dziesięć spakowanych locale (zobacz następny punkt). - Wyciek. Z
createI18n({ messages: { en, fr, ... } })każda strona dostarcza wszystkie locale i ciągi wszystkich stron: 50% wycieku locale (na dwóch fingerprintowanych locale) i 90% wycieku stron. TrybstaticIntlayera również pakuje wszystkie locale (stąd porównywalna wartość wycieku locale), ale ma 0% wycieku stron: strona pobiera tylko słowniki komponentów, które renderuje. Przełączenie naimportMode: 'dynamic'usuwa również wyciek locale; ta konfiguracja nie była częścią tego uruchomienia Vue. - Rozmiar komponentu to miejsce, gdzie widać architekturę. Komponent wywołujący
useI18n()kompiluje się średnio do 196 KB, ponieważt()jest związane z globalną instancją, która przechowuje każdy komunikat każdego locale. Ten sam komponent zuseIntlayer()kompiluje się do 7,7 KB: sięga tylko po własny słownik. - Reaktywność nie jest problemem dla żadnej z nich (2-5 ms). System reaktywności Vue sprawia, że przełączanie locale jest tanie, gdy komunikaty są już w pamięci.
@intlayer/vue-i18n, adapter drop-in, zachowuje APIvue-i18ni zmierzył 47,0 KB na stronę oraz 8,4 KB na komponent, bez zmian w kodzie aplikacji.
Dla porównania, to samo uruchomienie zmierzyło fluent-vue na 171,8 KB na stronę, 29,7 KB runtime'u i 217 KB na komponent.
Pełna tabela, ze wszystkimi bibliotekami i wszystkimi strategiami, w raporcie benchmarku Vue.
Skąd ta różnica? Globalna instancja vs skompilowane słowniki
vue-i18n to runtime. createI18n() buduje globalną instancję przechowującą drzewo komunikatów per locale; useI18n() wiąże z nią każdy komponent; t("footer.github") wyszukuje klucz w czasie renderowania. To właśnie umożliwia bloki SFC <i18n>, v-t i ładowanie komunikatów w runtime, i to również dlatego graf zależności każdego komponentu zawiera całe drzewo:
Skopiuj kod do schowka
Optymalizacja oznacza, że ty dzielisz en.json na pliki per trasa, ty wywołujesz setLocaleMessage() w strażniku routera i ty utrzymujesz poprawne mapowanie trasa-plik, gdy komponenty się przemieszczają. Runtime nie może tego zrobić za ciebie, ponieważ nie ma pojęcia, o jakie klucze komponent poprosi.
Intlayer przenosi tę wiedzę do builda. Treść jest deklarowana obok komponentu, a vite-intlayer ustala, który komponent importuje który słownik:
Skopiuj kod do schowka
Kompilator emituje, per słownik i per locale, dokładnie ten JSON, którego potrzebuje dany komponent, i odrzuca słowniki, których nic nie importuje. Ograniczenie per trasa jest konsekwencją ograniczenia per komponent, a nie zadaniem.
Aby odrzucić również nieużywane locale, ustawdictionary.importMode: 'dynamic'wintlayer.config.ts. Zobacz dokumentację optymalizacji bundle'a.
Doświadczenie programisty
Konfiguracja
vue-i18n
Skopiuj kod do schowka
Skopiuj kod do schowka
Intlayer
Skopiuj kod do schowka
Skopiuj kod do schowka
Skopiuj kod do schowka
Komponent
vue-i18n
Skopiuj kod do schowka
Skopiuj kod do schowka
t('counter.label') jest stringiem, dopóki sam nie otypujesz schematu komunikatów; literówka renderuje klucz.
Intlayer
Skopiuj kod do schowka
Skopiuj kod do schowka
label i increment są otypowane; literówka to błąd TypeScript, brakująca wartość francuska to błąd builda.
Leniwe ładowanie per locale
vue-i18n
Skopiuj kod do schowka
Następnie wywołaj loadLocaleMessages() ze strażnika routera i samodzielnie podziel locales/{locale}.json per trasa, jeśli chcesz ograniczenia per strona.
Intlayer
Skopiuj kod do schowka
Zachowaj API vue-i18n, uzyskaj wynik Intlayera
@intlayer/vue-i18n to adapter drop-in: useI18n(), t(), d(), n(), interpolacja {name} i {0}, liczba mnoga z pipe ("car | cars"), v-t i i18n.global.locale nadal działają, serwowane ze słowników Intlayera skompilowanych przez vite-intlayer.
Skopiuj kod do schowka
W benchmarku build compat tej samej aplikacji zszedł ze 134,9 KB do 47,0 KB na stronę i ze 196 KB do 8,4 KB na komponent, bez zmian w komponentach. Twoje istniejące locales/{locale}.json mogą pozostać źródłem prawdy dzięki wtyczce synchronizacji JSON.
Zobacz przewodnik migracji z vue-i18n i dokumentację kompatybilności. Użytkownicy Nuxt mają tę samą ścieżkę przez kompatybilność @nuxtjs/i18n.
Kiedy wybrać które?
- Wybierz vue-i18n, jeśli chcesz standardowego podejścia Vue, polegasz na komunikatach ICU lub blokach SFC
<i18n>, używasz już@nuxtjs/i18nlub platforma tłumaczeniowa oczekuje scentralizowanego JSON-a. Zarezerwuj czas na podział katalogów i leniwe ładowanie per trasa, jeśli rozmiar bundle'a ma znaczenie. - Wybierz Intlayer, jeśli chcesz treści ograniczonej do komponentu, ścisłego TypeScriptu, błędów brakujących kluczy w czasie budowania, bezwysiłkowego tree-shakingu i leniwego ładowania oraz wbudowanych narzędzi redakcyjnych (Visual Editor, CMS, tłumaczenie AI, serwer MCP). Szczególnie istotne dla dużych, modularnych baz kodu Vue / Nuxt i design systemów.
- Wybierz
@intlayer/vue-i18n, jeśli jesteś już navue-i18ni chcesz zysków w rozmiarze bundle'a bez przepisywania.
Często zadawane pytania
Jedno i drugie, w zależności od wybranego podejścia. vue-intlayer to natywny runtime z composable useIntlayer(). @intlayer/vue-i18n to adapter zgodności, który zachowuje API vue-i18n i podmienia jego źródło, dzięki czemu możesz migrować bez modyfikowania komponentów i stopniowo przechodzić plik po pliku.
Adapter ich nie odczytuje. Przenieś te wiadomości do plików JSON lokalizacji lub do pliku .content.ts obok komponentu, co stanowi tę samą koncepcję z wygenerowanymi typami. To jedyna funkcja vue-i18n, która nie jest przenoszona.
Tak. Intlayer z Nuxt obejmuje wielojęzyczny routing, middleware wykrywania języka i generowanie mapy witryny. Jeśli używasz @nuxtjs/i18n, adapter zgodności Nuxt i18n stanowi ścieżkę migracji.
Tak. Wtyczka synchronizacji JSON odczytuje je w dialekcie vue-i18n ({name}, {0}, formy mnogie z kreską "car | cars") i zapisuje tłumaczenia z powrotem przy aktualizacji przez CLI lub CMS.
Natywna obsługa ICU jest w trakcie opracowywania. Adapter @intlayer/vue-i18n obsługuje składnię wiadomości vue-i18n, w tym formy mnogie oraz interpolację nazwaną i listową. Informacje o modelu pluralizacji Intlayer znajdziesz w sekcji treści wyliczeniowe.
Powiązane porównania
Dokumentacja referencyjna:
Raporty benchmarków:
Aby zrozumieć, skąd wzięły się te biblioteki, przeczytaj historię i18n w JavaScript.
Gwiazdki GitHub
Gwiazdki GitHub są silnym wskaźnikiem popularności projektu, zaufania społeczności i długoterminowej istotności. Choć nie są bezpośrednią miarą jakości technicznej, odzwierciedlają, ilu programistów uważa projekt za użyteczny, śledzi jego postępy i prawdopodobnie go zaadoptuje.
Aktywność commitów
Gwiazdki pokazują popularność. Commity pokazują, ile pracy włożono w projekt. W chwili pisania Intlayer ma około 7 500 commitów, więcej niż większość porównywanych tu bibliotek i mniej więcej 5 razy więcej niż next-intl czy next-i18next.
- intlify/vue-i18n
- aymericzip/intlayer
Commity na domyślnej gałęzi, źródło: GitHub API.
Intlayer to monorepo, więc ta liczba obejmuje każdy pakiet dla frameworków, CLI i dokumentację. Traktuj commity jako sygnał aktywności, a nie jakości.
Pobrania z npm
- vue-i18n
- vue-intlayer
Źródło: API pobrań rejestru npm.
Liczba pobrań nagradza najstarsze rozwiązania, a nie najlepsze. Biblioteka wydana lata temu wciąż jest instalowana przez każdy projekt, który ją wtedy wybrał, przez każde uruchomienie CI i przez każdy pakiet, który od niej zależy. Ta liczba mierzy bezwładność bardziej niż świadomy wybór.
Asystenci AI wzmacniają ten efekt. next-intl, i18next i vue-i18n są wszędzie w kodzie, na którym ich trenowano, więc proponują je domyślnie, bez porównywania alternatyw. Każda sugestia dodaje pobrań, które napędzają kolejną sugestię. Porównuj na podstawie benchmarku, a nie liczby pobrań.
Podsumowanie
vue-i18n jest dojrzały, elastyczny i głęboko zintegrowany z Vue. Benchmark pokazuje, ile kosztuje jego projekt runtime-first w buildzie Vite: runtime 24 KB gzip, 134,9 KB na stronę dla aplikacji, która bez i18n waży 41 KB, 90% treści z innych stron na każdej stronie oraz komponenty, z których każdy sięga 196 KB, ponieważ wiszą na globalnym drzewie komunikatów.
Intlayer przenosi pracę do kompilatora. Słowniki per komponent i usuwanie martwej treści to wyniki builda, a nie konwencje. Na tej samej aplikacji: runtime 3,9 KB, 57,1 KB na stronę, 0% wycieku stron, komponenty 25x mniejsze. A jeśli przepisanie nie wchodzi w grę, @intlayer/vue-i18n pokonuje większość tej drogi bez zmian w komponentach.
Wszystkie surowe dane, aplikacje testowe i skrypty są w repozytorium Benchmark Bloom. Uruchom je sam.
Więcej szczegółów znajdziesz w dokumencie „Dlaczego Intlayer?".
Komentarze
Nie ma jeszcze komentarzy. Bądź pierwszą osobą, która podzieli się swoimi przemyśleniami.
