מדידה וניפוי באגים של ביצועים באמצעות 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 Connector

צילום מסך של דוח המחבר של 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 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

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

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

סיכום

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

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

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