Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
大家好,我是 Eric。
在 2020 年底,最後一次公司網站的小改版中,為了改善 Google Page Speed Insights 的成績,因此研究了應該要如何延遲載入 (lazy loading) Google Maps。
先展示一下調整前後的主要差異:
這邊提供兩種方式,第一種是直接透過 iframe
來嵌入,第二種則是藉由 Google Maps JavaScript API 來嵌入。
內容目錄
如果你是透過 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();
事實上,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
的方式,來偵測動態數值。