מדידה וניפוי באגים של ביצועים באמצעות Google Analytics 4 ו-BigQuery

במאמר הזה מוסבר איך שולחים נתוני Web Vitals לנכסי Google Analytics 4 ומייצאים את הנתונים לניתוח ב-BigQuery וב-Looker Studio.

Google מספקת מספר כלים — Search Console, PageSpeed Insights (PSI) ודוח חוויית המשתמש ב-Chrome (CrUX) — שמאפשרים למפתחים לראות את ביצועי האתרים שלהם ביחס למדדי Core Web Vitals של המשתמשים האמיתיים בשדה.

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

עם זאת, יש כמה סיבות חשובות שלא כדאי להסתמך רק על הכלים האלה כדי למדוד את ביצועי האתר:

  • כלים מבוססי CrUX מדווחים על נתונים לפי תקופות חודשיות או 28 ימים קודמים. כלומר, צריך להמתין זמן רב אחרי שמבצעים שינויים עד שאפשר לראות את התוצאות.
  • אפשר לפלח כלים המבוססים על CrUX רק לפי מספר מוגבל של מאפיינים, כמו מדינה, סוג חיבור וקטגוריית מכשיר (מחשב או נייד). אי אפשר לפלח את הנתונים לפי מאפיינים ספציפיים לעסק (לדוגמה: משתמשים שהביעו עניין, משתמשים בקבוצת ניסוי מסוימת וכו').
  • כלים מבוססי CrUX יכולים לתת לכם מידע על הביצועים שלכם, אבל לא יכולים לדעת למה. כלי הניתוח מאפשרים לשלוח נתונים נוספים כדי לעקוב אחר בעיות ולנפות באגים.

לכן אנחנו ממליצים לכל בעלי האתרים לעקוב אחרי המדדים של Core Web Vitals באמצעות הכלי הקיים שלהם לניתוח נתונים. בפוסט הזה נסביר איך להשתמש בכלים החינמיים ש-Google מציעה כדי לעשות זאת.

אחרי שתסיימו את ההגדרה, תוכלו ליצור מרכזי בקרה כמו אלה:

צילום מסך של הדוח Web Vitals Connector

צילום מסך של הדוח Web Vitals Connector

אם אתם רוצים לקבל סקירה כללית ויזואלית של כל השלבים שמפורטים כאן, תוכלו לעיין בשיחה שלנו מ-Google I/O 2021:

מדידה

תמיד היה אפשר למדוד ביצועים ב-Google Analytics באמצעות מדדים מותאמים אישית, אבל יש כמה תכונות חדשות ב-Google Analytics 4 (GA4) שמפתחים צריכים להתרגש לקראתן.

לממשק האינטרנט של Google Analytics יש כלי ניתוח חזקים, אבל קשה להתגבר על העוצמה והגמישות של גישה לנתוני אירועים גולמיים באמצעות שפת שאילתות שסביר להניח שאתם כבר מכירים.

כדי להתחיל למדוד את מדדי הליבה לבדיקת חוויית המשתמש באתר באמצעות Google Analytics 4 ו-BigQuery, צריך לבצע שלושה דברים:

  1. יצירת נכס Google Analytics 4 ופרויקט BigQuery.
  2. מפעילים את BigQuery Export בהגדרת הנכס ב-Google Analytics, כך שכל הנתונים שתקבלו יאוכלסו באופן אוטומטי בטבלאות של הפרויקטים ב-BigQuery.
  3. אתם יכולים להוסיף לאתר את ספריית ה-JavaScript של Web-vitals כדי למדוד את מדדי הליבה לבדיקת חוויית המשתמש באתר ולשלוח את הנתונים ל-Google Analytics 4, כולל נתוני השיוך (Attribution).

ניתוח

בסיום ההגדרה אמורים להופיע נתוני אירועים בממשק BigQuery, ואפשר להריץ שאילתות על הנתונים באופן הבא:

SELECT * FROM `my_project_id.analytics_XXXXX.events_*`
WHERE event_name IN ('LCP', 'INP', 'CLS')

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

נתוני אירועים של Web Vitals ב-BigQuery

שליחת שאילתות על הנתונים של מדדי Web Vitals

לפני שמתחילים להריץ שאילתות על נתוני האירועים ב-Web Vitals, חשוב להבין איך הנתונים נצברים.

מה שהכי חשוב להבין הוא שבמקרים מסוימים יכול להיות שיתקבלו מספר אירועים באותו מדד, באותו דף. מצב כזה יכול לקרות אם הערך של המדד משתנה ומדווחים על ערך מעודכן (בעיה נפוצה ב-CLS).

לגבי אירועים של Web Vitals, הערך האחרון שנשלח הוא תמיד המדויק ביותר, ולכן לפני שמבצעים ניתוח כלשהו, חשוב לסנן רק לפי הערכים האלה. קטע הקוד שסופק על ידי ספריית ה-JavaScript של וריאנטים של אינטרנט כדי לשלוח נתונים ל-Google Analytics 4 כולל שליחת מזהה ייחודי לכל מדד, כך שאפשר להשתמש בשאילתה הבאה כדי להגביל את התוצאות רק לערך האחרון שהתקבל עבור כל מזהה מדד:

# Subquery all Web Vitals events from the last 28 days
WITH web_vitals_events AS (
  SELECT event_name as metric_name, * EXCEPT(event_name, is_last_received_value) FROM (
    SELECT *, IF (ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id')
      ORDER BY (SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = 'metric_value') DESC
    ) = 1, true, false) AS is_last_received_value
    FROM `bigquery_project_id.analytics_XXXXX.events_*`
    WHERE event_name in ('CLS', 'INP', 'LCP') AND
      _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 28 DAY)) AND FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY))
  ) WHERE is_last_received_value
)

