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

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

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

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

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

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

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

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

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

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

אפשר גם לקרוא סקירה כללית ויזואלית של כל השלבים שמתוארים כאן, בשיחה שלנו מ-Google I/O '21:

מדידה

תמיד אפשר למדוד את הביצועים ב-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 של נכסי האינטרנט, כדי למדוד את מדדי הליבה לבדיקת חוויית המשתמש באתר ולשלוח את הנתונים אל Google Analytics 4.

ניתוח

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

SELECT * FROM `my_project_id.analytics_XXXXX.events_*`
WHERE event_name IN ('LCP', 'FID', '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', 'FID', '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, FID ו-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', 'FID', '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', 'FID', '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', 'FID', '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', 'FID', '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', 'FID', '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 ו-FID. פשוט מחליפים את סעיף המקום במדד הרלוונטי לצורך ניפוי הבאגים:

WHERE metric_name = 'CLS'
WHERE metric_name = 'LCP'

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

הצג

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

# 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', 'FID', '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 בתצוגת הניתוח. בתצוגה הזו ניתן לבחור את השדות שרוצים להמחיש, לבחור סוגי תרשימים, להגדיר מסננים וליצור תרשימי אד-הוק לניתוח חזותי מהיר. אתם יכולים ליצור את תרשים הקו הזה מתוצאות השאילתה שלמעלה כדי לראות את המגמה של ערכי LP לאורך זמן:

תרשים קו של ערכי 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.

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

הסקריפט הבא יבצע עיבוד מראש של נתוני 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', 'FID', '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 שעות. כך אפשר לצמצם את העלויות כתוצאה מחזרה על אותה שאילתה.
  • אם אתם משתמשים במנוע BigQuery BI, תוכלו להריץ פונקציות ואופרטורים של SQL שעברו אופטימיזציה בטבלה הזו.

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

שימוש ב-Web Vitals Connector

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

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

מסך ההרשאה של Web Vitals

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

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

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

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

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

שימוש מתקדם

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

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

סיכום

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

כמה מסקנות מרכזיות מהפוסט הזה:

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