แพ็กเกจ Next.js สำหรับการจัดการไลบรารีของบุคคลที่สาม

ในปี 2021 ทีม Chrome Aurora ได้เปิดตัวคอมโพเนนต์สคริปต์เพื่อปรับปรุงประสิทธิภาพในการโหลดสคริปต์ของบุคคลที่สามใน Next.js หลังเปิดตัว เราได้ขยายความสามารถเพื่อให้นักพัฒนาซอฟต์แวร์โหลดทรัพยากรของบุคคลที่สามได้ง่ายและรวดเร็วขึ้น

บล็อกโพสต์นี้แสดงภาพรวมเกี่ยวกับฟีเจอร์ใหม่ๆ ที่เราเผยแพร่ โดยเฉพาะไลบรารี @next/third-parties รวมถึงข้อมูลสรุปเกี่ยวกับโครงการริเริ่มในอนาคตในแผนกลยุทธ์ของเรา

ผลกระทบด้านประสิทธิภาพของสคริปต์ของบุคคลที่สาม

41% ของคำขอของบุคคลที่สามทั้งหมดในเว็บไซต์ Next.js เป็นสคริปต์ สคริปต์อาจใช้เวลาค่อนข้างนานในการดาวน์โหลดและเรียกใช้ ซึ่งจะบล็อกการแสดงผลและชะลอการโต้ตอบของผู้ใช้ ซึ่งต่างจากเนื้อหาประเภทอื่นๆ ข้อมูลจากรายงานประสบการณ์ของผู้ใช้ (CrUX) ของ Chrome แสดงให้เห็นว่าเว็บไซต์ Next.js ที่โหลดสคริปต์ของบุคคลที่สามจำนวนมากขึ้นมีอัตราการโต้ตอบกับ Next Paint (INP) และ Largest Contentful Paint (LCP) ต่ำกว่า

แผนภูมิแท่งที่แสดงเปอร์เซ็นต์การลดลงของ Next.js ที่มีคะแนน INP และ LCP ที่ดีตามสัดส่วนจำนวนของบุคคลที่สามที่โหลด
รายงาน CrUX เดือนธันวาคม 2023 (110,823 เว็บไซต์)

สหสัมพันธ์ที่สังเกตได้ในแผนภูมินี้ไม่ได้บอกเป็นนัยถึงความเป็นเหตุผล อย่างไรก็ตาม การทดสอบในเครื่องให้หลักฐานเพิ่มเติมว่าสคริปต์ของบุคคลที่สามมีผลกระทบกับประสิทธิภาพของหน้าเว็บอย่างมาก เช่น แผนภูมิด้านล่างจะเปรียบเทียบเมตริกต่างๆ ของห้องทดลองเมื่อมีการเพิ่มคอนเทนเนอร์ Google Tag Manager ซึ่งประกอบด้วยแท็กที่เลือกแบบสุ่ม 18 แท็กลงในการจัดหมวดหมู่ ซึ่งเป็นแอปตัวอย่าง Next.js ยอดนิยม

แผนภูมิแท่งแสดงความแตกต่างของเมตริกต่างๆ ในห้องทดลองเมื่อเว็บไซต์โหลดโดยมีและไม่มี Google Tag Manager
WebPageTest (Mobile 4G - เวอร์จิเนียสหรัฐอเมริกา)

เอกสาร WebPageTest จะอธิบายรายละเอียดเกี่ยวกับวิธีวัดการจับเวลาเหล่านี้ เมื่อมองเผินๆ ก็เห็นได้ชัดว่าเมตริกในห้องทดลองเหล่านี้ทั้งหมดได้รับผลกระทบจากคอนเทนเนอร์ GTM ตัวอย่างเช่น Total block Time (TBT) เป็นพร็อกซีในห้องทดลองที่มีประโยชน์เมื่อเทียบกับ INP และเห็นว่าเพิ่มขึ้นเกือบ 20 เท่า

คอมโพเนนต์ของสคริปต์

เมื่อจัดส่งคอมโพเนนต์ <Script> ใน Next.js แล้ว เราได้แนะนำคอมโพเนนต์ดังกล่าวผ่าน API ที่ใช้งานง่ายซึ่งคล้ายกับองค์ประกอบ <script> แบบดั้งเดิมมากที่สุด การใช้สคริปต์นี้ช่วยให้นักพัฒนาซอฟต์แวร์ค้นหาสคริปต์ของบุคคลที่สามร่วมกันในคอมโพเนนต์ใดก็ได้ในแอปพลิเคชัน และ Next.js จะช่วยจัดลำดับสคริปต์หลังจากที่ทรัพยากรที่สำคัญโหลดขึ้นแล้ว

<!-- By default, script will load after page becomes interactive -->
<Script src="https://example.com/sample.js" />

<!-- Script is injected server-side and fetched before any page hydration occurs -->
<Script strategy=”beforeInteractive” src="https://example.com/sample.js" />

<!-- Script is fetched later during browser idle time -->
<Script strategy=”lazyOnload” src="https://example.com/sample.js" />