שימו לב שכל השאילתות האחרות שיש להן הפניה בפוסט הזה יתחילו בשאילתת המשנה הזו.

שאילתות לדוגמה

בחלקים הבאים מוצגות כמה דוגמאות לשאילתות נפוצות של מדדי Web Vitals שאולי תרצו להריץ.

LCP, INP ו-CLS באחוזון 75% (p75) ברחבי האתר

# Subquery all Web Vitals events from the last 28 days
WITH web_vitals_events AS (
  SELECT event_name as metric_name, * EXCEPT(event_name, is_last_received_value) FROM (
    SELECT *, IF (ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id')
      ORDER BY (SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = 'metric_value') DESC
    ) = 1, true, false) AS is_last_received_value
    FROM `bigquery_project_id.analytics_XXXXX.events_*`
    WHERE event_name in ('CLS', 'INP', 'LCP') AND
      _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 28 DAY)) AND FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY))
  ) WHERE is_last_received_value
)
# Main query logic
SELECT
  metric_name,
  APPROX_QUANTILES(metric_value, 100)[OFFSET(75)] AS p75,
  COUNT(1) as count
FROM (
  SELECT
    metric_name,
    ROUND((SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = "metric_value"), 3) AS metric_value,
  FROM web_vitals_events
)
GROUP BY 1

כל ערכי ה-LCP הנפרדים מהגבוה לנמוך

# Subquery all Web Vitals events from the last 28 days
WITH web_vitals_events AS (
  SELECT event_name as metric_name, * EXCEPT(event_name, is_last_received_value) FROM (
    SELECT *, IF (ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id')
      ORDER BY (SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = 'metric_value') DESC
    ) = 1, true, false) AS is_last_received_value
    FROM `bigquery_project_id.analytics_XXXXX.events_*`
    WHERE event_name in ('CLS', 'INP', 'LCP') AND
      _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 28 DAY)) AND FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY))
  ) WHERE is_last_received_value
)
# Main query logic
SELECT
  ROUND((SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = "metric_value"), 3) AS metric_value,
FROM web_vitals_events
WHERE metric_name = 'LCP'
ORDER BY metric_value DESC
# Subquery all Web Vitals events from the last 28 days
WITH web_vitals_events AS (
  SELECT event_name as metric_name, * EXCEPT(event_name, is_last_received_value) FROM (
    SELECT *, IF (ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id')
      ORDER BY (SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = 'metric_value') DESC
    ) = 1, true, false) AS is_last_received_value
    FROM `bigquery_project_id.analytics_XXXXX.events_*`
    WHERE event_name in ('CLS', 'INP', 'LCP') AND
      _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 28 DAY)) AND FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY))
  ) WHERE is_last_received_value
)
# Main query logic
SELECT
  page_path,
  APPROX_QUANTILES(metric_value, 100)[OFFSET(75)] AS LCP,
  COUNT(1) as count
