在过去的一年里,WordPress 开发者仔细分析了 WordPress 现有的 i18n 系统的性能,并最终创建了一个新的名为「Performance Translations」(高效翻译)的功能插件:
该插件提供了一个全面改进的性能更好的语言包加载系统,在经过成千上万用户的测试之后,WordPress 6.5 核心代码中已经内置了该插件的功能。
这个新功能在加载语言包文件时更快,并且使用的内存更少,并且还支持同时加载多个语言环境,这使得语言环境切换也变得更快。除此之外,它还支持包含在 PHP 格式的翻译文件,这样既可利用 OPCache 对其进行加速。
新的.l10n.php
翻译文件格式
现在从 WordPress.org 下载的语言包里面,除了原来就有的 .mo
和 .po
文件之外,可能还会多出一个 .l10n.php
新文件 ,如果有该格式的文件,WordPress 6.5 就优先通过它来加载语言包,该文件使得翻译加载更快,并用到的内存更少。
这是一个渐进式的增强,意思是如果只有 .mo
文件而没有 .l10n.php
文件,WordPress 依旧通过加载 .mo
文件来加载语言包,反之亦然,因此理论上现在语言包里面可以只有 .l10n.php
文件,但是目前 WordPress 还是需要有对应的 .mo
和 .po
文件,主要用于语言包的更新检查,不过这个限制将来会得到解决。
如何生成新的 .l10n.php
文件
如果要生成新的 PHP 翻译文件,GlotPress 的 4.0 版(translate.WordPress.org 的支持插件)已经支持新 .l10n.php
格式。
除此之外,WP-CLI 2.10.0 ( i18n-command
2.6.0) 也提供了一个新的命令 wp i18n make-php
,可以根据 .po
文件创建翻译 PHP 文件:
# Create PHP files for all PO files in the current directory.
$ wp i18n make-php .
# Create a PHP file from a single PO file in a specific directory.
$ wp i18n make-php example-plugin-de_DE.po languages
如果是 WordPress 插件开发者,还可以使用新 WP_Translation_File
类将文件转换 .mo
为翻译 PHP 文件:
$contents = WP_Translation_File::transform( $mofile, 'php' );
if ( $contents ) {
file_put_contents( $path_to_php_file, $contents );
}
禁用 .l10n.php
文件
如果出于某种原因想禁用翻译 PHP 文件的支持,可以使用新的 translation_file_format
filter 来改变翻译文件的首选格式(默认是 php
):
add_filter('translation_file_format', fn () => 'mo');
此外 WordPress 6.5 还提供了一个新的 filter load_translation_file
,可以用它来更改翻译文件的路径。
$l10n
全局变量
我们知道 WordPress 使用全局变量 $l10n
来存储已加载的翻译,在 WordPress 6.5 之前,这个全局变量是 MO
类的实例,它用于读取 .mo
文件提供的翻译字符串,随着 WordPress 6.5 的更新,$l10n
全局变量将改为 WP_Translations
类的实例。
WP_Translations
类充当了一个桥梁,维持了与 MO
类相似的特性和接口,以确保向后兼容性。通过这种方式,WordPress 可以透明地处理新的 PHP 翻译文件格式,同时保持对旧的 .mo
文件格式的支持。
缓存语言文件路径列表
此外,WordPress 6.5 还有个优化改进,在 6.5 之前,像 get_available_languages()
这样的函数 和 WP_Textdomain_Registry
这样的类,每次都是直接使用 glob()
函数搜索 .mo
文件,这可能导致一些性能问题,特别是在拥有很多翻译或在文件系统较慢的环境中的网站上。
因此,WordPress 6.5 引入了新的缓存机制,通过 WP_Textdomain_Registry
类集中查找翻译文件,然后将其存储在 group 为 translations
的对象缓存中,缓存键的格式为 cached_mo_files_<hash>
,其中 <hash>
是扫描目录的 MD5 哈希值,例如 wp-content/languages
,并且每当更新语言包时,缓存就会被清除。