14時の間食

CakePHPの記事を中心にWeb制作について

ブログのレスポンスを高速化する為に行った7つの施策

Web制作

    ブログのリニューアルに伴い表示速度の改善を試みたので意識して行った施策を書いておきます。

    1, WordPressではなくCakePHPを使用

    WordPressはインストールした時点でブログを構成する上でのあらゆる機能が備わっているため、場合によっては高速化のために不要な機能をそぎ落としていくことも必要かと思います。

    一方、CakePHPはインストールした時点ではまだ何も機能を引き出していないので、ブログに必要な機能を用意するくらいなら、余程トリッキーなことをしない限り軽量に動作します。

    私はただでさえ脳みそミニマムな上、WordPressにはあまり慣れていないため、備わっている機能を全て把握できる手のひらサイズのブログを作るためにCakeを選びました。

    もっとも、これは施策ではなく単なる好みですね。自分の好きなCMSなりブログサービスなりフレームワークを使うことがブログを最適化するんでも一番やる気になれると思います。
    自分が最も愛を持って取り組めるツールを使いましょう!

    2, 画像ファイルはMySQL(DB)に格納しない

    このブログではアイキャッチ画像をMySQL(DB)にBLOB型で格納しています。←しているという…。
    結論から言ってしまうと、高速化を考えるなら画像のDB保存は避けた方が無難です。

    DB保存のメリットとデメリットを挙げるとこんな感じでしょうか。

    DBに保存するメリット

    • セキュリテイ上の優位性。認証をパスした人だけに表示・DLさせるといったことが容易。
    • ファイルとレコードが常に一致しているので、レコードはあるのにファイルがない(※もしくはその逆)…といった不整合が発生しない。
    • ファイルとレコードが常に一致しているので、バックアップ・リストアも容易。

    DBに保存するデメリット

    • DB保存よりWebサーバの方がキャッシュに優れている。
    • データベースへの負荷が増える。
    • 表示方法によっては動作が遅い。

    画像をHTML内に埋め込む

    やはり、普通に公開するだけの画像ファイルはディレクトリに保存するのが良さそうではありますが、諦めてはいけません。 DB保存でも表示を高速化する方法がありました。

    参考:PHPでMysqlから取得した画像バイナリーデータを高速表示

    データベースから読み込んだ画像のバイナリデータをBase64エンコードしてそのままHTML内に埋め込む、という手法です。
    具体的にはこうです。

    <img src=”data:<?php echo $mine_type ?>;base64,<?php echo base64_encode($image); ?>” />
    

    $mine_typeは画像のMINE Type(image/jpegなど)を、$imageはDBにBLOBで格納したバイナリデータを入れてあげてください。
    こうすることでHTML内に画像データが展開されます。

    アクセス毎に複数の画像ファイルを取ってくるより1つのHTMLへのアクセスで済むほうが速いですからね。
    CakePHPのビューキャッシュと併用すればDBへのアクセス数も減り、ほぼDB保存のデメリットは解消されます。

    3, 外部JavaScriptはページの最後で読み込む

    JavaScriptファイルはheadタグ内で読み込むより、bodyの閉じタグ直前で読み込む方が表示速度が速くなります。

    JavaScriptファイルの読み込み中はページの読み込みが止まるため、どの位置で読み込んでも最終的な表示完了までの速度は変わりませんが、
    bodyの閉じタグ直前で読み込むことで体感的な表示速度を向上させることが出来ます。

            <!--
            ========================================================================
            □ bodyの閉じタグ前 - JavaScript
            ========================================================================
            -->
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
            <script src="/js/bootstrap.min.js"></script>
            <script src="/js/jquery.infinitescroll.min.js"></script>
            <script src="/js/entry.root.js"></script>
        </body>
    </html>
    

    ちょっとしたことですが意識していきたいですね。

    4, デザインのCSS化

    脳内メーカー的な

    このブログのデザインは、装飾に画像の使用を避け、ほぼ全てCSSのグラデーションとボーダーで成り立っています。

    各種アイコンはアイコンフォントのFont Awesomeを使用しています。

    記事本文以外での画像使用を徹底的に避けたので、デザインに使用した画像は背景に使用した2KBのループ画像のみです。こんなの→ 背景

    視覚的表現をCSSに置き換えることで、高速化だけでなくRetinaのような高精細ディスプレイでも美しく描画されるようになりました。
    特に2倍の解像度を意識する必要はありません。(※↓このキャプチャはRetinaで表示したものではないので普通に荒いですが…)

    ヘッダー周りのブログデザイン メニュー周りのブログデザイン

    私はフラットデザインより押せる感のあるもっこりしたボタンが好きなので、グラデーションはつい多用しがちです。
    グラデーションのCSSは手で書くと大変なので、いつも便利なジェネレーターを使用しています。

    Ultimate CSS Gradient Generator

    Photoshop感覚でスライダーをいじるだけで↓のようなコードが生成されます。
    自動でベンダープレフィックスもついたコードが生成されるため、多くのブラウザ&バージョンをカバーしてくれます。

    background: #258dc8; /* Old browsers */
    background: -moz-linear-gradient(top,  #258dc8 0%, #258dc8 100%); /* FF3.6+ */
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#258dc8), color-stop(100%,#258dc8)); /* Chrome,Safari4+ */
    background: -webkit-linear-gradient(top,  #258dc8 0%,#258dc8 100%); /* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(top,  #258dc8 0%,#258dc8 100%); /* Opera 11.10+ */
    background: -ms-linear-gradient(top,  #258dc8 0%,#258dc8 100%); /* IE10+ */
    background: linear-gradient(to bottom,  #258dc8 0%,#258dc8 100%); /* W3C */
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#258dc8', endColorstr='#258dc8',GradientType=0 ); /* IE6-9 */
    

    IE8以下などの古いブラウザではグラデーションは表示されませんが、背景色を指定しておけば問題ありません。

    background: #258dc8; /* Old browsers */
    

    このツールではグラデーションの指定と同時に近似色の背景色も指定してくれるので安心です。

    5, JavaScriptやCSSのミニファイ

    実はミニファイって言葉は知らなかったのですが、コメントやインデント、改行を取り除いて圧縮することですね。

    きっちりインデントを施したCSSが…

    .clearfix {
      *zoom: 1;
    }
    
    .clearfix:before,
    .clearfix:after {
      display: table;
      line-height: 0;
      content: "";
    }
    
    .clearfix:after {
      clear: both;
    }
    
    .hide-text {
      font: 0/0 a;
      color: transparent;
      text-shadow: none;
      background-color: transparent;
      border: 0;
    }
    
    .input-block-level {
      display: block;
      width: 100%;
      min-height: 30px;
      -webkit-box-sizing: border-box;
         -moz-box-sizing: border-box;
              box-sizing: border-box;
    }
    

    ミニファイするとこうなる!

    .clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}
    

    インデントがぁー(´;ω;`)!!!

    この処理を施すことで、ブログで使用しているCSSは35KBから26KBになりました。

    SassやCompassを使用している方はコンパイル時に自動的に行えるのかと思いますが、個人的にはまだSassの導入を見送っているので、Web上で使えるツールのお世話になりました。

    http://cssminifier.com/

    こうしたツールは他にも沢山あります。

    変換したファイルの名前は~.min.cssとするのが慣例的で宜しいかと。
    もちろん編集する時のために元ファイルも残しておきます。

    6, ブラウザキャッシュの利用

    .htaccessを使用しファイル毎にブラウザがキャッシュを保存する有効期限を記述してやることで、その期間中は問答無用でキャッシュを使用するという指定ができます。

    ファイルの新旧を比較するための問い合わせ自体をしなくなるので正に問答無用です。
    HTTPリクエストの数が大幅に減少しますので、その効果は絶大です。

    ただし、apacheにmod_expiresモジュールがインストールされている必要があります。
    レンタルサーバーの場合、さくらやロリポップ!が対応しています。

    <ifModule mod_expires.c>
        #ブラウザキャッシュを使用
        ExpiresActive On
        ExpiresByType image/gif "access plus 1 weeks"
        ExpiresByType image/png "access plus 1 weeks"
        ExpiresByType image/jpeg "access plus 3 days"
        ExpiresByType text/css "access plus 1 weeks"
        ExpiresByType application/javascript "access plus 1 weeks"
    </ifModule>
    

    MIN Type → 有効期限の順に指定します。
    この指定では、gif, png, jpg, css, jsファイルに有効期限を設けブラウザキャッシュを有効にしています。

    有効期限の表し方には、次の単位が使用できます。

    • years
    • months
    • weeks
    • days
    • hours
    • minutes
    • seconds

    この指定を施した結果

    Expiresの指定を行った後、デバッグツールでページの読み込み速度を確認してみました。
    グレーで薄く304 Not Modifiedと表示されているファイルが既に有効期限内のキャッシュを持っておりリクエストを行っていないファイルです。

    Firebag

    これだけのリクエスト削減。素晴らしいですね。
    体感的にも「ローカル環境か?」と見紛うほど速度が上がっています。

    初めてサイトを訪れた方や直帰の一見さんには効果を体感してもらえませんが、教えてあげたいですね。
    「うちは2ページ目からがヤバイんすよ」て。

    7, 圧縮転送を有効にする

    ブラウザキャッシュが効果ありすぎて圧縮転送の威力が霞んで見えてきました。
    しかし、ブラウザキャッシュが「2ページ目から」ならこれは「1ページ目から」の対策です。

    圧縮してからファイルを転送することで、転送量を減らします。

    ※apacheにはmod_deflateモジュールがインストールされている必要があります。

    記述方法

    .htaccessにこのように記述します。

    <IfModule mod_deflate.c>
        SetOutputFilter DEFLATE
        AddOutputFilterByType DEFLATE text/plain
        AddOutputFilterByType DEFLATE text/html
        AddOutputFilterByType DEFLATE text/xml
        AddOutputFilterByType DEFLATE text/css
        AddOutputFilterByType DEFLATE application/xml
        AddOutputFilterByType DEFLATE application/xhtml+xml
        AddOutputFilterByType DEFLATE application/rss+xml
        AddOutputFilterByType DEFLATE application/javascript
        AddOutputFilterByType DEFLATE application/x-javascript
    </IfModule>
    

    圧縮を有効にしたことにより、当ブログではHTMLやCSSの転送量が2~4割ほど削減されました。

    光回線ではそこまで体感できるほどの速度差は得られませんでしたが、
    移動端末でMVMOを使用している場合や電波の悪い場所での通信など、速度が出ない環境でのアクセスでは数十KB単位の転送量削減が効いてくるのではないかと思います。

    レスポンスの高速化は人にもサーバにも優しい

    以上、ブログ高速化のために試してみて有効だった施策をまとめてみました。

    特にリクエスト数や転送量を削減する施策については読み込みを待つユーザーだけでなくサーバにも負担が減り、結果として発信者・受信者双方が幸せになれる素晴らしいアイデアだと思います。

    応答の速いサイトは検索エンジンにも好まれます。
    こうした施策は積極的に取り入れて行きたいですね。

    カテゴリー

    最近の記事

    Author

    • ささきち-このブログを書いてる人
      s3make@ささきち
      多摩川沿いに住むフリーのWebデザイナーです。近所のイオンによく行きます。