Railsで多言語対応する時、localeのymlファイルをjavascriptで利用できるi18n-jsというgemが便利です。i18n-jsについてはRailsでi18n-jsを使ってJavaScriptの国際化にわかりやすくまとめられています。
ただ、このi18n-jsは工夫して使わないとパフォーマンスが劣化することがあります。
#巨大なtranslation.js
i18n-jsを普通に利用すると、全ての言語の翻訳がtranslation.js
という1つのjavascriptにまとめられます。ユーザーが見る言語分だけでいいはずなのに無駄にファイルサイズが膨らんでしまい、スマホで見るとjsのロード時間に時間がかかったりします。
そこで、i18n-jsをlocaleごとに分割して必要な言語分の翻訳リソースのみを利用するようにすることでロード時間を短縮することができます。
#1. i18n-js.ymlに設定を記述
まず、各言語ごとのファイルを出力するためにconfig/i18n-js.yml
を用意します。
下記のように書いておくと、app/assets/javascripts/i18n
の中に、ja.yml
、en.yml
といった言語ごとのlocaleファイルが出力されるようになります。
translations:
- file: "app/assets/javascripts/i18n/%{locale}.js"
#2. rake i18n:js:exportで出力
ターミナルで
$ rake i18n:js:export
と打つと、先ほど設定したディレクトリに各localeファイルが出力されます。
#3. 必要なlocaleファイルだけ読み込むように修正
ユーザーの必要なlocaleファイルのみを読み込むように、viewを修正します。
application.html.erb
やapplication.html.haml
のapplication.js
を読み込んでいるあたりで、下記のように記述します。(hamlの場合を記述しています)
- if Rails.env.development?
= javascript_include_tag "/assets/i18n/translations"
- else
= javascript_include_tag "i18n/#{I18n.locale}"
developmentモードの場合はいちいちlocaleをlocaleを分割したりしないので、translations.js
を読むようにしておきます。それ以外の場合、先ほど出力したi18nディレクトリ以下のlocaleファイルを読み込むようにします。これで、ユーザーに必要なlocaleファイルだけが読み込まれるようになります。
#4. production.rbを書き換えてasset pipelineに対応
各localeのjsファイルにハッシュ値をつけるために、出力したlocaleファイルがprecompileされるようにproduction.rb
に設定を追加します。下記を記述することで、app/assets/javascripts/i18n/
以下のjsファイル全てがprecompile対象になります。
config.assets.precompile += %w( application.js application.css )
files = Dir[Rails.root.join('app', 'assets', 'javascripts', 'i18n', '*.js')]
files.map! {|file| file.sub(%r(#{Rails.root}/app/assets/javascripts/), '') }
config.assets.precompile += files
#5. rake assets:precompile を実行
この状態でasset:precompile
すれば完了です。capistranoなどを使ってデプロイする場合、rake assets:precompile
の前に実行するようにタスクを組んでください。
これで、日本語を設定しているユーザーにはja.js
、英語を設定しているユーザーにはen.js
というように、必要なlocaleファイルだけがロードされるようになります。railsで多言語対応を行うにあたり、jsのロード時間を節約したい時は試してみてください。