FROM (
  SELECT
    REGEXP_SUBSTR((SELECT value.string_value FROM UNNEST(event_params) WHERE key = "page_location"), r'\.com(\/[^?]*)') AS page_path,
    ROUND((SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = "metric_value"), 3) AS metric_value,
  FROM web_vitals_events
  WHERE metric_name = 'LCP'
)
GROUP BY 1
ORDER BY count DESC
LIMIT 10

10 הדפים המובילים עם ה-CLS הגרוע ביותר (p75)

# Subquery all Web Vitals events from the last 28 days
WITH web_vitals_events AS (
  SELECT event_name as metric_name, * EXCEPT(event_name, is_last_received_value) FROM (
    SELECT *, IF (ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id')
      ORDER BY (SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = 'metric_value') DESC
    ) = 1, true, false) AS is_last_received_value
    FROM `bigquery_project_id.analytics_XXXXX.events_*`
    WHERE event_name in ('CLS', 'INP', 'LCP') AND
      _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 28 DAY)) AND FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY))
  ) WHERE is_last_received_value
)
# Main query logic
SELECT
  page_path,
  APPROX_QUANTILES(metric_value, 100)[OFFSET(75)] AS CLS,
  COUNT(1) as count
FROM (
  SELECT
    REGEXP_SUBSTR((SELECT value.string_value FROM UNNEST(event_params) WHERE key = "page_location"), r'\.com(\/[^?]*)') AS page_path,
    ROUND((SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = "metric_value"), 3) AS metric_value,
  FROM web_vitals_events
  WHERE metric_name = 'CLS'
)
GROUP BY 1
HAVING count > 50 # Limit to relatively popular pages
ORDER BY CLS DESC
LIMIT 10

ניפוי באגים

בשאילתות הקודמות מוסבר איך להריץ שאילתות על נתוני המדד Web Vitals, שיעזרו לכם להבין את הביצועים הנוכחיים ואת המגמות שלהם לאורך זמן. אבל מה אפשר לעשות אם הביצועים נמוכים מהצפוי, אבל לא ברור למה?

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

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

שאילתות לדוגמה

השאילתות הבאות מדגימות איך להשתמש בפרמטר האירוע debug_target כדי לזהות את שורש הבעיות בביצועים.

הרכיבים המובילים שתורמים ל-CLS

debug_target היא מחרוזת סלקטור ב-CSS שתואמת לרכיב בדף הרלוונטי ביותר לערך המדד.

עם CLS, הערך debug_target מייצג את הרכיב הגדול ביותר מתוך הפרש הפריסה הגדול ביותר שתרמה לערך ה-CLS. אם לא השתנה רכיבים, הערך של debug_target יהיה null.

בשאילתה הבאה יוצגו דפים מהגרוע ביותר לטוב ביותר לפי CLS באחוזון ה-75, מקובצים לפי debug_target:

# Subquery all Web Vitals events from the last 28 days
WITH web_vitals_events AS (
  SELECT event_name as metric_name, * EXCEPT(event_name, is_last_received_value) FROM (
    SELECT *, IF (ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id')
      ORDER BY (SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = 'metric_value') DESC
    ) = 1, true, false) AS is_last_received_value
    FROM `bigquery_project_id.analytics_XXXXX.events_*`
    WHERE event_name in ('CLS', 'INP', 'LCP') AND
      _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 28 DAY)) AND FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY))
  ) WHERE is_last_received_value
)
# Main query logic
SELECT
  page_path,
  debug_target,
  APPROX_QUANTILES(metric_value, 100)[OFFSET(75)] AS CLS,
  COUNT(1) as count
FROM (
  SELECT
    REGEXP_SUBSTR((SELECT value.string_value FROM UNNEST(event_params) WHERE key = "page_location"), r'\.com(\/[^?]*)') AS page_path,
    (SELECT value.string_value FROM UNNEST(event_params) WHERE key = "debug_target") as debug_target,
    ROUND((SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = "metric_value"), 3) AS metric_value,
    *
  FROM web_vitals_events
  WHERE metric_name = 'CLS'
)
GROUP BY 1, 2
HAVING count > 50 # Limit to relatively popular pages
ORDER BY CLS DESC

