前回記事では、レスポンシブWebデザインを採用したプロジェクトの進行に関してディレクションのポイントを2つご紹介しました。
ここからはより具体的に、制作フェーズで課題となりがちな「表示速度の改善」と「画像の取扱い」について、技術的なガイドラインとなるものをご紹介したいと思います。
CSSの書き順もモバイルファーストで
先ほどモバイルファーストとデスクトップファーストの進め方について触れましたが、実はCSSにも「モバイルファースト」な書き方と「デスクトップファースト」な書き方があります。 レスポンシブWebデザインにおいて両者がどのように影響するか見てみましょう。
CSSの書き順による負荷の違い
簡単なサンプルとして、スクリーンサイズによって<h1>の文字色が変わるスタイルを作ってみます。 デスクトップファースト、モバイルファーストそれぞれの違いに注目してください。
まず、デスクトップファーストな書き方はこちら。
/* スクリーンサイズが480px以上のときは青 */
h1 {
color: blue;
}
/* スクリーンサイズが480pxより小さいときは赤 */
@media screen and (max-width:479px) {
h1 {
color: red;
}
}
そしてこちらがモバイルファーストな書き方です。
/* スクリーンサイズが480pxより小さいときは赤 */
h1 {
color: red;
}
/* スクリーンサイズが480px以上のときは青 */
@media screen and (min-width:480px) {
h1 {
color: blue;
}
}
表示結果はどちらも変わらないものの、480pxより小さいスクリーンサイズで表示した際のスタイルの当たり方が異なります。
- デスクトップファースト … 最初に適用された青を打ち消して赤を適用する
- モバイルファースト … 赤を適用する(青は480px以上のときにはじめて適用)
つまり前者は小さいスクリーンサイズにおいて、「スタイルを打ち消す」という余分な処理をするため効率が悪いのです。
通常、画面サイズが大きくなるにつれてレイアウトが複雑になったりデザイン要素が増えたりし、それに伴ってスタイルも増えていきます。 その際デスクトップファーストで記述すると、小さいスクリーンサイズに不要なスタイルや画像を余分にたくさん読み込むことになり、CSSの処理負荷を高めてしまいます。そのためスクリーンサイズの小さいものから順にスタイルを適用するモバイルファーストな書き方が適しています。
弊社ではプロジェクトの進め方自体はデスクトップファーストでも、マークアップの段階でモバイルファーストに切り替えて制作を進めています。
メディアクエリのスタイルはブレイクポイントごとにまとめる
ブレイクポイントごとのスタイル指定を別ファイルに分ける方法もありますが、CSSファイルはなるべく1つにまとめることを推奨します。 これは、次章で紹介する表示速度の改善と関係してきます。
CSSファイルを1つにした場合、その中で同じメディアクエリが何度も登場するケースがありますが、これらをブレイクポイントごとにまとめると、ファイルサイズの肥大化を防ぐことができ、軽量化につながります。
とは言え1つの要素に関するスタイルが離れた位置に書かれているとマークアップの作業効率が悪いので、弊社ではタスクランナー(Gulpなど)を使って完成形のCSSファイルでのみメディアクエリがまとまるようにしています。
表示速度の改善策いろいろ
上のCSSの書き方以外にも、表示速度を改善する対策は多数あります。 次の表は私たちが標準的に実施を検討する項目ですが、中でも「必須」とした項目は効果が大きめなのでぜひ取り入れてみてください。
アプローチ |
具体的な方法 |
必須 |
アプローチ1
サーバへの通信回数を減らす |
まとめられるJSは1ファイルにまとめる |
● |
まとめられるCSSは1ファイルにまとめる |
● |
LPなど1ページ完結なら外部ファイル化しない |
|
CSSスプライトを使う |
|
ローカルキャッシュをコントロールする(.htaccess) |
|
アプローチ2
サーバへの通信量を減らす |
JSをminifyする |
● |
CSSをminifyする |
● |
不要なコードを残さない/td> |
● |
画像を圧縮する |
● |
HTMLをminifyする |
|
gzip圧縮する(.htaccess) |
|
アプローチ3
レンダリングの速度を低下させない |
<head>で読み込む必要のないJSは</body>直前に読み込む |
● |
<head>で読み込む必要があるJSには async / defer 属性を指定する |
|
アプローチ1:サーバへの通信回数を減らす
私たちはWebサイトを閲覧するとき、表示に必要なファイルを必要な数だけサーバへリクエストしています。
この回数をなるべく減らすように制作することが表示速度の改善に繋がります。
まとめられるものはまとめてファイルの数を減らす
CSS、JSといった外部ファイルは、必要以上に分けずまとめられるものは1ファイルにまとめます。 LPなど1ページで完結するものなら、そもそもこれらを外部ファイル化しない選択肢もあります。
CSSスプライトを使うと、画像も1枚にまとめることができます。
CSSスプライトとは、複数の画像を1枚にしたファイルを作り、CSSで「見せる範囲」を指定してWebサイト上に表示させる技術です。アイコンやボタンなど、汎用的なものに使うのが向いています。(最近ではアイコンをWebフォント化し、ボタンには画像を使用しないため、CSSスプライトを使う案件が減りましたが、この方法も効果が大きいです)
ローカルキャッシュを有効にする
サーバ側でできる対策の一つがローカルキャッシュをコントロールすることです。
ユーザが表示したページのデータが個々のブラウザに「キャッシュ」として保存され、再度同じページを表示するときにはそのキャッシュを利用します。こうすることで都度サーバからデータを取得する必要がなく、通信回数を減らすことができます。
これを実現するには、キャッシュの有効期限の設定が必要となります。
Apacheサーバなら.htaccessで設定が可能です。
<IfModule mod_expires.c>
ExpiresActive on
# デフォルトのキャッシュ期限を1週間に
ExpiresDefault "access plus 1 month"
# ファイルの種類ごとに個別で期間を設定する
ExpiresByType text/html "access plus 0 seconds"
ExpiresByType text/css "access plus 1 year"
ExpiresByType text/javascript "access plus 1 year
</IfModule>
※mod_expiresモジュールを使用します。
※上記は一例です。HTML, CSS, JS 以外にもファイルのMIMEタイプごとに指定ができるので、環境に合わせて設定してください。
参考)Apache モジュール mod_expires
ローカルキャッシュを使うときに注意したいのは、キャッシュの有効期限を待たずにファイルを更新した場合、以前のキャッシュが使われてすぐに更新が確認できないことです。
これを回避するため、CSSやJSの読み込み時はファイル名に更新の都度異なるパラメータを付けるようにしておきます。
毎回手作業で行うとミスが出るので、PHPなどでファイルの更新日時を自動取得し、パラメータとして付与するようにしておくと効率的です。
アプローチ2:サーバへの通信量を減らす
アプローチ1ではサーバへリクエストする「回数」に着目しましたが、次は一度のリクエストにかかる「通信量」を見ていきます。
通信量を減らす=各ファイルのサイズをいかに圧縮するか?を考える作業です。
ファイルを圧縮する
圧縮方法はファイルの種類ごとにいろいろあります。大きく分けると次の3種類のツールが選択肢に挙がるのではないでしょうか。無料のツールも数多くありますので、合うものを探してみましょう。
- 方法1)圧縮ソフトをインストールする
- 方法2)Webサービスを使う
- 方法3)タスクランナーを導入する
圧縮方法:HTML、CSS、JSの場合
HTMLやCSS、JSのようなテキストで構成されるファイルであれば、改行やインデントを詰めて1行にすること(「ミニファイ(minify)」と呼びます)で圧縮します。 そもそも不要なコードを残さないこともファイルサイズ削減への第一歩です。
とは言え、マークアップ時にミニファイされた状態で作業することはもちろん現実的ではありません。
人が見やすいように改行やインデントの入った状態で制作をし、公開前に先述したツールを使ってミニファイされたものをサーバへアップロードします。
ただこれも都度人力で実行するのは手間で、忘れてしまうことがあるかもしれません。
そこで、これらの作業を自動化できる「タスクランナー」が重宝されています。
弊社ではGulpを使用し、CSSのミニファイに加え、前項で紹介したメディアクエリのまとめも合わせて処理しています。
圧縮方法:画像の場合
画像ファイルはその形式によって、メタデータと呼ばれるGPSの位置情報や日付データが含まれていることがあります。
このようなビジュアルとして見えない情報を削除したり、視認できない範囲で色数を減らしたりすることでファイルサイズを減らす作業が画像の圧縮です。
やりすぎると劣化してしまうので、仕上がりの画質を確認しながら条件に合う方法を選んでください。
サーバ側でも圧縮をかける
サーバの機能を使って圧縮する方法として「gzip圧縮」があります。
ここまではアップロード前のファイルを圧縮するという考え方でしたが、gzip圧縮はサーバ側で圧縮をかけたデータを転送するという方法です。
これも、Apacheサーバなら.htaccessで設定できます。
サーバ側にかえって負荷をかけてしまっては本末転倒なので、圧縮してほしいファイルの種類をあらかじめ指定しておきましょう。
<IfModule mod_deflate.c>
<IfModule mod_filter.c>
# 圧縮するMIMEタイプの指定
AddOutputFilterByType DEFLATE "application/javascript" \
"text/css" \
"text/html" \
</IfModule>
</IfModule>
# SVGをgzip圧縮した「svgz」の表示設定
<IfModule mod_mime.c>
AddEncoding gzip svgz
</IfModule>
※mod_deflateモジュールを使用します。 ※上記は一例です。
参考)Apache モジュール mod_deflate
アプローチ3:レンダリングの速度を低下させない
ブラウザはHTMLのソースを上から順に読み込みます。また、並行して読み込めるファイルの数には制限があります。
JSファイルを<head>内で読み込むと、JSの読み込みが始まった時点でそれ以降、つまり実際にページの要素として表示される<body>部分のレンダリングが止まり、結果表示が遅く感じられる可能性があるため、JSは</body>直前に読み込むのが主流です。
一方計測用のコードなど、中には<head>内での読み込みを必須としているJSもあります。
この場合は<script>タグの属性async、deferを使うことで、レンダリングを遅らせることなく処理を実行できます。
※ <head>内必須ではないものでも、スライダーなど見た目を整形するようなJSだと、読み込みが後回しになることで表示崩れが起きることもあります。優先順位をつけて選択しましょう。
(2)では、レスポンシブWebデザイン制作フェーズで課題となりがちな「表示速度の改善」のポイントをまとめました。
次回(3)では「画像の取扱い」について技術的なガイドラインとなるものをご紹介したいと思います。