Physical Address

304 North Cardinal St.
Dorchester Center, MA 02124

延遲載入 Google Maps 的 2 種方法

大家好,我是 Eric。

在 2020 年底,最後一次公司網站的小改版中,為了改善 Google Page Speed Insights 的成績,因此研究了應該要如何延遲載入 (lazy loading) Google Maps。

先展示一下調整前後的主要差異:

延遲載入 Google Maps 前與延遲載入後,消除相關警示。

這邊提供兩種方式,第一種是直接透過 iframe 來嵌入,第二種則是藉由 Google Maps JavaScript API 來嵌入。

利用 iframe 嵌入 Google Maps

如果你是透過 iframe 的方式載入,那你可以搭配 JavaScript 函式庫 Lozad.js,修改你的 HTML 代碼,加入 class="lozad" 的 CSS 類別,並將 src 屬性改為 data-src

<iframe data-src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3614.57069363609!2d121.53048741480356!3d25.048639283965496!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x3442a963ea71d813%3A0xa128c180fb94071f!2zMTA0OTHlj7DljJfluILkuK3lsbHljYDmnb7msZ_ot681NOiZnw!5e0!3m2!1szh-TW!2stw!4v1609558378050!5m2!1szh-TW!2stw"
        width="600"
        height="450"
        frameborder="0"
        style="border:0;"
        allowfullscreen=""
        aria-hidden="false"
        tabindex="0"
        class="lozad"></iframe>

接著在你的子佈景主題,或是網站專案的主要 JavaScript 檔中,初始化 Lozad.js 即可:

const observer = lozad();
// lazy loads elements with default selector as '.lozad'
observer.observe();

利用 Google Maps JavaScript API 嵌入

事實上,ScrollTrigger 並非是作為延遲載入的正規方式。今天會使用 ScrollTrigger,最主要是因為我們公司網站同時使用了 GSAP 作為動畫的解決方案。因此如果希望循正規方式設定延遲載入的,請參考 Observer API 的相關文件。

ScrollTrigger 可以用於偵測瀏覽器的捲動深度,並根據捲動深度觸發相對應的動畫。而正因為是透過 trigger: '選擇器' 作為觸發條件,因此也可以做到「看到特定元素時,執行特定函式」的功用。

記住,如果你的網站沒有使用 GSAP 做動態效果,你不需要,也不應該為了延遲載入 Google Maps 而使用 ScrollTrigger。

關於如何利用 JavaScript API 嵌入 Google Maps,可以參考這篇文章

首先在頁面中加入 HTML 標記:

<div id="map" style="height: 500px; width: 500px;">
</div>

接著插入觸發條件,以及回傳值的函式。

/**
 * 設定觸發條件
 */
ScrollTrigger.create({
	trigger: '#map', // 捲動到 div#map 的時候觸發
	once: true, // 只觸發一次
	start: 'top bottom', // div#map 的頂端 (top) 碰觸到畫面底端 (bottom) 時
	onEnter: (self) => { // 進入觸發條件時,呼叫函式
		loadGoogleMap(document);
	},
});

/**
 * 載入 Google Maps 的函式庫。
 * param string d 是 document
 */
function loadGoogleMap( d ) {
  const gm = d.createElement('script'),
		s = d.scripts[0];
	gm.src =
		'https://maps.googleapis.com/maps/api/js?key={{你的 API Key}}&callback=initMap';
	gm.defer = true;
	s.parentNode.insertBefore(gm, s);
}

/**
 * 繪製 Google Maps 的函式,作為函式庫回傳的對象。
 */
function initMap() {
  const ll = new google.maps.LatLng(25.048639, 121.532676),
		map = new google.maps.Map(document.getElementById('map'), {
			zoom: 14, // 放大範圍
			center: ll, // 地圖中心
		}),
		marker = new google.maps.Marker({
			position: ll,
			map,
		}),
		mapStyle = [
			{
				stylers: [
					{
						saturation: -100,
					},
				],
			},
		],
		mapType = new google.maps.StyledMapType(mapStyle);
	map.mapTypes.set('GrayScaleMap', mapType); // 設為灰階地圖
	map.setMapTypeId('GrayScaleMap');
}

結語

如同前面所說的,如果真的要循正規方式實作 Google Maps 的延遲載入,需要透過 Observer API 或者 addEventListener 的方式來進行。但是因為我自己對於 Observer API 還不熟悉,加上剛好公司網站使用了 GSAP,所以用了這種略微偏門,但是可以達到一樣效果的作法。

另外,除了 onEnter 之外,ScrollTrigger 也針對不同的觸發階段,提供了不同的方法來呼叫其他函式,包含 onEnterBack (從觸發處的終點倒轉)、onLeave (觸發元素的終點完全離開可視區)、onLeaveBack (觸發元素的起點完全離開可視區) 等。〈使用 GSAP 的 ScrollTrigger 製作捲動動畫〉一文中介紹的計數器效果,則是利用 onUpdate 的方式,來偵測動態數值。

參考資料

Eric Chuang
Eric Chuang

正職是廣告行銷人員,因為 Google Tag Manager 的關係開始踏入網站製作的領域,進一步把 WordPress 當成 PHP + HTML + CSS + JavaScript 的學習教材。此外,因為工作的關係,曾經用 Automattic 的 Underscores (_s) 替客戶與公司官網進行全客製化佈景主題開發。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料