แอปพลิเคชัน Next.js หลายหมื่นแอป รวมถึงเว็บไซต์ยอดนิยม เช่น Patreon, Target และ Notion ต่างใช้คอมโพเนนต์ <Script> ถึงแม้ว่าจะมีประสิทธิภาพดังกล่าว แต่นักพัฒนาแอปบางรายได้นำเสนอข้อกังวลเกี่ยวกับสิ่งต่อไปนี้

  • ตำแหน่งในการวางคอมโพเนนต์ <Script> ในแอป Next.js ในขณะที่ทำตามวิธีการติดตั้งที่แตกต่างกันของผู้ให้บริการบุคคลที่สาม (ประสบการณ์การใช้งานสำหรับนักพัฒนาซอฟต์แวร์)
  • กลยุทธ์การโหลดแบบใดที่เหมาะสมที่สุดสำหรับใช้กับสคริปต์ต่างๆ ของบุคคลที่สาม (ประสบการณ์ของผู้ใช้)

เพื่อรับมือกับข้อกังวลทั้ง 2 ประการนี้ เราจึงได้เปิดตัว @next/third-parties ซึ่งเป็นไลบรารีเฉพาะทางที่มีชุดคอมโพเนนต์และยูทิลิตีที่เพิ่มประสิทธิภาพแล้วซึ่งปรับแต่งให้เหมาะกับบุคคลที่สามยอดนิยม

ประสบการณ์ของนักพัฒนาซอฟต์แวร์: ทำให้ไลบรารีของบุคคลที่สามจัดการได้ง่ายขึ้น

สคริปต์ของบุคคลที่สามจำนวนมากมีการใช้งานในเว็บไซต์ Next.js ในเปอร์เซ็นต์ที่สูง โดย Google Tag Manager ได้รับความนิยมมากที่สุด โดยมีเว็บไซต์ 66% ตามลำดับ @next/third-parties สร้างขึ้นบนคอมโพเนนต์ <Script> โดยใช้ Wrapper ระดับที่สูงขึ้นซึ่งออกแบบมาเพื่อลดความซับซ้อนของการใช้งานสำหรับกรณีการใช้งานทั่วไปเหล่านี้

import { GoogleAnalytics } from "@next/third-parties/google";

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
      <GoogleTagManager gtmId="GTM-XYZ" />
    </html>
  );
}

Google Analytics เป็นสคริปต์ของบุคคลที่สามที่ใช้กันอย่างแพร่หลายอีกประเภทหนึ่ง (52% ของเว็บไซต์ Next.js) มีคอมโพเนนต์ของตัวเองโดยเฉพาะด้วย

import { GoogleAnalytics } from "@next/third-parties/google";

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
      <GoogleAnalytics gaId="G-XYZ" />
    </html>
  );
}

@next/third-parties ช่วยลดความซับซ้อนของขั้นตอนการโหลดสคริปต์ที่ใช้กันโดยทั่วไป แต่ยังทำให้เราสามารถพัฒนายูทิลิตีสำหรับหมวดหมู่อื่นๆ ของบุคคลที่สาม ได้ เช่น การฝัง ตัวอย่างเช่น การฝัง Google Maps และ YouTube จะใช้ในเว็บไซต์ 8% และ 4% ตามลำดับ และเรายังได้จัดส่งคอมโพเนนต์เพื่อให้โหลดได้ง่ายขึ้นด้วย

import { GoogleMapsEmbed } from "@next/third-parties/google";
import { YouTubeEmbed } from "@next/third-parties/google";

export default function Page() {
  return (
    <>
      <GoogleMapsEmbed
        apiKey="XYZ"
        height={200}
        width="100%"
        mode="place"
        q="Brooklyn+Bridge,New+York,NY"
      />
      <YouTubeEmbed videoid="ogfYd705cRs" height={400} params="controls=0" />
    </>
  );
}

ประสบการณ์ของผู้ใช้: ทำให้ไลบรารีของบุคคลที่สามโหลดเร็วขึ้น

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

ดูตัวอย่างวิดีโอที่ฝังใน YouTube ในขณะที่การใช้งานแบบอื่นๆ บางรูปแบบ มีประสิทธิภาพดีกว่าการฝังแบบเนทีฟมาก ปัจจุบันคอมโพเนนต์ <YouTubeEmbed> ที่ส่งออกโดย @next/third-parties ใช้ lite-youtube-embed ซึ่งเมื่อแสดงในการเปรียบเทียบ Next.js แบบ "สวัสดีโลก" จะโหลดได้เร็วกว่าอย่างมาก

GIF ที่แสดงการเปรียบเทียบการโหลดหน้าเว็บระหว่างคอมโพเนนต์ฝัง YouTube และ iframe ของ YouTube แบบปกติ
WebPageTest (Mobile 4G - เวอร์จิเนียสหรัฐอเมริกา)