תוצאת שאילתה לגבי הרכיבים המובילים שתרמו ל-CLS

אם תכירו את הרכיבים בדף, יהיה לכם הרבה יותר קל לזהות את שורש הבעיה ולפתור אותה.

חשוב לזכור שיכול להיות שהרכיבים שמדווחים כאן הם לא אותם הרכיבים שמשתנים כשאתם מבצעים ניפוי באגים בדפים באופן מקומי, ולכן חשוב לתעד את הנתונים האלה מלכתחילה. קשה מאוד לתקן דברים שאתם לא מבינים שהם בעיות!

ניפוי באגים במדדים אחרים

השאילתה הקודמת מציגה את התוצאות של מדד CLS, אבל אפשר להשתמש באותה שיטה לדיווח על יעדי ניפוי הבאגים עבור LCP ו-INP. פשוט מחליפים את הסעיף שבו במדד הרלוונטי לניפוי באגים:

WHERE metric_name = 'INP'
WHERE metric_name = 'LCP'

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

הצג

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

# Subquery all Web Vitals events from the last 28 days
WITH web_vitals_events AS (
  SELECT event_name as metric_name, * EXCEPT(event_name, is_last_received_value) FROM (
    SELECT *, IF (ROW_NUMBER() OVER (
      PARTITION BY (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id')
      ORDER BY (SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = 'metric_value') DESC
    ) = 1, true, false) AS is_last_received_value
    FROM `bigquery_project_id.analytics_XXXXX.events_*`
    WHERE event_name in ('CLS', 'INP', 'LCP') AND
      _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 28 DAY)) AND FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY))
  ) WHERE is_last_received_value
)
# Main query logic
SELECT
  event_date,
  metric_name,
  APPROX_QUANTILES(ROUND(metric_value, 2), 100)[OFFSET(75)] AS p75
FROM
  (
    SELECT
      event_date,
      metric_name,
      ROUND((SELECT COALESCE(value.double_value, value.int_value) FROM UNNEST(event_params) WHERE key = 'metric_value'), 3) AS metric_value
    FROM web_vitals_events
    WHERE
      metric_name = 'LCP'
  )
GROUP BY
  1, 2
ORDER BY event_date

לפי תוצאות השאילתות האלה, קשה לזהות מגמות או חריגים רק על ידי עיון בנתונים.

תוצאות של שאילתות לגבי ערך המדד היומי

במקרים כאלה, הצגה חזותית של הנתונים יכולה לעזור לכם להפיק תובנות מהר יותר.

המחשה חזותית של תוצאות שאילתות ב-Looker Studio

ב-BigQuery אפשר להציג במהירות תוצאות של שאילתות ב-Data Studio. Looker Studio הוא כלי חינמי להמחשה חזותית וללוחות בקרה של נתונים. כדי להציג את תוצאות השאילתה באופן חזותי, אחרי שמריצים את השאילתה בממשק המשתמש של BigQuery, לוחצים על הלחצן Explore Data (עיון בנתונים) ובוחרים באפשרות Explore with Looker Studio.

בדיקה באמצעות האפשרות של Looker Studio ב-BigQuery

הפעולה הזו תיצור קישור ישיר מ-BigQuery ל-Looker Studio בתצוגת ה-Explore. בתצוגה הזו אפשר לבחור את השדות שרוצים להמחיש, לבחור סוגי תרשימים, להגדיר מסננים וליצור תרשימים אד-הוק לניתוח חזותי מהיר. מתוצאות השאילתה הקודמת, אתם יכולים ליצור את תרשים הקו הזה כדי לראות את המגמה של ערכי LCP לאורך זמן:

תרשים קו של ערכי LCP יומיים ב-Looker Studio

