วัดประสิทธิภาพด้วย web-vitals.js, Google Analytics และ BigQuery

1. ก่อนเริ่มต้น

สิ่งที่คุณต้องทำ

ใน Codelab นี้ คุณจะได้ทำสิ่งต่อไปนี้

  • ลิงก์พร็อพเพอร์ตี้ Google Analytics 4 กับ BigQuery
  • เพิ่มไลบรารี web-vitals ลงในหน้าเว็บ
  • เตรียมและส่งweb-vitalsข้อมูลไปยัง Google Analytics
  • ค้นหาข้อมูล Core Web Vitals ใน BigQuery
  • สร้างแดชบอร์ดใน Google Data Studio เพื่อแสดงข้อมูล Core Web Vitals เป็นภาพ

สิ่งที่คุณต้องมี

ก่อนจะเริ่มต้น

ก่อนอื่น ให้ลิงก์ Google Analytics 4 กับ BigQuery เพื่อให้มั่นใจว่าคุณจะเริ่มวิเคราะห์ประสิทธิภาพได้ทันทีที่โค้ดใช้งานจริง

ทําตามขั้นตอนในศูนย์ช่วยเหลือของ Google Analytics เพื่อลิงก์พร็อพเพอร์ตี้ GA4 กับ BigQuery

ตอนนี้พร็อพเพอร์ตี้ Google Analytics พร้อมที่จะส่งออกข้อมูลเหตุการณ์ไปยัง BigQuery แล้ว ให้ผสานรวมไลบรารี web-vitals ในเว็บไซต์

2. เพิ่มไลบรารี web-vitals และ gtag ลงในหน้าเว็บ

ก่อนอื่น ให้เพิ่มไลบรารี web-vitals ลงในหน้าเว็บ

  1. เปิดเทมเพลตหน้าเว็บที่ต้องการเพิ่มไลบรารี web-vitals ในตัวอย่างนี้ เราจะใช้หน้าเว็บแบบง่ายๆ ดังนี้

basic.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Web Vitals Test</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  <p><img style="max-width: 360px" src="https://placekitten.com/g/3840/2160" alt="Kitten" /></p>
  <p>Text below image</p>
</body>
</html>
  1. วางซอร์สโค้ดลงในไฟล์ว่างในโปรแกรมแก้ไขข้อความ
  2. บันทึกไฟล์ในเครื่องเป็น basic.html
  3. คัดลอกสคริปต์โมดูลนี้ แล้ววางไว้ก่อนแท็กปิด </body> สคริปต์นี้จะโหลดไลบรารี web-vitals จากเครือข่ายนำส่งข้อมูล

basic.html

<script type="module">
  import {onCLS, onINP, onLCP} from 'https://unpkg.com/web-vitals@4/dist/web-vitals.attribution.js?module';

  onCLS(console.log);
  onINP(console.log);
  onLCP(console.log);
</script>

โค้ดที่ได้ควรมีลักษณะดังนี้

basic.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Web Vitals Test</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  <p><img style="max-width: 360px" src="https://placekitten.com/g/3840/2160" alt="Kitten" /></p>
  <p>Text below image</p>

<script type="module">
  import {onCLS, onINP, onLCP} from 'https://unpkg.com/web-vitals@4/dist/web-vitals.attribution.js?module';

  onCLS(console.log);
  onINP(console.log);
  onLCP(console.log);
</script>
</body>
</html>
  1. บันทึกไฟล์

คุณเพิ่มไลบรารี web-vitals ลงในหน้าเว็บ

3. วัด Core Web Vitals ของหน้าเว็บ

Core Web Vitals คือการวัดประสบการณ์ของผู้ใช้จริงตามที่บันทึกผ่าน Chrome หรือweb-vitalsในเบราว์เซอร์ Chromium เมื่อเปิดตัว web-vitals เป็นเวอร์ชันที่ใช้งานจริง คุณจะเห็นผลลัพธ์ที่หลากหลายตามความเร็วในการเชื่อมต่อ พลังงานของอุปกรณ์ และวิธีที่ผู้ใช้โต้ตอบกับเว็บไซต์ของคุณ เราจะจำลองประสบการณ์ของผู้ใช้ที่มีการเชื่อมต่อช้าเพื่อแสดงความสามารถของweb-vitalsไลบรารี

  1. เปิดไฟล์ที่บันทึกไว้ในเว็บเบราว์เซอร์
  2. คลิกขวาที่หน้าเว็บ
  3. คลิกตรวจสอบเพื่อเปิดเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ Google Chrome

