טעינת Maps JavaScript API

במדריך הזה מוסבר איך לטעון את Maps JavaScript API. יש שלוש דרכים לעשות את זה:

שימוש בייבוא ספרייה דינמית

ייבוא דינמי של ספריות מאפשר לטעון ספריות בזמן הריצה. כך אפשר לבקש את הספריות הנדרשות ברגע שצריך אותן, במקום לטעון את כולן בבת אחת. הוא גם מונע טעינה של Maps JavaScript API כמה פעמים בדף.

כדי לטעון את Maps JavaScript API, מוסיפים את רכיב הטעינה להפעלת API בתוך השורה לקוד האפליקציה, כמו שמוצג בקטע הקוד הבא:

<script>
  (g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
    key: "YOUR_API_KEY",
    v: "weekly",
    // Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
    // Add other bootstrap parameters as needed, using camel case.
  });
</script>

אפשר גם להוסיף את קוד רכיב הטעינה להפעלת ה-API ישירות לקוד ה-JavaScript.

כדי לטעון ספריות בזמן הריצה, משתמשים באופרטור await כדי להפעיל את importLibrary() מתוך פונקציית async. הצהרה על משתנים למחלקות הנדרשות מאפשרת לכם לדלג על השימוש בנתיב מוגדר (למשל google.maps.Map), כמו שמוצג בדוגמת הקוד הבאה:

async function init() {
    // Import the needed libraries.
    await google.maps.importLibrary('maps');

    // Access the map.
    const mapElement = document.querySelector('gmp-map');
    // Access the underlying map object.
    const innerMap = mapElement.innerMap;

    console.log({ mapElement, innerMap });
}

void init();

אם האפליקציה צריכה כמה ספריות בו-זמנית, משתמשים ב-Promise.all() כדי לבקש אותן במקביל:

const [{ Place }, { AdvancedMarkerElement }] = await Promise.all([
  google.maps.importLibrary('places'),
  google.maps.importLibrary('marker'),
]);

אל תפעילו את await google.maps.importLibrary() בשורות נפרדות ברצף. הצהרות await עוקבות חוסמות את ההפעלה עד שכל ספרייה מסיימת את ההורדה וההפעלה לפני שהיא מבקשת את הספרייה הבאה, ויוצרות מפל מים ברשת שמגדיל את זמן הטעינה. הפונקציה Promise.all() מתחילה את כל ההורדות של הספרייה בו-זמנית, ומסתיימת ברגע שכולן מוכנות.

הפונקציה יכולה גם לטעון ספריות בלי להצהיר על משתנה למחלקות הנדרשות. זה שימושי במיוחד אם הוספתם מפה באמצעות הרכיב gmp-map. בלי המשתנה, צריך להשתמש בנתיבים מלאים, לדוגמה google.maps.Map:

let map;
let center =  { lat: -34.397, lng: 150.644 };

async function initMap() {
  await Promise.all([
    google.maps.importLibrary("maps"),
    google.maps.importLibrary("marker"),
  ]);

  map = new google.maps.Map(document.getElementById("map"), {
    center,
    zoom: 8,
    mapId: "DEMO_MAP_ID",
  });

  addMarker();
}

async function addMarker() {
  const marker = new google.maps.marker.AdvancedMarkerElement({
    map,
    position: center,
  });
}

initMap();

אפשר גם לטעון את הספריות ישירות ב-HTML, כמו שמוצג כאן:

<script>
google.maps.importLibrary("maps");
google.maps.importLibrary("marker");
</script>

איך עוברים ל-Dynamic Library Loading API

פרמטרים נדרשים

  • ‫key: מפתח ה-API שלכם. כדי לטעון את Maps JavaScript API, צריך לציין מפתח API תקין.

