2013/01/16更新

[Web] ソーシャルボタンを設置するとページ表示が遅くなる理由、その対策方法

このエントリーをはてなブックマークに追加            

こんにちは、@yoheiMuneです。
ブログですごくお世話になるTwitterなどのソーシャルボタン。読んで頂いた方が情報発信したいと思ったときの手助けになるので大変重宝しています。
しかし、そのまま利用するとページの初期化が遅くなり(体感では2〜3秒遅くなる)、せっかく来て頂いたのに待たせることとなってしまう。

今回は、ソーシャルボタンを設置すると表示が遅くなる原因と、その対策案(2つ)をブログに書きたいと思います。

画像



ソーシャルボタンを設置するとページの初期表示が遅くなる原因

ソーシャルボタンは、TwitterやFacebookなどの各サイトでHTML/JSコードを入手することで、簡単に自身のサイトに導入することが可能です。 しかし入手したコードをそのままページに埋め込むと、初期表示が遅くなる。 遅くなる原因は、主に以下2つかと思います。

scriptタグの埋め込み
HTML内にscriptタグを埋め込むとページの描画が遅くなります。 描画処理中にscriptタグを発見すると、scriptタグがサーバーからロードされて解釈されて実行されるまで、scriptタグ以降の描画を停止します。 これは、scriptタグがdocument.writeなどのHTMLに影響を与える可能性があるため、scriptタグの挙動が分かるまで、描画処理は後続処理を始めたくないから。
つまりHTML内にscriptタグがあると、ページ描画のためにscriptタグをサーバーからロードする時間が必要となり、結果としてページの初期表示が遅くなります。


画像ロードやiframeのために、リクエスト数が消費される
これは非力な端末(iPhoneやAndroidのスマホなど)で問題になることで、初期化処理に必要なリクエスト本数が多いと、ページの初期表示が遅くなります。
特にスマホ端末では同時リクエスト数が制限されていることも多く、ソーシャルボタン初期化のためにリクエスト数を消費すると、ソーシャルボタン以外の部分の初期化が遅くなってしまいます。

他にも遅くなる原因があるかと思いますが、上記2つを対策できればいい感じにサイトが早くなるのではないかなぁと思います。 以下では、対策案を2つ書きたいと思います。

注)以下で紹介する解決策は一例です。他にももっと良い解決策があるかもしれないし、ソーシャルボタンがサイトでどれほど重視されるのかにより取る対策案も変わるかと思います。


対策1:ソーシャルボタンを遅延ロードする

1つ目の対策は、ソーシャルボタンを読み込む&表示するタイミングをページコンテンツ表示後に行うということです。 これによりページコンテンツ描画中にはソーシャルボタンに対する処理がなくなり、結果としてページ表示が早くなります。

具体的には以下のような実装を行います。
<div id="snsbox"><!-- ここにボタンが現れる --></div>



<script type="text/javascript">

// 最初に変数をまとめて定義
var google_btn, twitter_btn, facebook_btn, hatena_btn;

// google (ボタン作成サイトから、コピペするとシングルクオートなので注意)
// またscriptタグの終了タグはエスケープする必要がある。
google_btn = 
  '<div class="glbtn btn"><g:plusone size="medium" annotation="inline" width="90"></g:plusone></div> <script>window.___gcfg={lang:"ja"};(function(){var po=document.createElement("script");po.type="text/javascript";po.async=true;po.src="https://apis.google.com/js/plusone.js";var s=document.getElementsByTagName("script")[0];s.parentNode.insertBefore(po,s);})();<\/script>';

// はてな (wordpress使用のため、phpタグあり)
hatena_btn =
  '<div class="htbtn btn"><a href="//b.hatena.ne.jp/entry/<?php the_permalink(); ?>" class="hatena-bookmark-button" data-hatena-bookmark-title="<?php the_title(); ?>" data-hatena-bookmark-layout="standard" title="このエントリーをはてなブックマークに追加"><img src="//b.st-hatena.com/images/entry-button/button-only.gif" alt="このエントリーをはてなブックマークに追加" width="20" height="20" style="border: none;" /></a></div> <script type="text/javascript" src="//b.st-hatena.com/js/bookmark_button.js" charset="utf-8" async="async"><\/script>';

// Twitter
twitter_btn =
  '<div class="twbtn btn"><a href="https://twitter.com/share" class="twitter-share-button" data-via="ご自身のTwitterアカウント" data-lang="ja">ツイート</a></div> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");<\/script>';

// Facebook (wordpress使用のため、phpタグあり)
// appIdには自分のIDを設定する。
facebook_btn =
  '<div class="fbbtn btn"><iframe src="//www.facebook.com/plugins/like.php?href=<?php the_permalink(); ?>&send=false&layout=button_count&width=100&show_faces=true&action=like&colorscheme=light&font=arial&height=35&appId=XXXXXXXXXXXX" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px; height:21px;" allowTransparency="true"></iframe></div>';

// onload後に非同期で、 <div id="snsbox"></div> の中に上記をまとめて出現させる
window.addEventListener('load', function() {
  setTimeout(function(){
    $('#snsbox').append(google_btn + hatena_btn + twitter_btn + facebook_btn);
  },1000);  
});

</script>
引用元:http://fukuyama.co/lazyloadsns

ソーシャルボタンの内容をHTML文字列として結合して、そのHTML文字列をドバっとボタンの表示位置に流し込むように実装されています。 引用させて頂きました。ありがとうございます。



対策2:scriptタグを非同期に読み込む

上記の実装を行うには、それなりにJSとか書かなきゃ行けませんが、scriptタグの問題(レンダリング処理を停止する件)に対応することができます。 これだけ対応しても、いい感じにページ初期表示の高速化が期待できます。


実装方法は簡単で、scriptタグのasync属性を利用します。
async属性を付与すると、scriptのロードしながら後続処理のレンダリングも行われ、scriptタグ読み込みによるページ表示の遅延が軽減されます。
ただしasync属性を付与したscriptタグは、document.writeなどのページに書き込む系の処理が使えなかったり、 jQuery -> ページのJSの順でscriptタグを読み込みたい場合にも読み込み順序が保証されないという点があります。

具体的には、以下のように実装します。
(scriptタグをHTML内に埋め込んでいる場合)
<script type="text/javascript" src="http://b.st-hatena.com/js/bookmark_button.js" charset="utf-8" async="async"></script>

(JavaScriptでscriptタグを生成する場合)
// スクリプトタグを生成する。
var s = document.createElement('script');
s.src = '**** JSロード先のURL ****';
s.async = true;

// スクリプトタグを挿入する。
var fjs = document.getElementByTagName('script')[0];
fjs.parentNode.insertBefore(js,fjs);
上記のasync=trueとしている箇所がポイントです。
TwitterやFacebookのソーシャルボタンで「async=true」にすると早くなります。
想定通り動いているかは必ずご確認ください。

最後に

ブログ開設して1年3ヶ月くらい。そういえばソーシャルボタンが重たいなぁと思っていて、今回の調査を行いました。 せっかく訪れて頂いた方により快適にサイトを閲覧頂けるよう、今後も高速にしていきたいと思います。

最後までご覧頂きましてありがとうございました。





こんな記事もいかがですか?

RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。