1d60156133044215.png

  1. คลิกแท็บคอนโซล > การตั้งค่าคอนโซลb5c716ebfacfd86.png

a310e2b6e03891a1.png

  1. เลือกช่องทําเครื่องหมายเก็บบันทึกเพื่อให้บันทึกยังคงอยู่เมื่อคุณรีเฟรชหน้าเว็บ

cdfbcd3315aa45cd.png

  1. คลิกแท็บเครือข่าย > ออนไลน์ > 3G ช้า เพื่อจำลองการเชื่อมต่อเครือข่ายที่ช้า

b1fab3d167d032f0.png

  1. คลิกแท็บคอนโซล
  2. คลิกที่ใดก็ได้ในหน้าเว็บเพื่อบังคับให้พิมพ์เมตริกสำหรับ Largest Contentful Paint (LCP)
  3. คลิกโหลดหน้านี้ซ้ำ acaaa8c0fdd33b1.png เพื่อบังคับให้พิมพ์เมตริกสำหรับ Cumulative Layout Shift (CLS) และ Interaction to Next Paint (INP)

e18b530e48108a4.png

  1. คลิกแท็บเครือข่าย > ออนไลน์ > 3G เร็ว เพื่อจำลองการเชื่อมต่อเครือข่ายที่รวดเร็ว
  2. คลิกแท็บคอนโซล
  3. คลิกที่ใดก็ได้ในหน้าเว็บเพื่อบังคับให้เมตริกสำหรับ LCP พิมพ์อีกครั้ง

e5d5ca555ded9f7a.png

  1. คลิกโหลดหน้านี้ซ้ำ acaaa8c0fdd33b1.png เพื่อบังคับให้พิมพ์เมตริกสำหรับ CLS และ INP อีกครั้ง

e8bde4594a01021b.png

เท่านี้ก็เรียบร้อย คุณวัด Core Web Vitals ของหน้าเว็บ

4. สํารวจข้อมูล web-vitals โดยละเอียด

สำหรับเหตุการณ์ Core Web Vitals แต่ละรายการที่คุณวัด จะมีข้อมูลมากมายในข้อมูลที่ส่งคืน ซึ่งคุณสามารถใช้เพื่อแก้ไขข้อบกพร่องของคอขวดด้านประสิทธิภาพได้ web-vitalsเหตุการณ์แต่ละรายการมีอาร์เรย์ entries ซึ่งมีข้อมูลเกี่ยวกับเหตุการณ์ที่ส่งผลต่อค่าเมตริกปัจจุบัน

CLS entries

การขยายพร็อพเพอร์ตี้ entries ของออบเจ็กต์ที่ onCLS() บันทึกไว้จะแสดงรายการของรายการ LayoutShift แต่ละ LayoutShift มีพร็อพเพอร์ตี้ value ที่แสดงคะแนนการเปลี่ยนเลย์เอาต์ และอาร์เรย์ sources ที่เราใช้เพื่อดูว่าองค์ประกอบใดมีการเปลี่ยน

355f0ff58e735079.png

ในตัวอย่างนี้ การเปลี่ยนเลย์เอาต์เกิดขึ้น 2 ครั้ง โดยทั้ง 2 ครั้งเป็นการย้ายองค์ประกอบ h1 ในหน้าเว็บ พร็อพเพอร์ตี้ currentRect จะบอกตำแหน่งปัจจุบันขององค์ประกอบ และองค์ประกอบ previousRect จะบอกตำแหน่งเดิมขององค์ประกอบ

LCP entries

การขยายพร็อพเพอร์ตี้รายการของออบเจ็กต์ที่บันทึกโดย onLCP() จะแสดงให้เราเห็นว่าองค์ประกอบใดเป็นตัวเลือกสำหรับ Largest Contentful Paint ก่อนที่จะมีการรายงานค่าสุดท้าย

737ebf826005dbe7.png

ในตัวอย่างนี้ อาร์เรย์ entries มีรายการผู้สมัคร LCP ทั้งหมดตามลำดับเวลา ในกรณีนี้ ระบบจะแสดงผลองค์ประกอบ h1 ก่อน ตามด้วยองค์ประกอบ img img เป็น Largest Contentful Paint องค์ประกอบ LCP ที่รายงานจะเป็นรายการสุดท้ายในอาร์เรย์เสมอ

