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

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

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

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

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

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

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

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

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

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

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

מדידה

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

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

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

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

ניתוח

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

מה הציון לא יעזור לכם אם לא תוכלו לבצע פעולות ולתקן את הבעיות.

במאמר ניפוי באגים של ביצועים בשטח מוסבר איך לשלוח מידע נוסף על ניפוי באגים עם נתוני Analytics. אם תפעלו לפי ההוראות המפורטות בפוסט הזה, פרטי ניפוי הבאגים אמורים להופיע גם ב-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 במדד הרלוונטי כדי לנפות באגים:

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

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

הצג

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

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

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

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

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

יצירה של נתוני Web Vitals

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

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

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

שימוש במחבר Web Vitals

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

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

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

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

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

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

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

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

שימוש מתקדם

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

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

סיכום

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

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

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