
LazyLoad GoogleMap
2020年9月9日 • ☕️ 3 min read
地図付きのウェブページと言えば、GoogleMapでしょう。GoogleMapApiが簡単で使いやすくとても助かります。ただし、GoogleMapの導入により、ウェブページのパフォーマンス(ローディングスピード)の落ちることに注意しなければいけません。
問題
一般的な使い方
<script src="https://maps.googleapis.com/maps/api/js?key=xxxxxxxx"></script>
<scrip>
  const mapObject = new google.maps.Map(document.getElementById("map"));
</script>
検出方法:Lighthouseまたhttps://web.dev。
デフォルトでGoogleMapApiをincludeするとLighthouse Reportに下記の問題が生じます。
第三者のライブラリのincludeによりローディングスピードの低下
ユーザがウェブサイトにアクセスするとき、第三者のライブラリを第三者のCDNからダウンロードする必要があります。ライブラリのサイズにより時間がかかったりします。

ローディングした画面に非表示の項目なのに、ロードされた
地図の部分はスクロールしないと見えない部分なので、見えないところのデカいイメージをローディング時ダウンロードする必要がないということです。

解決
問題1:async deferにより重要性の低いライブラリを最後にロード
これはGoogle社の推奨する対策となります。
それはscriptリンクにasync、deferおよびcallbackの追加により、ロード順位を最下位へまわることです。
<scrip>
  // ローディング完了後のcallbackの定義
  function initMap() {
    const mapObject = new google.maps.Map(document.getElementById("map"));
  }
</script>
<script defer async src="https://maps.googleapis.com/maps/api/js?key=xxxxxxxx&callback=initMap"></script>
問題2:LazyLoadによりライブラリを必要な時だけロード
地図をロードした後すぐに表示しなければいけないケースが少ないでしょう。ほとんどの位置付けはページ中の会社場所などの一部となります。
なので、地図の部分にスクロールしたら表示しても遅くありません。
今回はIntersection Observer APIを使ってLazyLoadを簡単に実装してみましょう。
jQueryのgetScriptを使用
<script>
// <script src="xxxxx"></script> でライブラリのincludeは不要
function initMap() {
  const mapObject = new google.maps.Map(document.getElementById("map"));
}
$(document).ready(function () {
  const mapOb = new IntersectionObserver(
      (entries, ob) => {
        entries.forEach( entry =>{
          // 表示されたらGoogleMapAPIをロード
          if(entry.isIntersecting){
            $.getScript('https://maps.googleapis.com/maps/api/js?key=xxxxxxxx&callback=initMap');
            ob.disconnect();
          }
        });
      },
      {
        rootMargin: '100px'
      }
  );
  // id=mapのDOM位置を監視
  mapOb.observe(document.getElementById("map"));
});
</script>
完了
これで全ての問題を解決できました。Lighthouseのパフォーマンススコアも10数点上がるでしょう。
改善した効果のスクリーンショットはこちら。


Blog part of ThunderMiracle.com
コメントは表示領域に入ると読み込みます