Angular で Google Maps API を遅延ロード

Yusuke Wakui
nextbeat-engineering
Sep 14, 2021

はじめまして、ネクストビートで保育士就活バンク!の開発を担当している涌井と申します。

今回はAngularでGoogle Maps API を非同期で読み込む方法を紹介します。 GoogleMapsのパッケージは @angular/google-maps を利用しています。

Google Maps API の一般的な読み込み方法は HTML の head 要素内で script タグに記述する方法です。

しかしこの方法では次の要件が実現できませんでした。

  • パフォーマンスの観点から、Google Maps API を利用する直前に読み込みたい。
  • APIキーを開発環境と本番環境で動的に変更したい。

そこで、遅延ロードする方法を調査しました。

公式ドキュメントには Component のコンストラクタで読み込む方法が紹介されています。

実はこの方法には欠点があり、 Component が破棄されたあと、再作成されるとコンソールにエラーが表示されます。

You have included the Google Maps JavaScript API multiple times on this page. This may cause unexpected errors.

このページでは、Google Maps JavaScript APIを複数回使用しています。これにより予期せぬエラーが発生する可能性があります。

試行錯誤を重ねてAPIの最初の1度だけ読み込む Module を作成しました。

ポイントは loadMapsApishareReplay です。

これによって、2回目以降に subscribe されたときに、Google Maps API の読み込みを実行しないようにしています。

Component での使い方は次のとおりです。

コンストラクタで MAPS_API_LOADED を注入することで、 apiLoaded でAPIのロード状態を読み込めます。

constructor(@Inject(MAPS_API_LOADED) public apiLoaded) {
}

*ngIf でAPIの読み込みに成功した場合のみ google-map を表示するようにしています。

<google-map *ngIf="apiLoaded | async"></google-map>

実際に動かしてみました。

ボタンを押す度に Component は再作成されていますが、コンソールにはエラーが出ません。

これで、Angular で Google Maps API を遅延ロードできました。

まさかの公式ドキュメントの実装でエラーが吐かれ、思わぬ時間がかかってしまいましたが、 InjectionTokenshareReplay の使い方を知ることができました。

最後まで読んでいただきありがとうございました。

We are hiring!

株式会社ネクストビートでは

「人口減少社会において必要とされるインターネット事業を創造し、ニッポンを元気にする。」
を理念に掲げ一緒に働く仲間を募集しております。

https://www.nextbeat.co.jp/recruit

参考サイト

--

--