פרמטרים אופציונליים

  • ‫v: הגרסה של Maps JavaScript API שרוצים לטעון. אם לא תציינו במפורש ערוץ או גרסה, תקבלו את הערוץ השבועי כברירת מחדל. אם עברתם מתוכנית הפרימיום ולא ציינתם במפורש ערוץ או גרסה, תקבלו את הערוץ הרבעוני כברירת מחדל. אם תציינו גרסה לא חוקית, תקבלו את הערוץ שמוגדר כברירת מחדל. מידע נוסף

  • ‫libraries: מערך של ספריות נוספות של Maps JavaScript API שרוצים להתחיל לטעון מראש. בדרך כלל לא מומלץ לציין קבוצה קבועה של ספריות, אבל האפשרות הזו זמינה למפתחים שרוצים לשנות את התנהגות השמירה במטמון באתר שלהם. עדיין חשוב להפעיל את google.maps.importLibrary() לכל ספרייה שנבחרה לפני השימוש.

  • ‫language: השפה שבה רוצים להשתמש. השפה משפיעה על השמות של אמצעי הבקרה, הודעות על זכויות יוצרים, מסלולי נסיעה, תוויות של אמצעי בקרה ותגובות לבקשות שירות. כאן אפשר לעיין ברשימת השפות הנתמכות.

  • ‫region: קוד האזור שבו רוצים להשתמש. ההגדרה הזו משנה את ההתנהגות של ה-API בהתאם למדינה או לאזור נתונים.

  • ‫authReferrerPolicy: לקוחות של Maps JS יכולים להגדיר הגבלות על מפנים מסוג HTTP במסוף Cloud, כדי להגביל את כתובות ה-URL שמותר להן להשתמש במפתח API מסוים. כברירת מחדל, אפשר להגדיר את ההגבלות האלה כך שרק נתיבים מסוימים יוכלו להשתמש במפתח API. אם כתובת URL כלשהי באותו דומיין או מקור יכולה להשתמש במפתח ה-API, אתם יכולים להגדיר את authReferrerPolicy: "origin" כדי להגביל את כמות הנתונים שנשלחים כשמאשרים בקשות מ-Maps JavaScript API. כשמציינים את הפרמטר הזה ומפעילים את ההגבלות על מפנים ב-HTTP במסוף Cloud, אפשר לטעון את Maps JavaScript API רק אם יש הגבלה על מפנים ב-HTTP שתואמת לדומיין של האתר הנוכחי בלי לציין נתיב.

  • ‫mapIds: מערך של מזהי מפות. גורם לטעינה מראש של ההגדרות של מזהי המפות שצוינו. לא חובה לציין כאן מזהי מפות כדי להשתמש בהם, אבל האפשרות הזו זמינה למפתחים שרוצים לשפר את ביצועי הרשת.

  • ‫channel: ראו מעקב אחרי השימוש בכל ערוץ.

שימוש בתג לטעינה ישירה של סקריפט

בקטע הזה מוסבר איך להשתמש בתג לטעינה ישירה של סקריפט. הסקריפט הישיר טוען ספריות כשהמפה נטענת, ולכן הוא יכול לפשט מפות שנוצרו באמצעות רכיב gmp-map, כי לא צריך לבקש ספריות באופן מפורש בזמן הריצה. מכיוון שתג הטעינה הישירה של הסקריפט טוען את כל הספריות המבוקשות בבת אחת כשהסקריפט נטען, יכול להיות שהביצועים של אפליקציות מסוימות יושפעו. צריך לכלול את התג לטעינה ישירה של סקריפט רק פעם אחת בכל טעינת דף.

הוספת תג סקריפט

כדי לטעון את Maps JavaScript API בתוך קובץ HTML, מוסיפים תג script כמו שמוצג בהמשך.

<script async
    src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&loading=async&callback=initMap">
</script>

פרמטרים של כתובת URL לטעינת סקריפט ישירה

בקטע הזה מפורטים כל הפרמטרים שאפשר לציין במחרוזת השאילתה של כתובת ה-URL לטעינת הסקריפט, כשאתם טוענים את Maps JavaScript API. חלק מהפרמטרים הם חובה וחלק הם אופציונליים. כמו בכתובות URL רגילות, כל הפרמטרים מופרדים באמצעות התו אמפרסנד (&).

בכתובת ה-URL לדוגמה הבאה יש פלייסהולדרים לכל הפרמטרים האפשריים:

