初代編集長ブログ―安田英久

Webフォントをできるだけ軽く表示する圧縮の.htaccessや遅延ロードJSを作ってみた

Webフォントを使ってもできるだけ表示が快適になるように工夫してみました
Web担のなかの人

今日は、Webフォントのお話しを。Web担で初めてWebフォントを使ってみたのですが、予想どおり転送量が大きくてページ表示が重くなるので、できるだけ表示が快適になるように工夫してみました。

脱・新人Web担!あずさのWeb担当者日記という新コーナーで、Webフォントを使いました。

イベントなどでも女性Web担当者の数が増えていることから、現場の女性の方に執筆を依頼し、担当編集者も女性にして、女性向けの記事として作ってもらったら、「女性誌っぽいデザインにしたい」ということで、Webフォントを使うことになったのです。

しかし、重い! どれぐらい重いかというと、HTMLやCSSやJSや画像を全部あわせても740Kバイトぐらいなのに、フォントファイル1つで3.2Mバイトもあるのです!

Webフォントを使ってもできるだけページ表示を軽くするための注意点や工夫点をお伝えします。

ポイント1:本当に効果的なところ以外では使わない

なので、第1のポイントは「本当に効果的なところ以外では使わない」こと。

最初はタイトルや見出しなどにもWebフォントを使っていたのですが、デフォルトの表示と大きく変わるわけではないので、そこはWebフォントの適用を中止しました。

ポイント2:Webフォントは圧縮する

今回利用したWebフォントは、3.2Mバイトのサイズがあります。そのまま転送すると600ミリ秒~1秒の時間がかかります(他の環境やモバイルなどではもっとかかります)。

Webサーバー側で圧縮した状態で送り出すことで、転送サイズを減らしましょう。そのためには、.htaccessなどで次のような指示をします(Webサーバーでmod_deflateが有効になっている必要あり)。

WebフォントをApache側で圧縮して転送する.htaccessの記述
<IfModule mod_mime.c>
	AddType font/opentype         .otf
	AddType font/eot              .eot
	AddType font/truetype         .ttf
	AddType application/font-woff .woff
</IfModule>
<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE font/opentype font/eot font/truetype application/font-woff
</IfModule>

これで、Webフォントへのアクセスは自動的にWebサーバーが圧縮して転送してくれ、転送量が2.3Mバイト、転送時間は450ミリ秒~800ミリ秒になりました。

さらに、毎回の圧縮処理が入るとアクセスが多いときには負荷になるだろうと、あらかじめgzip圧縮したフォントファイルをサーバー上の同じ場所に作っておいて、圧縮ファイルがある場合はそちらを転送するようにしました。

あらかじめ圧縮したWebフォントファイルが同じディレクトリにあればそれを使う.htaccessの設定
<IfModule mod_rewrite.c>
  RewriteCond %{HTTP:Accept-encoding} !gzip
  RewriteRule .* - [S=4]
  RewriteCond %{REQUEST_URI} \.otf$
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}\.gz -s
  RewriteRule .* %{REQUEST_URI}\.gz [L,QSA,T=font/opentype,E=no-gzip:1]
  RewriteCond %{REQUEST_URI} \.eot$
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}\.gz -s
  RewriteRule .* %{REQUEST_URI}\.gz [L,QSA,T=font/eot,E=no-gzip:1]
  RewriteCond %{REQUEST_URI} \.ttf$
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}\.gz -s
  RewriteRule .* %{REQUEST_URI}\.gz [L,QSA,T=font/truetype,E=no-gzip:1]
  RewriteCond %{REQUEST_URI} \.woff$
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}\.gz -s
  RewriteRule .* %{REQUEST_URI}\.gz [L,QSA,T=application/font-woff,E=no-gzip:1]
</IfModule>

Webフォントは正しいコンテントタイプをHTTPヘッダーで返さないとブラウザがWebフォントとして扱ってくれない場合があります。最初、そこにハマりました。

RewriteRuleのTフラグでコンテントタイプを指示できると思ったのですが、うまくいかなかったので、結局次のようにしてForceTypeディレクティブで強引に上書きしています。このあたりはもう少し調べてみます。

強引にコンテントタイプを設定する.htaccessの設定
<FilesMatch "\.(?i:otf(\.gz)?)$">
  ForceType font/opentype
</FilesMatch>
<FilesMatch "\.(?i:ttf(\.gz)?)$">
  ForceType font/eot
</FilesMatch>
<FilesMatch "\.(?i:eot(\.gz)?)$">
  ForceType font/truetype
</FilesMatch>
<FilesMatch "\.(?i:woff(\.gz)?)$">
  ForceType application/font-woff
</FilesMatch>

