From edd51b7097c92191669b84b5e718dead52a6ee9d Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Sun, 26 Jun 2022 11:26:59 +0200 Subject: [PATCH] build: load Google Maps and YouTube APIs on demand in dev app Only loads the Google Maps and YouTube APIs when they are necessary in the dev app. This will make the app load quicker and reduce the amount of logs in the console. --- src/dev-app/google-map/google-map-demo.html | 3 +- src/dev-app/google-map/google-map-demo.ts | 51 ++++++++++++++++--- src/dev-app/index.html | 13 ----- .../youtube-player/youtube-player-demo.ts | 14 ++++- 4 files changed, 59 insertions(+), 22 deletions(-) diff --git a/src/dev-app/google-map/google-map-demo.html b/src/dev-app/google-map/google-map-demo.html index 60440a485e98..9bb8317d2ab6 100644 --- a/src/dev-app/google-map/google-map-demo.html +++ b/src/dev-app/google-map/google-map-demo.html @@ -1,4 +1,5 @@ -
+
Loading Google Maps API...
+
| null = null; + /** Demo Component for @angular/google-maps/map */ @Component({ selector: 'google-map-demo', @@ -96,6 +98,7 @@ export class GoogleMapDemo { }; isGroundOverlayDisplayed = false; + hasLoaded: boolean; groundOverlayImages = [ { title: 'Red logo', @@ -116,19 +119,16 @@ export class GoogleMapDemo { isBicyclingLayerDisplayed = false; mapTypeId: google.maps.MapTypeId; - mapTypeIds = [ - google.maps.MapTypeId.HYBRID, - google.maps.MapTypeId.ROADMAP, - google.maps.MapTypeId.SATELLITE, - google.maps.MapTypeId.TERRAIN, - ]; + mapTypeIds = ['hybrid', 'roadmap', 'sattelite', 'terrain'] as google.maps.MapTypeId[]; markerClustererImagePath = 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'; directionsResult?: google.maps.DirectionsResult; - constructor(private readonly _mapDirectionsService: MapDirectionsService) {} + constructor(private readonly _mapDirectionsService: MapDirectionsService) { + this._loadApi(); + } authFailure() { console.log('Auth failure event emitted'); @@ -257,4 +257,41 @@ export class GoogleMapDemo { return result; } + + private _loadApi() { + this.hasLoaded = !!window.google?.maps; + + if (this.hasLoaded) { + return; + } + + if (!apiLoadingPromise) { + // Key can be set through the `GOOGLE_MAPS_KEY` environment variable. + const apiKey: string | undefined = (window as any).GOOGLE_MAPS_KEY; + + apiLoadingPromise = Promise.all([ + this._loadScript( + `https://maps.googleapis.com/maps/api/js?libraries=visualization${ + apiKey ? `&key=${apiKey}` : '' + }`, + ), + this._loadScript('https://unpkg.com/@googlemaps/markerclustererplus/dist/index.min.js'), + ]); + } + + apiLoadingPromise.then( + () => (this.hasLoaded = true), + error => console.error('Failed to load Google Maps API', error), + ); + } + + private _loadScript(url: string): Promise { + return new Promise((resolve, reject) => { + const script = document.createElement('script'); + script.src = url; + script.addEventListener('load', resolve); + script.addEventListener('error', reject); + document.body.appendChild(script); + }); + } } diff --git a/src/dev-app/index.html b/src/dev-app/index.html index b02a2bafb2c9..67ea3ff04fcc 100644 --- a/src/dev-app/index.html +++ b/src/dev-app/index.html @@ -17,20 +17,7 @@ Loading... - - - - diff --git a/src/dev-app/youtube-player/youtube-player-demo.ts b/src/dev-app/youtube-player/youtube-player-demo.ts index 4befbd9a0b01..81fe178e0b61 100644 --- a/src/dev-app/youtube-player/youtube-player-demo.ts +++ b/src/dev-app/youtube-player/youtube-player-demo.ts @@ -53,7 +53,9 @@ export class YouTubePlayerDemo implements AfterViewInit, OnDestroy { videoWidth: number | undefined; videoHeight: number | undefined; - constructor(private _changeDetectorRef: ChangeDetectorRef) {} + constructor(private _changeDetectorRef: ChangeDetectorRef) { + this._loadApi(); + } ngAfterViewInit(): void { this.onResize(); @@ -70,4 +72,14 @@ export class YouTubePlayerDemo implements AfterViewInit, OnDestroy { ngOnDestroy(): void { window.removeEventListener('resize', this.onResize); } + + private _loadApi() { + if (!window.YT) { + // We don't need to wait for the API to load since the + // component is set up to wait for it automatically. + const script = document.createElement('script'); + script.src = 'https://www.youtube.com/iframe_api'; + document.body.appendChild(script); + } + } }