INP entries

เมื่อขยายentriesพร็อพเพอร์ตี้ของออบเจ็กต์ที่บันทึกโดย onINP(), ระบบจะแสดงอาร์เรย์ที่มีรายการ PerformanceEventTiming สำหรับการโต้ตอบกับการแสดงผลถัดไปในหน้าเว็บ

a63ef33575c3218d.png

พร็อพเพอร์ตี้ name จะบอกประเภทข้อมูลจากผู้ใช้ที่ทริกเกอร์ตัวจับเวลาสำหรับความพร้อมใช้งานของเทรดหลัก valueที่ web-vitals รายงานคือระยะเวลาที่ระบุเป็นพร็อพเพอร์ตี้ duration ของรายการ PerformanceEventTiming ซึ่งแปลงจากไมโครวินาทีเป็นมิลลิวินาที ในกรณีนี้ INP ที่วัดได้คือ 48 มิลลิวินาที

5. เตรียมและส่งข้อมูล Web Vitals ไปยัง Google Analytics 4

ก่อนที่จะส่งweb-vitalsข้อมูลไปยัง Google Analytics 4 คุณต้องแปลงข้อมูลให้อยู่ในรูปแบบที่ GA4 รับได้

จัดโครงสร้างข้อมูลการแก้ไขข้อบกพร่องสำหรับ CWV แต่ละรายการ

ขั้นตอนสุดท้ายก่อนส่งโค้ดนี้ไปยัง Google Analytics คือการจัดโครงสร้างข้อมูลจากรายการ รวมถึงข้อมูลที่ฟังก์ชันข้างต้นส่งคืน

diagnostics.html

  function getDebugInfo(name, attribution) {
    // In some cases there won't be any entries (e.g. if CLS is 0,
    // or for LCP after a bfcache restore), so we have to check first.
    if (attribution) {
      if (name === 'LCP') {
        return {
          debug_url: attribution.url,
          debug_time_to_first_byte: attribution.timeToFirstByte,
          debug_resource_load_delay: attribution.resourceLoadDelay,
          debug_resource_load_time: attribution.resourceLoadTime,
          debug_element_render_delay: attribution.elementRenderDelay,
          debug_target: attribution.element || '(not set)',
        };
      } else if (name === 'INP') {
        return {
          debug_event: attribution.interactionType,
          debug_time: Math.round(attribution.interactionTime),
          debug_load_state: attribution.loadState,
          debug_target: attribution.interactionTarget || '(not set)',
          debug_interaction_delay: Math.round(attribution.inputDelay),
          debug_processing_duration: Math.round(attribution.processingDuration),
          debug_presentation_delay:  Math.round(attribution.presentationDelay),
        };
      } else if (name === 'CLS') {
        return {
          debug_time: attribution.largestShiftTime,
          debug_load_state: attribution.loadState,
          debug_target: attribution.largestShiftTarget || '(not set)',
        }
      }
    }
    // Return default/empty params in case there is no attribution.
    return {
      debug_target: '(not set)',
    };
  }
  
  function sendToGoogleAnalytics({ name, delta, value, id, entries, attribution }) {
    gtag('event', name, {
      // Built-in params:
      value: delta, // Use `delta` so the value can be summed.
      // Custom params:
      metric_id: id, // Needed to aggregate events.
      metric_value: value, // Value for querying in BQ
      metric_delta: delta, // Delta for querying in BQ
      // Send the returned values from getDebugInfo() as custom parameters
        ...getDebugInfo(name, attribution)
    });
  }

ส่งข้อมูลไปยัง Google Analytics

สุดท้าย ให้สร้างฟังก์ชันที่รับพารามิเตอร์จากweb-vitalsเหตุการณ์และส่งไปยัง Google Analytics

diagnostics.html

function sendToGoogleAnalytics({ name, delta, value, id, entries, attribution }) {
  gtag('event', name, {
    // Built-in params:
    value: delta, // Use `delta` so the value can be summed.
    // Custom params:
    metric_id: id, // Needed to aggregate events.
    metric_value: value, // Value for querying in BQ
    metric_delta: delta, // Delta for querying in BQ
    // Send the returned values from getDebugInfo() as custom parameters
      ...getDebugInfo(name, attribution)
  });
}

