地図付きのウェブページと言えば、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数点上がるでしょう。
改善した効果のスクリーンショットはこちら。