webhack / ウェブ技術が好き

javascriptやcssやHTML5とかサーバーサイド等のウェブ技術全般を好きに書くブログ

「Twitterで共有する」ボタンを高速・快適に表示するスクリプトの説明

f:id:tkosuga:20160731002044j:plain 写真はうちのみーこが子猫だった頃。

「ツイート」ボタンを表示しているサイトが抱える共通の課題に「ツイートボタンの表示が遅い&重い」があります。

ツイートボタンを外すと当然速くなりますがサイトへのトラフィックが減る事になるので本末転倒です。

この遅くなる&重く感じる理由は、ページ表示タイミングで各スクリプトの読み込みと初期化が一斉に行われている中でTwitterスクリプトも同じく読み込みと初期化が行われているためです。

ページを読み進めてツイートボタンが表示された時に初めて初期化するなど、ページ読み込み時ではなく任意のタイミングでTwitterスクリプトの読み込み・初期化・表示を行うとこの課題を解決できます。

以下、任意のタイミングでTwitterスクリプトを初期化してツイートボタン表示まで行うサンプルコードです。

    function initTwitterAPI(loadedHandler, clickHandler) {
      window.twttr = (function(d, s, id) {
        var js, fjs = d.getElementsByTagName(s)[0],
          t = window.twttr || {};
        if (d.getElementById(id)) return t;
        js = d.createElement(s);
        js.id = id;
        js.src = "https://platform.twitter.com/widgets.js";
        fjs.parentNode.insertBefore(js, fjs);

        t._e = [];
        t.ready = function(f) {
          t._e.push(f);
        };
        return t;
      }(document, "script", "twitter-wjs"));

      window.twttr.ready(function(twttr) {
        window.twttr.events.bind('loaded', function(event) {
          if (!event) return;
          loadedHandler(event);
        });
        window.twttr.events.bind('click', function(event) {
          if (!event) return;
          clickHandler(event);
        });
      });
    }
    setTimeout(function() { // 任意のタイミングを1.5秒後として初期化を行う。
      initTwitterAPI(
        function(event) {
          window.twttr.widgets.createShareButton(null, document.getElementById('twitter-share-button'));
        },
        function(event) {
          document.getElementById('twitter-share-thanks').innerHTML = "thank you your tweet!!";
        }
      );
    }, 1500);

個別に説明して行きます。まずTwitterAPI(platform.twitter.com/widgets.js)の初期化はSet-up Twitter for Websitesの内容ままです。 このコードは非同期に実行され初期化が終わるとTwitterAPIの twttr が利用できるようになります。

      window.twttr = (function(d, s, id) {
        var js, fjs = d.getElementsByTagName(s)[0],
          t = window.twttr || {};
        if (d.getElementById(id)) return t;
        js = d.createElement(s);
        js.id = id;
        js.src = "https://platform.twitter.com/widgets.js";
        fjs.parentNode.insertBefore(js, fjs);

        t._e = [];
        t.ready = function(f) {
          t._e.push(f);
        };
        return t;
      }(document, "script", "twitter-wjs"));

次にloadの完了とツイートボタンをclickした時のイベントを追加します。loadedHandler と clickHandler は初期化時に引数で指定しています。 このイベントはScripting: Eventsで説明されている内容です。 イベントの主な用途にはGoogleAnalyticsでツイートボタンをクリックされた回数をトラッキングする等があります。

      window.twttr.ready(function(twttr) {
        window.twttr.events.bind('loaded', function(event) {
          if (!event) return;
          loadedHandler(event);
        });
        window.twttr.events.bind('click', function(event) {
          if (!event) return;
          clickHandler(event);
        });
      });

任意のタイミングでTwitterAPIを初期化して同時に実行したいハンドラーを引数に指定します。

1つ目のハンドラー内でシェアボタンを動的に作ります。twttr.widgets.createShareButton はScripting: Factory FunctionsTweet Button JavaScript Factory Functionで説明されています。 2つ目のハンドラー内でツイートボタンを押してくれた人に向けて感謝のメッセージを動的に表示します。

      initTwitterAPI(
        function(event) {
          window.twttr.widgets.createShareButton(null, document.getElementById('twitter-share-button'));
        },
        function(event) {
          document.getElementById('twitter-share-thanks').innerHTML = "ツイートありがとう!!";
        }
      );

以上でツイートボタンを快適に表示できるようになりました。

すっきり。

CodePenにデモを設置しました。Run Penを押して挙動を確認して下さい。

codepen.io

この記事はレコーディングダイエットができるウェブアプリを開発した中で「Twitterで共有する」機能を実装している中で色々調べた内容をまとめたものです。

tkosuga.jp

インストール必要なしブラウザで動作するのでよかったら試して見て下さいね。