https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY
&loading=async
&callback=FUNCTION_NAME
&v=VERSION
&libraries="LIBRARIES"
&language="LANGUAGE"
&region="REGION"
&auth_referrer_policy="AUTH_REFERRER_POLICY"
&map_ids="MAP_IDS"
&channel="CHANNEL"
&solution_channel="SOLUTION_IDENTIFIER"

כתובת ה-URL בתג script שבדוגמה הבאה טוענת את Maps JavaScript API:

<script async
    src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&loading=async&callback=initMap">
</script>

פרמטרים נדרשים (ישירים)

כשאתם טוענים את Maps JavaScript API, אתם צריכים להגדיר את הפרמטרים הבאים.

  • ‫key: מפתח ה-API שלכם. ‫Maps JavaScript API לא ייטען אם לא תציינו מפתח API תקין.

פרמטרים אופציונליים (ישירים)

אתם יכולים להשתמש בפרמטרים האלה כדי לבקש גרסה ספציפית של Maps JavaScript API, לטעון ספריות נוספות, להתאים את המפה לשוק המקומי או לציין את המדיניות לבדיקת הגורם המפנה מסוג HTTP.

  • ‫loading: אסטרטגיית טעינת הקוד שבה Maps JavaScript API יכול להשתמש. מגדירים את הערך async כדי לציין ש-Maps JavaScript API לא נטען באופן סינכרוני, ושקוד JavaScript לא מופעל על ידי האירוע load של הסקריפט. כדי לשפר את הביצועים, מומלץ מאוד להגדיר את הערך async כשאפשר. (במקום זאת, השתמשו בפרמטר callback כדי לבצע פעולות כש-Maps JavaScript API זמין). זמין החל מגרסה 3.55.

  • ‫callback: השם של פונקציה גלובלית שתיקרא אחרי ש-Maps JavaScript API ייטען במלואו.

  • ‫v: הגרסה של Maps JavaScript API שבה רוצים להשתמש.

  • ‫libraries: רשימה מופרדת בפסיקים של ספריות נוספות של Maps JavaScript API שרוצים לטעון.

  • ‫language: השפה שבה רוצים להשתמש. השפה משפיעה על השמות של אמצעי הבקרה, הודעות על זכויות יוצרים, מסלולי נסיעה ותוויות של אמצעי בקרה, וגם על התשובות לבקשות שירות. כאן אפשר לעיין ברשימת השפות הנתמכות.

  • ‫region: קוד האזור שבו רוצים להשתמש. הפרמטר הזה משנה את ההתנהגות של ה-API בהתאם למדינה או לאזור שצוינו.

  • ‫auth_referrer_policy: לקוחות יכולים להגדיר הגבלות על מפנים ב-HTTP במסוף Cloud, כדי להגביל את כתובות ה-URL שמותר להן להשתמש במפתח API מסוים. כברירת מחדל, אפשר להגדיר את ההגבלות האלה כך שרק נתיבים מסוימים יוכלו להשתמש במפתח API. אם כל כתובת URL באותו דומיין או מקור יכולה להשתמש במפתח ה-API, אתם יכולים להגדיר את auth_referrer_policy=origin כדי להגביל את כמות הנתונים שנשלחים כשמאשרים בקשות מ-Maps JavaScript API. האפשרות הזו זמינה החל מגרסה 3.46. אם הפרמטר הזה מצוין וההגבלות על מפנים ב-HTTP מופעלות במסוף Cloud, אפשר יהיה לטעון את Maps JavaScript API רק אם יש הגבלה על מפנים ב-HTTP שתואמת לדומיין של האתר הנוכחי בלי לציין נתיב.

  • ‫map_ids: רשימה מופרדת בפסיקים של מזהי מפות. גורם לטעינה מראש של ההגדרות של מזהי המפות שצוינו. לא חובה לציין כאן מזהי מפות כדי להשתמש בהם, אבל האפשרות הזו זמינה למפתחים שרוצים לשפר את ביצועי הרשת.

  • channel: ראו מעקב אחרי השימוש בכל ערוץ.

שימוש בחבילת NPM ‏js-api-loader

החבילה ‎@googlemaps/js-api-loader זמינה לטעינה באמצעות מנהל החבילות של NPM. מתקינים אותו באמצעות הפקודה הבאה:

npm install @googlemaps/js-api-loader

מייבאים את החבילה כמו שמוצג כאן:

TypeScript

// Import the needed libraries.
import { setOptions, importLibrary } from '@googlemaps/js-api-loader';

JavaScript

// Import the needed libraries.
import { setOptions, importLibrary } from '@googlemaps/js-api-loader';

הטוען משתמש ב-Promises כדי להפוך ספריות לזמינות. טוענים ספריות באמצעות השיטה importLibrary(). בדוגמה הבאה מוצג שימוש ב-loader כדי לטעון מפה:

TypeScript

// Import the needed libraries.
import { setOptions, importLibrary } from '@googlemaps/js-api-loader';

const API_KEY = 'GOOGLE_MAPS_API_KEY';

async function init(): Promise<void> {
    // Set loader options.
    setOptions({
        key: API_KEY,
    });

    // Load the Maps library.
    const { Map } = await importLibrary('maps');

    // Set map options.
    const mapOptions = {
        center: { lat: 48.8566, lng: 2.3522 },
        zoom: 3,
    };

    // Declare the map.
    new Map(document.getElementById('map')!, mapOptions);
}

void init();

JavaScript

// Import the needed libraries.
import { setOptions, importLibrary } from '@googlemaps/js-api-loader';

const API_KEY = 'GOOGLE_MAPS_API_KEY';

async function init() {
    // Set loader options.
    setOptions({
        key: API_KEY,
    });

    // Load the Maps library.
    const { Map } = await importLibrary('maps');

    // Set map options.
    const mapOptions = {
        center: { lat: 48.8566, lng: 2.3522 },
        zoom: 3,
    };

    // Declare the map.
    new Map(document.getElementById('map'), mapOptions);
}

void init();

הקוד המלא לדוגמה

מעבר ל-Dynamic Library Import API

בקטע הזה מוסבר איך להעביר את השילוב לשימוש ב-Dynamic Library Import API.

שלבי ההעברה

קודם כול, מחליפים את התג לטעינה ישירה של סקריפט בתג של רכיב טעינה להפעלת API מוטבע.

לפני

<script async
    src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&loading=async&libraries=maps&callback=initMap">
</script>

אחרי

<script>
  (g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
    key: "YOUR_API_KEY",
    v: "weekly",
    // Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
    // Add other bootstrap parameters as needed, using camel case.
  });
</script>

בשלב הבא, מעדכנים את קוד האפליקציה:

  • משנים את הפונקציה initMap() לפונקציה אסינכרונית.
  • מפעילים את importLibrary() כדי לטעון את הספריות שצריך ולגשת אליהן.

לפני

let map;

function initMap() {
  map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: -34.397, lng: 150.644 },
    zoom: 8,
  });
}

window.initMap = initMap;

אחרי

let map;
// initMap is now async
async function initMap() {
    // Request libraries when needed, not in the script tag.
    const { Map } = await google.maps.importLibrary("maps");
    // Short namespaces can be used.
    map = new Map(document.getElementById("map"), {
        center: { lat: -34.397, lng: 150.644 },
        zoom: 8,
    });
}

initMap();

טעינה של כמה ספריות

כדי לטעון יותר מספרייה אחת, משתמשים ב-Promise.all() כדי לבקש את הספריות במקביל ולפרק את המחלקות שמוחזרות:

const [{ Place }, { AdvancedMarkerElement }] = await Promise.all([
  google.maps.importLibrary('places'),
  google.maps.importLibrary('marker'),
]);

אל תטענו ספריות באופן סדרתי על ידי שרשור של הצהרות await נפרדות:

// Avoid loading libraries serially:
const { Place } = await google.maps.importLibrary('places');
const { AdvancedMarkerElement } = await google.maps.importLibrary('marker');

כשמפעילים את await לכל קריאה ל-importLibrary() בזו אחר זו, הבקשה השנייה לספרייה לא מתחילה עד שהספרייה הראשונה מסיימת את ההורדה וההפעלה. שימוש ב-Promise.all() מפעיל את כל הבקשות לספרייה בו-זמנית, וכך מפחית את זמן האחזור ברשת ומשפר את מהירות האתחול.