ลงทะเบียนฟังก์ชันด้วยฟังก์ชัน web-vitals แต่ละรายการ ซึ่งจะเริ่มทำงานเมื่อเบราว์เซอร์พร้อมที่จะวัดเหตุการณ์แต่ละรายการ

diagnostics.html

onLCP(sendToGoogleAnalytics);
onINP(sendToGoogleAnalytics);
onCLS(sendToGoogleAnalytics);

เยี่ยมมาก! ตอนนี้คุณส่งweb-vitalsเหตุการณ์ไปยัง Google Analytics แล้ว

6. ตรวจสอบว่าข้อมูล Web Vitals ปรากฏใน Google Analytics

วิธีตรวจสอบว่าพร็อพเพอร์ตี้ Google Analytics 4 บันทึกเหตุการณ์

  1. เปิดพร็อพเพอร์ตี้ Google Analytics 4 แล้วไปที่รายงาน

ab1bf51ba70f3609.png

  1. เลือกเรียลไทม์

65a5b8087b09b2a.png

  1. รีเฟรชหน้าทดสอบ 2-3 ครั้ง และอย่าลืมคลิกที่หน้าเว็บระหว่างการรีเฟรชเพื่อทริกเกอร์เหตุการณ์ INP
  2. มองหาส่วนจํานวนเหตุการณ์ตามชื่อเหตุการณ์ใน UI ของภาพรวมแบบเรียลไทม์ คุณควรเห็นเหตุการณ์ LCP, INP และ CLS

f92b276df1c2f6ce.png

  1. คลิกชื่อเหตุการณ์ใดก็ได้เพื่อดูพารามิเตอร์ที่ส่งพร้อมกับเหตุการณ์เหล่านั้น

8529bd743f121dd9.png

  1. คลิกคีย์พารามิเตอร์เหล่านั้นเพื่อดูสรุปค่าที่ Google Analytics ได้รับ

f0cf6a3dd607d533.png

คุณอาจต้องการเพิ่มข้อมูลอื่นๆ ลงในข้อมูลการแก้ไขข้อบกพร่อง เช่น ชื่อเทมเพลตหน้าเว็บ หรือเหตุการณ์หน้าเว็บอื่นๆ ที่เกี่ยวข้องกับ INP ซึ่งกล่าวถึงก่อนหน้านี้ใน Codelab นี้ เพียงแก้ไขคำสั่ง return ในฟังก์ชัน getDebugInfo()

เมื่อพอใจกับข้อมูลที่มาจากหน้าทดสอบแล้ว ให้ติดตั้งใช้งานโค้ด GA ใหม่ในเวอร์ชันที่ใช้งานจริงของเว็บไซต์ แล้วไปที่ขั้นตอนถัดไป

7. ค้นหาข้อมูลใน BigQuery

เมื่อโค้ด Google Analytics ใช้งานได้ 2-3 วันแล้ว คุณจะเริ่มค้นหาข้อมูลใน BigQuery ได้ ก่อนอื่น ให้ตรวจสอบว่าระบบกำลังโอนข้อมูลไปยัง BigQuery

  1. เปิด คอนโซล Google Cloud แล้วเลือกโปรเจ็กต์จากเมนูแบบเลื่อนลงที่ด้านบนของหน้าจอ
  2. จากเมนูการนำทาง 3cbb0e5fcc230aef.png ที่ด้านซ้ายบนของหน้าจอ ให้คลิก BigQuery ในส่วนหัวข้อมูลวิเคราะห์
  3. ในบานหน้าต่าง Explorer ให้ขยายโปรเจ็กต์เพื่อดูชุดข้อมูล Google Analytics ชื่อชุดข้อมูลคือ analytics_ ตามด้วยรหัสพร็อพเพอร์ตี้ Google Analytics 4 (เช่น analytics_229787100)
  4. ขยายชุดข้อมูล แล้วคุณจะเห็นevents_ตาราง ตัวเลขในวงเล็บคือจำนวนวันที่พร้อมให้ค้นหา

Subquery to select only CWV events

