Vue i18n 条件导入单语言翻译包优化组件性能及Lighthouse评分问询
Vue i18n 单语言局部翻译资源按需加载实现方案
核心思路:通过动态导入+Vue i18n的翻译合并API,仅加载当前语言对应的分类翻译资源,避免全量多语言资源打包,降低首屏加载体积。
实现步骤
- 提取当前使用的语言码
可从路由路径、i18n全局实例或你提到的config.baseapi中拆分获取,示例逻辑:
// 从baseapi路径中提取语言码,示例baseapi:http://localhost:3000/en/p/add const getCurrentLang = () => { const pathSegments = config.baseapi.split('/') return pathSegments[3] || 'en' // 兜底默认使用英文 }
- 组件内异步加载对应翻译并注入i18n
动态import会自动做代码拆分,不会将所有语言包打入初始包,配合Vue i18n的mergeLocaleMessageAPI将翻译合并到全局实例,同时添加加载标记避免重复请求:
<script setup> import { useI18n } from 'vue-i18n' import { ref, onMounted } from 'vue' import config from '~/config' const { mergeLocaleMessage } = useI18n() // 存储已加载的分类语言标识,避免重复加载 const loadedCateLangs = ref([]) // 提取当前语言码 const getCurrentLang = () => { const pathSegments = config.baseapi.split('/') return pathSegments[3] || 'en' } const loadCateTranslation = async () => { const currentLang = getCurrentLang() // 已加载过则直接跳过 if (loadedCateLangs.value.includes(currentLang)) return try { // 动态导入对应语言的分类翻译文件 const transModule = await import(`~/locales/${currentLang}category.json`) // 将翻译合并到i18n全局实例 mergeLocaleMessage(currentLang, transModule.default) loadedCateLangs.value.push(currentLang) } catch (err) { console.error('分类翻译加载失败,加载兜底英文资源', err) // 加载失败时兜底加载英文翻译 const enTrans = await import('~/locales/encategory.json') mergeLocaleMessage('en', enTrans.default) } } // 组件挂载时加载翻译 onMounted(() => { loadCateTranslation() }) </script> <template> <div class="categorizer"> <!-- 正常使用$t调用翻译即可,示例: --> <span>{{ $t('category.electronics') }}</span> </div> </template>
注意:如果使用Vite构建,动态导入路径需要保留固定前缀,上述
~/locales/${currentLang}category.json写法符合要求,Vite会自动扫描所有匹配规则的文件生成独立异步chunk;Webpack同样支持该动态导入写法。
方案效果
- 仅加载当前语言对应的分类翻译资源,其他语言的翻译不会被打包进初始资源,有效减少首屏加载体积,提升Lighthouse性能评分
- 无需在组件
<i18n>块内写入全量多语言翻译,避免组件代码冗余 - 支持重复访问组件时复用已加载的翻译,不会重复发起请求
内容的提问来源于stack exchange,提问作者ClassicGuy
相关产品推荐
相关产品推荐