ちなみに、最初にテストしたときはWebサーバーによる圧縮に時間がかかっているように見えたのですが、いまチェックしてみると、mod_deflateで圧縮した場合と比べて、特にリクエストに対する反応時間は変わっていませんでした。ですから、わざわざ圧縮済みファイルを置いておく効果はほとんどないかもしれません(アクセスが多い時間帯だと変わるのかな)。

まぁ、gzipで圧縮する際に最高圧縮率に設定したので4Kバイトほと節約できているのがメリットでしょうか。

手法転送サイズ転送時間の例
非圧縮3.2MB(3,311,516バイト)600ms~1000ms
Apacheのmode_deflate圧縮(標準)2.3MB(2,415,239バイト)450ms~800ms
gzip事前圧縮2.3MB(2,411,075バイト)400ms~800ms

ポイント3:ブラウザ側でキャッシュできるようにする

重いWebフォントファイルを何度もWebサーバーから取得する必要はありません。一度表示したWebフォントは、ブラウザがキャッシュして二度とサーバーに読みに行かないようにしましょう。

Webフォントファイルがブラウザ側でキャッシュされるようにするための.htaccessの設定
<FilesMatch "\.(?i:(otf|ttf|eot|woff)(\.gz)?)$">
    ExpiresDefault A25920000
</FilesMatch>

これで、一度Webフォントファイルにアクセスした時点から300日間は、同じURLのフォントファイルを参照する場合でもサーバーに読みに行かずにローカルのキャッシュを使ってくれます。

ポイント4:Webフォントの適用を遅らせる

それでもやはりフォントの処理で1秒ぐらい余分にかかるのでWebフォントの適用をページ表示から少し遅らせることにしました。

まず、@font-faceの定義を独立したCSSファイルに移動してそのファイルはページから直接には読み込まないようにすることで、ページを表示しただけではフォント定義が読み込まれないようにします(つまりフォントファイルにもアクセアスしない)。

その状態で、グーグルのWbFont Loaderを使って、ページ表示が完了してから遅らせてフォントを適用します。

Webフォントを遅延ロードするためのJavaScript
<script type="text/javascript">
WebFontConfig = {
  custom: {
    families: ['HuiFont'],
    urls: ['/files/css/fonts.css']  // @font-face指定CSSファイル
  }
};
$(document).ready(function() {
  setTimeout(
    function() {
      var wf = document.createElement('script');
      wf.src = ('https:' == document.location.protocol ? 'https' : 'http') + '://ajax.googleapis.com/ajax/libs/webfont/1.4.7/webfont.js';
      wf.type = 'text/javascript';
      wf.async = 'true';
      var s = document.getElementsByTagName('script')[0];
      s.parentNode.insertBefore(wf, s);
    },
    5000
  );
});
</script>

この例では、ブラウザがページ表示を構築してから5秒後にWebフォントを適用しています。

ポイント5:ローカルの校正HTMLファイルでは適用できない

Webフォントは原則として「同じドメイン名じゃないと使えない」ものです。

どういうことかというと、Web担のサーバーに置いてあるWebフォントファイルは、Web担のサーバー上のHTMLファイルからでないと使えないのです。

ふだんはそれで問題ないのですが、校正用HTMLをHTMLファイルで関係者に送って確認してもらう場合には、その校正HTMLファイルをローカルにダウンロードして開いてもWebフォントが反映されません。

同じサーバーにあるHTML以外からもWebフォントを使えるようにするには、HTTPヘッダーでそれを指示しなければいけません。具体的には、.htaccessなどで次の命令を記述します。

Webフォントを他のドメイン名やローカルから使えるようにする.htaccessの設定
<FilesMatch "\.(?i:(otf|ttf|eot|woff)(\.gz)?)$">
  Header set Access-Control-Allow-Origin *
</FilesMatch>

外部サーバーが決まっている場合はそのサーバー名を記述すればいいのですが、前述のようなローカルにダウンロードしたHTMLファイルの場合は、さまざまなブラウザで使えるようにするには上記の記述が必要になります。

ただし、こうすると、だれでもそのWebフォントを使えるようになってしまう点に注意が必要です。Web担では上記の指示は入れていません。

用語集
CSS / HTML / JavaScript / Webサーバー / キャッシュ / ダウンロード / ディレクトリ / ドメイン名
この記事が役に立ったらシェア!
メルマガの登録はこちら Web担当者に役立つ情報をサクッとゲット!

人気記事トップ10(過去7日間)

今日の用語

リードジェネレーション
リードは潜在顧客のことで、ある特定の商品、サービスに関心がありそうなユーザーもし ...→用語集へ

インフォメーション

RSSフィード


Web担を応援して支えてくださっている企業さま [各サービス/製品の紹介はこちらから]