หากต้องการค้นหาชุดข้อมูลที่มีเฉพาะเหตุการณ์ CWV ให้เริ่มต้นด้วยการค้นหาย่อยที่เลือกเหตุการณ์ LCP, CLS และ INP ในช่วง 28 วันที่ผ่านมา โดยจะค้นหาค่าที่รายงานล่าสุดสำหรับรหัสเหตุการณ์ web-vitals แต่ละรายการโดยใช้คีย์ metric_id เพื่อให้แน่ใจว่าคุณจะไม่นับเหตุการณ์ CWV เดียวกันมากกว่า 1 ครั้ง

# 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
   # Make sure to update your project ID and GA4 property ID here!
   FROM `YOUR_PROJECT_ID.analytics_YOUR_GA_PROPERTY_ID.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_events

โครงสร้างเหตุการณ์ GA4

ข้อมูลเหตุการณ์ Google Analytics 4 แต่ละรายการจะอยู่ในคอลัมน์ STRUCT event_params พารามิเตอร์เหตุการณ์แต่ละรายการที่คุณส่งไปยัง GA4 ในเว็บไซต์จะแสดงด้วยคีย์ของพารามิเตอร์นั้น และค่าจะเป็น STRUCT ที่มีคีย์สําหรับประเภทข้อมูลที่เป็นไปได้แต่ละประเภท ในตัวอย่างข้างต้น metric_value อาจมี int_value หรือ double_value ดังนั้นจึงใช้ฟังก์ชัน COALESCE() หากต้องการรับ debug_target ที่คุณส่งผ่านก่อนหน้านี้ ให้เลือกคีย์ string_value ใน debug_target

...
(SELECT value.string_value FROM UNNEST(event_params) WHERE key = "debug_target") as debug_target
...

ค้นหาหน้าเว็บและองค์ประกอบที่มีประสิทธิภาพแย่ที่สุด

debug_target คือสตริงตัวเลือก CSS ที่สอดคล้องกับองค์ประกอบในหน้าที่เกี่ยวข้องกับค่าเมตริกมากที่สุด

เมื่อใช้ CLS debug_target จะแสดงองค์ประกอบที่ใหญ่ที่สุดจากการเปลี่ยนแปลงเลย์เอาต์ที่ใหญ่ที่สุดซึ่งมีส่วนทำให้เกิดค่า CLS หากไม่มีการเลื่อนองค์ประกอบ ค่า debug_target จะเป็น null

หน้าในรายการคำค้นหาต่อไปนี้เรียงจากแย่ที่สุดไปดีที่สุดตาม CLS ที่เปอร์เซ็นไทล์ที่ 75 โดยจัดกลุ่มตาม debug_target

# Main query logic
SELECT
  page_path,
  debug_target,
  APPROX_QUANTILES(metric_value, 100)[OFFSET(75)] AS metric_p75,
  COUNT(1) as page_views
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
# OPTIONAL: You may want to limit your calculations to pages with a 
# minimum number of pageviews to reduce noise in your reports. 
# HAVING page_views > 50
ORDER BY metric_p75 DESC

1bbbd957b4292ced.png

หากทราบว่าองค์ประกอบใดในหน้าเว็บที่เลื่อน ก็จะช่วยให้ระบุและแก้ไขสาเหตุของปัญหาได้ง่ายขึ้นมาก

โปรดทราบว่าองค์ประกอบที่รายงานที่นี่อาจไม่ใช่องค์ประกอบเดียวกันกับที่คุณเห็นเมื่อแก้ไขข้อบกพร่องของหน้าเว็บในเครื่อง ซึ่งเป็นเหตุผลว่าทำไมการบันทึกข้อมูลนี้ตั้งแต่แรกจึงสำคัญมาก การแก้ไขสิ่งที่คุณไม่รู้ว่าเป็นปัญหาเป็นเรื่องยากมาก

แก้ไขข้อบกพร่องของเมตริกอื่นๆ

คําค้นหาข้างต้นแสดงผลลัพธ์สําหรับเมตริก CLS แต่คุณสามารถใช้เทคนิคเดียวกันนี้เพื่อรายงานเป้าหมายการแก้ไขข้อบกพร่องสําหรับ LCP และ INP ได้ เพียงแทนที่ข้อความ WHERE ด้วยเมตริกที่เกี่ยวข้องเพื่อแก้ไขข้อบกพร่อง

# Replace:
# WHERE metric_name = 'CLS'
# With:
WHERE metric_name = 'LCP'

8. แสดงผลการค้นหาเป็นภาพใน Data Studio

BigQuery มีวิธีที่รวดเร็วในการแสดงผลการค้นหาใดๆ เป็นภาพผ่าน Data Studio Data Studio เป็นเครื่องมือแสดงข้อมูลเป็นภาพและแดชบอร์ดที่ใช้งานได้ฟรี หากต้องการแสดงผลการค้นหาเป็นภาพหลังจากเรียกใช้การค้นหาใน UI ของ BigQuery ให้คลิกสํารวจข้อมูล แล้วเลือกสํารวจด้วย Data Studio

สำรวจด้วยตัวเลือก Data Studio ใน BigQuery

ซึ่งจะสร้างลิงก์โดยตรงจาก BigQuery ไปยัง Data Studio ในมุมมองสํารวจ ในมุมมองนี้ คุณสามารถเลือกช่องที่ต้องการแสดงภาพ เลือกประเภทแผนภูมิ ตั้งค่าตัวกรอง และสร้างแผนภูมิเฉพาะกิจเพื่อการวิเคราะห์ด้วยภาพอย่างรวดเร็ว จากผลการค้นหาข้างต้น คุณสามารถสร้างแผนภูมิเส้นนี้เพื่อดูแนวโน้มของค่า LCP เมื่อเวลาผ่านไปได้

แผนภูมิเส้นของค่า LCP รายวันใน Data Studio

ลิงก์โดยตรงระหว่าง BigQuery กับ Data Studio นี้ช่วยให้คุณสร้างแผนภูมิอย่างรวดเร็วจากการค้นหาใดก็ได้ และทำการวิเคราะห์ด้วยภาพ อย่างไรก็ตาม หากต้องการทําการวิเคราะห์เพิ่มเติม คุณอาจต้องดูแผนภูมิหลายรายการในแดชบอร์ดแบบอินเทอร์แอกทีฟเพื่อให้ได้มุมมองที่ครอบคลุมมากขึ้นหรือเจาะลึกข้อมูลได้ การมีแดชบอร์ดที่ใช้งานง่ายหมายความว่าคุณไม่ต้องเขียนคําค้นหาและสร้างแผนภูมิด้วยตนเองทุกครั้งที่ต้องการวิเคราะห์เมตริก

คุณสร้างแดชบอร์ดใน Data Studio ได้โดยใช้เครื่องมือเชื่อมต่อ BigQuery ดั้งเดิม โดยไปที่ datastudio.google.com สร้างแหล่งข้อมูลใหม่ เลือกเครื่องมือเชื่อมต่อ BigQuery แล้วเลือกชุดข้อมูลที่ต้องการใช้

การใช้เครื่องมือเชื่อมต่อ BigQuery แบบเนทีฟใน Data Studio

9. สร้างข้อมูล Web Vitals

เมื่อสร้างแดชบอร์ดของข้อมูลเหตุการณ์ Web Vitals ตามที่อธิบายไว้ข้างต้น การใช้ชุดข้อมูลการส่งออกของ Google Analytics 4 โดยตรงจะไม่ใช่แนวทางที่มีประสิทธิภาพ เนื่องจากโครงสร้างของข้อมูล GA4 และการประมวลผลล่วงหน้าที่จำเป็นสำหรับเมตริก Web Vitals ทำให้บางส่วนของคําค้นหาของคุณทํางานหลายครั้ง ซึ่งจะทำให้เกิดปัญหา 2 อย่าง ได้แก่ ประสิทธิภาพของแดชบอร์ดและค่าใช้จ่ายของ BigQuery

คุณใช้โหมดแซนด์บ็อกซ์ของ BigQuery ได้โดยไม่มีค่าใช้จ่าย แพ็กเกจการใช้งานฟรีของ BigQuery จะให้คุณประมวลผลข้อมูลการค้นหา 1 TB แรกต่อเดือนได้โดยไม่มีค่าใช้จ่าย สำหรับวิธีการวิเคราะห์ที่กล่าวถึงในโพสต์นี้ คุณควรจะสามารถใช้ได้ภายในขีดจำกัดฟรีนี้ทุกเดือน เว้นแต่คุณจะใช้ชุดข้อมูลขนาดใหญ่มากหรือทำการค้นหาชุดข้อมูลอย่างหนักเป็นประจำ แต่หากคุณมีเว็บไซต์ที่มีการรับส่งข้อมูลสูงและต้องการตรวจสอบเมตริกต่างๆ เป็นประจำโดยใช้แดชบอร์ดแบบอินเทอร์แอกทีฟที่รวดเร็ว เราขอแนะนำให้ประมวลผลล่วงหน้าและสร้างข้อมูล Web Vitals ในขณะที่ใช้ฟีเจอร์ประสิทธิภาพของ BigQuery เช่น การแบ่งพาร์ติชัน การจัดกลุ่ม และการแคช

สคริปต์ต่อไปนี้จะประมวลผลข้อมูล BigQuery (ตารางแหล่งข้อมูล) ล่วงหน้าและสร้างตารางที่สร้างขึ้น (ตารางเป้าหมาย)

# Materialize Web Vitals metrics from GA4 event export data

# Replace target table name
CREATE OR REPLACE TABLE YOUR_PROJECT_ID.analytics_YOUR_GA_PROPERTY_ID.web_vitals_summary
  PARTITION BY DATE(event_timestamp)
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
              `YOUR_PROJECT_ID.analytics_YOUR_GA_PROPERTY_ID.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 ชั่วโมง ซึ่งจะช่วยลดค่าใช้จ่ายจากการค้นหาคำค้นหาเดียวกันซ้ำ
  • หากใช้ BigQuery BI Engine คุณจะเรียกใช้ฟังก์ชันและตัวดำเนินการ SQL ที่เพิ่มประสิทธิภาพแล้วในตารางนี้ได้