ในทำนองเดียวกัน สำหรับ Google Maps เรารวม loading="lazy" เป็นแอตทริบิวต์เริ่มต้นสำหรับการฝังเพื่อให้แน่ใจว่าแผนที่จะโหลดเฉพาะเมื่อมีระยะทางจากวิวพอร์ตที่ระบุเท่านั้น ข้อมูลนี้อาจดูเป็นแอตทริบิวต์ที่เห็นได้ชัด โดยเฉพาะเพราะในเอกสารประกอบของ Google Maps ได้มีการรวมไว้ในข้อมูลโค้ดตัวอย่าง แต่มีเว็บไซต์ Next.js เพียง 45% ที่ฝัง Google Maps เท่านั้นที่กำลังใช้ loading="lazy"

การเรียกใช้สคริปต์ของบุคคลที่สามใน Web Worker

เทคนิคขั้นสูงอย่างหนึ่งที่เรากำลังสำรวจใน @next/third-parties คือการทำให้โหลดสคริปต์ของบุคคลที่สามไปยัง Web Worker ได้ง่ายขึ้น ไลบรารีที่ได้รับความนิยม เช่น Partytown สามารถลดผลกระทบของสคริปต์ของบุคคลที่สามที่มีต่อประสิทธิภาพของหน้าเว็บได้อย่างมาก โดยการย้ายสคริปต์ออกจากชุดข้อความหลักทั้งหมด

GIF แบบเคลื่อนไหวต่อไปนี้แสดงให้เห็นถึงความแตกต่างของงานที่ใช้เวลานานและเวลาในการบล็อกเทรดหลักเมื่อใช้กลยุทธ์ <Script> ต่างๆ กับคอนเทนเนอร์ GTM ภายในเว็บไซต์ Next.js โปรดทราบว่าแม้การสลับระหว่างตัวเลือกกลยุทธ์จะเลื่อนเวลาการทำงานสคริปต์เหล่านี้ออกไปเท่านั้น แต่การย้ายสคริปต์การทำงานไปยัง Web Worker จะทำให้สคริปต์เหล่านี้หมดลงอย่างสิ้นเชิงในเทรดหลัก

GIF ที่แสดงความแตกต่างของเวลาในการบล็อกเทรดหลักสําหรับกลยุทธ์สคริปต์ต่างๆ
WebPageTest (Mobile 4G - เวอร์จิเนียสหรัฐอเมริกา)

ในตัวอย่างนี้ การย้ายการดำเนินการของคอนเทนเนอร์ GTM และสคริปต์แท็กที่เชื่อมโยงไปยังเว็บผู้ปฏิบัติงานลดลง TBT ลง 92%

โปรดทราบว่าหากไม่มีการจัดการอย่างรอบคอบ เทคนิคนี้อาจทําให้สคริปต์ของบุคคลที่สามจำนวนมากเสียหายในแบบเงียบๆ ทําให้การแก้ไขข้อบกพร่องทําได้ยาก ในอีกไม่กี่เดือนข้างหน้า เราจะตรวจสอบว่าคอมโพเนนต์ของบุคคลที่สามที่ @next/third-parties เสนอทำงานได้อย่างถูกต้องเมื่อเรียกใช้ใน Web Worker หรือไม่ ถ้าใช่ เราจะพยายามจัดหาวิธีที่ง่ายและไม่บังคับสำหรับนักพัฒนาแอปในการใช้เทคนิคนี้

ขั้นตอนถัดไป

ในกระบวนการพัฒนาแพ็กเกจนี้ เห็นได้ชัดว่าจำเป็นต้องรวมศูนย์คำแนะนำการโหลดของบุคคลที่สามเพื่อให้เฟรมเวิร์กอื่นๆ ได้รับประโยชน์จากเทคนิคพื้นฐานเดียวกันกับที่ใช้ เราจึงสร้าง Third Party Capital ซึ่งเป็นไลบรารีที่ใช้ JSON เพื่ออธิบายเทคนิคการโหลดของบุคคลที่สาม ซึ่งปัจจุบันใช้เป็นพื้นฐานสำหรับ @next/third-parties

ในขั้นตอนถัดไป เราจะมุ่งเน้นที่การปรับปรุงคอมโพเนนต์ที่มีให้สำหรับ Next.js อย่างต่อเนื่อง รวมถึงขยายความพยายามในการรวมยูทิลิตีที่คล้ายกันไว้ในเฟรมเวิร์กและแพลตฟอร์ม CMS อื่นๆ ที่ได้รับความนิยม ขณะนี้เรากำลังทำงานร่วมกับผู้ดูแลของ Nuxt และวางแผนที่จะเปิดตัวยูทิลิตีของบุคคลที่สามที่คล้ายกันซึ่งปรับให้เหมาะกับระบบนิเวศของพวกเขาในอนาคตอันใกล้

หากบุคคลที่สามรายใดรายหนึ่งที่คุณใช้ในแอป Next.js รองรับโดย @next/third-parties ติดตั้งแพ็กเกจแล้วลองใช้งานเลย! เราอยากทราบความคิดเห็นของคุณเกี่ยวกับ GitHub