הקישור הישיר הזה בין BigQuery ל-Looker Studio מאפשר ליצור תרשימים מהירים מכל אחת מהשאילתות ולבצע ניתוח חזותי. עם זאת, אם תרצו לבצע ניתוח נוסף, תוכלו לצפות במספר תרשימים בלוח בקרה אינטראקטיבי כדי לקבל תמונה מקיפה יותר או להתעמק בנתונים. אם יש לכם מרכז בקרה נוח, לא תצטרכו לכתוב שאילתות וליצור תרשימים באופן ידני בכל פעם שתרצו לנתח את המדדים.

אפשר ליצור מרכז בקרה ב-Looker Studio באמצעות מחבר BigQuery המקורי. כדי לעשות זאת, עוברים אל datastudio.google.com, יוצרים מקור נתונים חדש, בוחרים את מחבר BigQuery ובוחרים את מערך הנתונים שאיתו רוצים לעבוד:

שימוש במחבר המקורי של BigQuery ב-Looker Studio

יצירת גרסה מהותית של נתונים בדוח ה-Web Vitals

כשיוצרים מרכזי בקרה לנתוני האירועים ב-Web Vitals כפי שמתואר למעלה, אי אפשר להשתמש ישירות במערך הנתונים של הייצוא מ-Google Analytics 4. בגלל המבנה של נתוני GA4 והעיבוד מראש שנדרש למדדי Web Vitals, חלקים מהשאילתה יפעלו כמה פעמים. כתוצאה מכך, נוצרות שתי בעיות: ביצועים במרכז הבקרה ועלויות ב-BigQuery.

אפשר להשתמש במצב ה-Sandbox של BigQuery ללא תשלום. בתוכנית השימוש בחינם של BigQuery, כל חודש מקבלים בחינם 1TB לעיבוד נתוני שאילתות, ומתחילים לשלם אחרי שהנפח הזה מנוצל. בשיטות הניתוח שצוינו בפוסט הזה, אלא אם אתם משתמשים במערך נתונים גדול בצורה משמעותית או מבצעים שאילתות רבות על מערך הנתונים באופן קבוע, לא תצטרכו לחרוג מהמגבלה החינמית הזו בכל חודש. אבל אם יש לכם אתר עם נפח תנועה גבוה ואתם רוצים לעקוב באופן קבוע אחרי מדדים שונים באמצעות מרכז בקרה אינטראקטיבי מהיר, מומלץ לעבד מראש את נתוני תפקוד האפליקציה ולממש אותם, ובמקביל להשתמש בתכונות היעילות של BigQuery כמו חלוקה למחיצות (partitioning), קיבוץ לאשכולות (clustering) ושמירה במטמון.

הסקריפט הבא יעבד מראש את הנתונים שלכם ב-BigQuery (טבלת מקור) וייצור טבלה מהותית (טבלת יעדים). כשמשתמשים בשאילתה הזו למערך הנתונים שלכם, כדאי גם להגדיר טווח תאריכים לטבלת המקור כדי להפחית את כמות הנתונים שיעובדו.

# Materialize Web Vitals metrics from GA4 event export data

# Replace target table name
CREATE OR REPLACE TABLE bigquery_project_id.ga4_demo_dev.web_vitals_summary
  PARTITION BY DATE(event_timestamp)
  CLUSTER BY metric_name
AS
SELECT
  ga_session_id,
  IF(
    EXISTS(SELECT 1 FROM UNNEST(events) AS e WHERE e.event_name = 'first_visit'),
    'New user',
    'Returning user') AS user_type,
  IF(
    (SELECT MAX(session_engaged) FROM UNNEST(events)) > 0, 'Engaged', 'Not engaged')
    AS session_engagement,
  evt.* EXCEPT (session_engaged, event_name),
  event_name AS metric_name,
  FORMAT_TIMESTAMP('%Y%m%d', event_timestamp) AS event_date