คุณค้นหาตารางที่สร้างขึ้นนี้ได้โดยตรงจากภายใน UI ของ BigQuery หรือจะใช้ใน Data Studio โดยใช้เครื่องมือเชื่อมต่อ BigQuery ก็ได้

เรียกใช้งานการสร้างข้อมูลจริงเป็นประจำ

หากเรียกใช้การค้นหาข้างต้นโดยไม่มีช่วงวันที่ ระบบจะเรียกใช้ในชุดข้อมูล Google Analytics ทั้งหมด คุณไม่ควรทำเช่นนี้ทุกวัน เนื่องจากคุณจะประมวลผลข้อมูลย้อนหลังจำนวนมากอีกครั้ง คุณอัปเดตคําค้นหาให้ต่อท้ายเฉพาะข้อมูลของวันสุดท้ายได้โดยนําคําสั่ง CREATE or REPLACE TABLE ออกจากจุดเริ่มต้นของคําค้นหา และเพิ่มเกณฑ์เพิ่มเติมลงในอนุประโยค WHERE ในคําค้นหาย่อยเทียบกับตาราง events_intraday_ ดังนี้

FROM
  # Replace source table name
  `YOUR_PROJECT_ID.analytics_YOUR_GA_PROPERTY_ID.events_intraday_*`
