Bloggerのコメント欄を改善する

Blogger高速化の一環として実施したコメント欄の改善についてです。

不満点

  • 埋め込み
    • 標準では、高さが足りずスクロールバーを表示する
    • スクリプトで表示するとiframeの領域が大きすぎることがある
    • 標準では、外部スクリプト(comment_from_post_iframe.js)を読み込む
      • ページの読み込みが遅延する
    • ページ読み込み時にiframeを読み込む
      • 閲覧者の99%は使用しないが、ページ読み込みを遅延する
      • 閲覧者の99%は使用しないが、コメント記入欄を表示する
  • ポップアップ
    • ポップアップにコメントが表示される
      • コメントは、ページ側に表示しているため、重複してしまう
    • モバイルでは、強制的に埋め込みとなる
  • フルページ
    • 外部ページに移動する
  • 共通
    • blogger.comのスクリプトを有効にする必要がある

改善

  • 埋め込みを使用する
  • 高さを決め打ちで確保してスクロールバーの表示を抑制する
    • Google未ログイン時は、あきらめる
  • 外部スクリプトなしで動作するようにする
    • ただし、リプライ(返信)機能を使用できない
  • コメント記入要求(クリック)があってからiframeを読み込む
    • ただし、要求からiframeの読み込みまで一定時間遅延する
  • コメント記入要求(クリック)がなくても、表示領域内に入った場合、読み込む
    • IntersectionObserver有効時

結果

コメント投稿

コメント欄

※実物がページ下部で動作しているはずなのでそちらを参照
※見た目は、一部異なります

変更例

<b:includable id='comment-form' var='post'>
  <div class='comment-form'>
    <a class='template-link comment-form-btn' href='javascript:void(0);' id='comment-form-btn'>
      コメントを書く<noscript>には、JavaScriptを有効にする必要があります</noscript>
    </a>
    <iframe allowtransparency='true' class='blogger-iframe-colorize blogger-comment-from-post' frameborder='0' id='comment-editor' name='comment-editor' role='form' src='' style='display:none; min-height:192px;' width='100%' expr:data-src='data:post.commentFormIframeSrc'/>
  </div>
</b:includable>

<b:includable id='comment-form' var='post'>内を置き換える


(function(document, window) {
  let isLoad = false;

  // コメントフォームの読み込み
  function onLoadCommentForm() {
    if (!isLoad) {
      isLoad = true;

      // コメントフォームボタンを非表示
      document.getElementById('comment-form-btn').hidden = true;

      // コメントエディタを読み込む
      const editor = document.getElementById('comment-editor');
      editor.addEventListener('load', function() {
        editor.style.display = 'block';
      });
      editor.src = editor.dataset.src;
    }
  }

  function main() {
    const btn = document.getElementById('comment-form-btn');
    if (btn) {
      // コメントフォームボタンをクリックした場合、コメントフォームを読み込む
      // IntersectionObserver非対応時の保険
      btn.addEventListener('click', onLoadCommentForm);

      // コメントフォームボタンが領域内に入った場合、コメントフォームを読み込む
      if ('IntersectionObserver' in window) {
        new IntersectionObserver(function(entries, observer) {
          // 登録後、intersectionRatio=0で一旦発火する
          if (entries[0].intersectionRatio != 0) {
            onLoadCommentForm();

            // 監視を終了する
            observer.disconnect();
          }
        }).observe(btn);
      }
    }
  }

  main();
  //window.addEventListener('lazy', main);
})(document, window);
//<iframe allowtransparency='true' class='blogger-iframe-colorize blogger-comment-from-post' frameborder='0' id='comment-editor' name='comment-editor' role='form' src='' style='display:none; min-height:192px;' width='100%' expr:data-src='data:post.commentFormIframeSrc'/>

</body>直前などに配置する