FROM
  (
    SELECT
      ga_session_id,
      ARRAY_AGG(custom_event) AS events
    FROM
      (
        SELECT
          ga_session_id,
          STRUCT(
            country,
            device_category,
            device_os,
            traffic_medium,
            traffic_name,
            traffic_source,
            page_path,
            debug_target,
            event_timestamp,
            event_name,
            metric_id,
            IF(event_name = 'LCP', metric_value / 1000, metric_value) AS metric_value,
            user_pseudo_id,
            session_engaged,
            session_revenue) AS custom_event
        FROM
          (
            SELECT
              (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id')
                AS ga_session_id,
              (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'metric_id')
                AS metric_id,
              ANY_VALUE(device.category) AS device_category,
              ANY_VALUE(device.operating_system) AS device_os,
              ANY_VALUE(traffic_source.medium) AS traffic_medium,
              ANY_VALUE(traffic_source.name) AS traffic_name,
              ANY_VALUE(traffic_source.source) AS traffic_source,
              ANY_VALUE(
                REGEXP_SUBSTR(
                  (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'page_location'),
                  r'^[^?]+')) AS page_path,
              ANY_VALUE(
                (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'debug_target'))
                AS debug_target,
              ANY_VALUE(user_pseudo_id) AS user_pseudo_id,
              ANY_VALUE(geo.country) AS country,
              ANY_VALUE(event_name) AS event_name,
              SUM(ecommerce.purchase_revenue) AS session_revenue,
              MAX(
                (
                  SELECT
                    COALESCE(
                      value.double_value, value.int_value, CAST(value.string_value AS NUMERIC))
                  FROM UNNEST(event_params)
                  WHERE key = 'session_engaged'
                )) AS session_engaged,
              TIMESTAMP_MICROS(MAX(event_timestamp)) AS event_timestamp,
              MAX(
                (
                  SELECT COALESCE(value.double_value, value.int_value)
                  FROM UNNEST(event_params)
                  WHERE key = 'metric_value'
                )) AS metric_value,
            FROM
              # Replace source table name
              `bigquery_project_id.analytics_XXXXX.events_*`
            WHERE
              event_name IN ('LCP', 'INP', 'CLS', 'first_visit', 'purchase')
            GROUP BY
              1, 2
          )
      )
    WHERE
      ga_session_id IS NOT NULL
    GROUP BY ga_session_id
  )
CROSS JOIN UNNEST(events) AS evt
WHERE evt.event_name NOT IN ('first_visit', 'purchase');

למערך הנתונים המהותי הזה יש מספר יתרונות:

  • מבנה הנתונים שטוח יותר וקל יותר להריץ שאילתות.
  • היא שומרת רק את אירועי Web Vitals ממערך הנתונים המקורי של GA4.
  • מזהה הסשן, סוג המשתמש (חדש לעומת חוזר) ופרטי המעורבות בסשן זמינים ישירות בעמודות.
  • הטבלה partitioned לפי תאריך ומקובצת באשכולות לפי שם המדד. בדרך כלל הפעולה הזו מפחיתה את כמות הנתונים שמעובדים בכל שאילתה.
  • בגלל שלא צריך להשתמש בתווים כלליים לחיפוש כדי לשלוח שאילתות על הטבלה הזו, תוצאות השאילתה יכולות להישמר במטמון למשך עד 24 שעות. כך תוכלו להפחית את העלויות עקב חזרה על אותה שאילתה.
  • אם אתם משתמשים במנוע ה-BI של BigQuery, אתם יכולים להריץ בטבלה הזו פונקציות ואופרטורים שעברו אופטימיזציה ל-SQL.

תוכלו להריץ שאילתות על הטבלה מהותית ישירות מתוך ממשק המשתמש של BigQuery, או להשתמש בה ב-Looker Studio באמצעות המחבר של BigQuery.

איך משתמשים במחבר Web Vitals

מכיוון שיצירת לוח בקרה מאפס דורשת זמן, פיתחנו פתרון ארוז שיצור עבורכם לוח בקרה שמבוסס על תבנית. קודם כל, צריך לוודא שיצרתם את הטבלה של דוח ה-Web Vitals בהתאם לשאילתה הקודמת. אחר כך נכנסים למחבר Web Vitals של Looker Studio דרך הקישור הזה: goo.gle/web-vitals-connector

אחרי שמספקים הרשאה חד-פעמית, אמור להופיע מסך ההגדרה הבא:

מסך האישור של מחבר Web Vitals

מספקים את מזהה הטבלה המהותית ב-BigQuery (כלומר טבלת היעד) ואת מזהה פרויקט החיוב ב-BigQuery. אחרי שלוחצים על Connect, מערכת Looker Studio תיצור מרכז בקרה חדש בתבנית ותשייך אליו את הנתונים. תוכלו לערוך, לשנות ולשתף את מרכז הבקרה איך שתרצו. אם יוצרים מרכז בקרה פעם אחת, לא צריך להיכנס שוב לקישור של המחבר, אלא אם רוצים ליצור מספר מרכזי בקרה ממערכי נתונים שונים.

בכרטיסייה Summary (סיכום) אפשר לנווט במרכז הבקרה כדי לראות את המגמות היומיות של מדדי Web Vitals ומידע מסוים על השימוש באתר, כמו משתמשים וסשנים.

בכרטיסייה User Analysis תוכלו לבחור מדד ולקבל פירוט של האחוזון המדדים ושל מספר המשתמשים לפי שימוש ומדדים עסקיים שונים.

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

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

שימוש מתקדם

ככל שתכירו יותר את מערך הנתונים, תוכלו לערוך את מרכז הבקרה ולהוסיף תרשימים משלכם לניתוח עשיר וממוקד. כדי להפוך את מרכז הבקרה לשימושי יותר, תוכלו לבצע את השלבים הבאים:

  • צריך להגדיר שאילתה מתוזמנת ב-BigQuery כדי לקבל נתונים מעודכנים. שאילתת הממשיות שהרצתנו קודם לוקחת רק תמונת מצב של הנתונים באותו רגע. אם רוצים שהנתונים החדשים במרכז הבקרה יהיו מעודכנים, תוכלו להריץ שאילתה מתוזמנת שתרוץ מדי יום ולצרף את הנתונים החדשים לטבלה הזו.
  • מצטרפים לנתונים מאינטראקציה ישירה (First-Party) (למשל, ניהול קשרי לקוחות (CRM)) כדי לקבל תובנות עסקיות. בטבלה מהותית אפשר להוסיף את user_id כעמודה נפרדת. כך תוכלו לצרף נתונים מאינטראקציה ישירה (First-Party). אם הנתונים מאינטראקציה ישירה עדיין לא נמצאים ב-BigQuery, אפשר לטעון את הנתונים או להשתמש במקור נתונים מאוחד.
  • לדווח על גרסת האתר או האפליקציה כפרמטר בנתונים שאתם שולחים ל-Google Analytics, ולהוסיף אותה כעמודה בטבלה המוצגת. לאחר מכן תוכלו להוסיף את נתוני הגרסה כמאפיין בתרשימים, כדי שיהיה קל יותר לראות ששינויי גרסה משפיעים על הביצועים.
  • אם אתם מצפים לשימוש משמעותי במערך הנתונים באמצעות שאילתה ישירה או מרכז הבקרה, תוכלו לנסות להשתמש בגרסה בתשלום של מנוע ה-BI של BigQuery.

סיכום

הפוסט הזה עוסק בעקרונות הבסיסיים של השימוש ב-Google Analytics 4 וב-BigQuery כדי למדוד ביצועים ולנפות באגים בעזרת נתונים ממשתמשים אמיתיים שנאספו בשטח. בנוסף, הסברנו איך ליצור דוחות ומרכזי בקרה אוטומטיים באמצעות Looker Studio ו-Web Vitals Connector כדי להציג את הנתונים בצורה חזותית בקלות רבה ככל האפשר.

נקודות עיקריות לגבי הפוסט הזה:

  • מדידת הביצועים באמצעות נתוני משתמשים אמיתיים היא חיונית להבנה, לניפוי באגים ולאופטימיזציה של האתר.
  • כשמדדי הביצועים והמדדים של העסק נמצאים באותה מערכת, אפשר לקבל תובנות מעמיקות יותר. אפשר לעשות את זה ב-Google Analytics וב-BigQuery.
  • הייצוא של נתוני Google Analytics מ-BigQuery ל-BigQuery נותן לכם פוטנציאל בלתי מוגבל לניתוח מעמיק בהתאמה אישית באמצעות שפת שאילתות שסביר להניח שאתם כבר מכירים.
  • ל-Google יש כמה ממשקי API וכלי תצוגה חזותית כמו Looker Studio, שמאפשרים ליצור דוחות בדיוק כמו שאתם רוצים.