WHERE
  event_name IN ('LCP', 'INP', 'CLS', 'first_visit', 'purchase')
  # The _TABLE_SUFFIX replaces the asterisk (*) in the table name
  # 
  AND _TABLE_SUFFIX = FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY)

คําค้นหานี้จะแสดงเฉพาะข้อมูลจากเมื่อวาน จากนั้นคุณสามารถใช้คอนโซล BigQuery เพื่อกำหนดเวลาให้คําค้นหาทํางานทุกวัน

10. แสดงข้อมูลเป็นภาพใน Google Data Studio

Google Data Studio รองรับการอ่านข้อมูลจาก Google BigQuery โดยกำเนิด ตอนนี้คุณมีweb-vitalsข้อมูลจาก Google Analytics 4 ที่อยู่ใน BigQuery แล้ว คุณสามารถใช้เครื่องมือเชื่อมต่อ BigQuery ของ Data Studio เพื่ออ่านตารางที่สร้างขึ้นได้โดยตรง

ใช้เครื่องมือเชื่อมต่อ Web Vitals

เนื่องจากการสร้างแดชบอร์ดตั้งแต่ต้นนั้นใช้เวลานาน เราจึงพัฒนาโซลูชันแบบแพ็กเกจที่จะสร้างแดชบอร์ดเทมเพลตให้คุณ ก่อนอื่น ตรวจสอบว่าคุณได้สร้างตาราง Web Vitals โดยใช้การค้นหาข้างต้นแล้ว จากนั้นเข้าถึงเครื่องมือเชื่อมต่อ Web Vitals สำหรับ Data Studio โดยใช้ลิงก์ goo.gle/web-vitals-connector

