Webサイトの表示速度を改善する(画像圧縮やCSS最適化など)

凝った作りのWebサイトは、どうしても重くなって表示速度が落ちます。画像やCSS、javascriptも圧縮しているのに、なぜか重い。そういうケースに遭遇したので試したことを残します。

画像の圧縮率を上げる

ページを重くするのは結局、画像です。TinyPNGなどのサービスで画像を圧縮するのが手軽です。また、gulpを使用している場合、gulp-imageminのimagemin-optipngより圧縮率の高いモジュールがありますので、それを使うと便利です。

imagemin-pngquant

npm

画像を非可逆圧縮するみたいで、圧縮効果はTinyPNGと同等なようです。

npmでインストール

npm install -D imagemin-pngquant
// or
npm install -S imagemin-pngquant

gulpfile.js

var pngquant = require('imagemin-pngquant’);
gulp.task("build:images:minify", function () {
return gulp.src([
    src + "/images/**/*.@(gif|jpg|png)",
    "!" + src + "/images/favicon-master.png"
    ])
    .pipe($.changed(build + "/images"))
    .pipe($.imagemin(
    [
        pngquant({
            quality: '65-80',
            speed: 1,
            floyd:0
        }),
        $.imagemin.optipng()
    ],
    imageminOpts
    ))
    .pipe(gulp.dest(build + "/images"))
});
var imageminOpts = {
    interlaced: true,
    progressive: true,
    optimizationLevel: 5
};

書き方はGulpでpngquantを使ってPNGの減色&軽量化を参考にしてます。

CSSセレクタ指定を工夫する

セレクタは右から左に解釈されるようなため、子孫セレクタの指定をなくせば処理が軽くなるようです。とはいえ、ブラウザの表示技術(レンダリング)の向上や実際のCSSの管理を考えると悩ましいところなので、できるだけ意識する程度で良い気もします。

Sassで管理する場合

SassでCSSを書く場合、その書きやすさから階層を深く書いてしまいがちです。機能別モジュールとしてクラスを管理する方法を3つ挙げてみます。

  1. クラスで指定して、孫セレクタを書かない
  2. クラスで指定するのにとどめる
  3. BEMで書く

1. クラス指定して、孫セレクタを書かない

要素名ではなくクラスで指定する方法です。htmlマークアップの手間が増えますがアンカーであれば「すべてのaを探す」ことは防げます。また、なるべく処理コストがかからないように孫セレクタを書かないようにします。CSSのバッティングに気をつけながら書く必要があります。

jade(pug)

section.m-sect
    h2.ttl 見出し
    .body
        p.txt テキストが入ります。

Sass (Indent Syntax)

.m
    @at-root
        &-sect
            .ttl
                ...
            .body
                ...
            .txt
                ...

2. クラス指定にとどめる

1と同様、要素名ではなくクラスで指定する方法ですが、孫指定を維持する方法です。1に比べてCSSのバッティングリスクは減ります。

Sass (Indent Syntax)

.m
    @at-root
        &-sect
            .ttl
                ...
            .body
                ...
                .txt
                    ...

3. BEMで書く

子孫セレクタを書かず、親・子・孫の管理をしやすくするベストな方法はBEM記法になると思うのですがいかがでしょう。ただし、孫のクラス名は必然的に長くなります。BEMについてはBEMによるフロントエンドの設計 – 基本概念とルール | CodeGridに詳しく書かれています。

jade(pug)

section.sect
    h2.sect__ttl 見出し
    .sect__body
        p.sect__body__txt テキストが入ります。

Sass (Indent Syntax)

.sect
    @at-root
        &__ttl
            ...
        &__body
            ...
            @at-root
                &__txt
                    ...

ブラウザキャッシュを設定する

Webサイトへの2回目以降のアクセスについて効果が出ます。PageSpeed Insightsで推奨されている内容でもあります。有効にするには、Cache-ControlヘッダやExpiresヘッダを使用して.htaccessに設定します。Cache-Controlヘッダを使用するのが主流なようですが、Expiresヘッダと併用することもできるようです。このことについては、ブラウザのキャッシュよるサイトパフォーマンスを向上させる方法でくわしく解説されています。

.htaccessにCache-Controlで設定

# 1日: 86400
# 30日: 86400* 30 = 2592000
# 3ヶ月: 86400 * 30 * 3 = 7776000
# gif、jpg(jpeg)、png、ico、js、css、gz を3ヶ月間ブラウザキャッシュさせる
<Files ~ ".(gif|jpe?g|png|ico|js|css|gz)$">
    Header set Cache-Control "max-age=7776000"
</Files>
# gif、jpg(jpeg)、png、ico、js、css、gz を前回のアクセスから30日間ブラウザキャッシュさせる
<Files ~ ".(gif|jpe?g|png|ico|js|css|gz)$">
    Header set Cache-Control "max-age=A2592000"
</Files>

WordPressプラグインを使う

WordPressを使ったWebサイトの場合、便利なプラグインがありますので紹介します。フロントエンドでできるだけのことをやって、あとはこれらのプラグインを使えば大抵なんとかなると思います。

EWWW Image Optimizer

プラグインページ

アップロード済み・プラグインインストール後のアップロード画像のメタデータ削除などを行って、OptiPNGで圧縮・最適化できます。

WP Fastest Cache

プラグインページ

WordPressキャッシュプラグインの最終兵器「 WP Fastest Cache」を見て使ってみましたが、使いやすいプラグインです。このプラグインを有効化するだけでPageSpeed Insightsの評価は上がりました。

[未検証]CSS内の不要な記述を削除する

CSSセレクタ指定の工夫よりも簡単に効果が出るはずな方法ですが、自動削除ツールでもないと大変な作業です。今のところ、Wordpressテーマ作成に使えるツールはないようですが静的サイトをgulpやgruntを使って制作する場合、gulp(grunt)-uncssが使えそうです。

僕がGulpで使っているプラグインとnode.jsモジュール一覧で紹介されてます。

phpファイルを精査できるツールがあれば、ぜひtwitterなどでレスいただけると大変助かります。。。
以上です。

Author

  • Shinichi Kuroda - 黒田晋一
  • 香川県高松市 - Takamatsu-shi, Kagawa, Japan.
  • Mail - info@studiobusstop.com