טעינת Maps JavaScript API

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

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

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

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

<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 Referrer מופעלות ב-Cloud Console, אפשר לטעון את Maps JavaScript API רק אם יש הגבלה של HTTP Referrer שתואמת לדומיין הנוכחי של האתר בלי לציין נתיב.

  • ‫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>

פרמטרים נדרשים (ישירים) {:.hide-from-toc}

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

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

פרמטרים אופציונליים (ישירות) {:.hide-from-toc}

אפשר להשתמש בפרמטרים האלה כדי לבקש גרסה ספציפית של 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 Referrer ב-מסוף Cloud, אפשר לטעון את Maps JavaScript API רק אם יש הגבלה של HTTP Referrer שתואמת לדומיין הנוכחי של האתר בלי לציין נתיב.

  • ‫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() מתחיל את כל הבקשות לספרייה בו-זמנית, מקצר את זמן האחזור ברשת ומשפר את מהירות האתחול.