หลังจากให้สิทธิ์แบบครั้งเดียว คุณควรเห็นหน้าจอการกำหนดค่าต่อไปนี้

หน้าจอการให้สิทธิ์ตัวเชื่อมต่อ Web Vitals

ระบุรหัสตาราง BigQuery ที่สร้างขึ้น (เช่น ตารางเป้าหมาย) และรหัสโปรเจ็กต์การเรียกเก็บเงิน BigQuery หลังจากคลิกเชื่อมต่อแล้ว Data Studio จะสร้างแดชบอร์ดใหม่ตามเทมเพลตและเชื่อมโยงข้อมูลของคุณกับแดชบอร์ดนั้น คุณสามารถแก้ไข ปรับเปลี่ยน และแชร์แดชบอร์ดได้ตามต้องการ หากสร้างแดชบอร์ดแล้ว 1 ครั้ง คุณก็ไม่จำเป็นต้องไปที่ลิงก์ตัวเชื่อมต่ออีก เว้นแต่ต้องการสร้างแดชบอร์ดหลายรายการจากชุดข้อมูลที่แตกต่างกัน

ขณะไปยังส่วนต่างๆ ของแดชบอร์ด คุณจะเห็นแนวโน้มรายวันของเมตริก Web Vitals และข้อมูลการใช้งานบางอย่างของเว็บไซต์ เช่น ผู้ใช้และเซสชัน ในแท็บสรุป

ในแท็บการวิเคราะห์ผู้ใช้ คุณสามารถเลือกเมตริกและดูรายละเอียดเปอร์เซ็นไทล์ของเมตริก รวมถึงจํานวนผู้ใช้ตามเมตริกการใช้งานและเมตริกทางธุรกิจต่างๆ

แท็บการวิเคราะห์เส้นทางหน้าเว็บช่วยให้คุณระบุจุดที่มีปัญหาในเว็บไซต์ได้ ที่นี่คุณสามารถเลือกเมตริกเพื่อดูภาพรวม แต่คุณยังเห็นแผนที่แบบกระจายของเส้นทางหน้าเว็บทั้งหมดที่มีค่าเปอร์เซ็นไทล์บนแกน Y และจำนวนระเบียนบนแกน X แผนที่แบบกระจายช่วยระบุหน้าเว็บที่มีค่าเมตริกต่ำกว่าที่คาดไว้ได้ เมื่อเลือกหน้าเว็บแล้ว คุณจะเจาะลึกพื้นที่ที่มีปัญหาได้อีกด้วยแผนภูมิกระจายของตารางเส้นทางหน้าเว็บ หรือโดยการดูตารางเป้าหมายการแก้ไขข้อบกพร่อง

แท็บการวิเคราะห์รายได้เป็นตัวอย่างของวิธีตรวจสอบเมตริกธุรกิจและประสิทธิภาพในที่เดียวกัน ส่วนนี้จะพล็อตเซสชันทั้งหมดที่ผู้ใช้ทําการซื้อ คุณสามารถเปรียบเทียบรายได้ที่ได้รับกับประสบการณ์ของผู้ใช้ในเซสชันที่เฉพาะเจาะจง

11. แหล่งข้อมูลอื่นๆ

เก่งมากที่ทำ Codelab นี้เสร็จสมบูรณ์ ตอนนี้คุณควรจะติดตามประสิทธิภาพของ Core Web Vitals ในเว็บไซต์ได้แล้วด้วยระดับรายละเอียดสูง นอกจากนี้ คุณควรระบุประเภทหน้าเว็บและองค์ประกอบที่เฉพาะเจาะจงในเว็บไซต์ที่ทำให้เกิด CWV สูงได้ด้วย เพื่อให้มุ่งเน้นการเพิ่มประสิทธิภาพได้

อ่านเพิ่มเติม

web.dev มีบทความและกรณีศึกษามากมายเกี่ยวกับกลยุทธ์ในการปรับปรุง Core Web Vitals เริ่มต้นด้วยการเพิ่มประสิทธิภาพบทความสำหรับเมตริกแต่ละรายการ

เอกสารอ้างอิง