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

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

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

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

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

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

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

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

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

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

เมื่อเปิดตัวคอมโพเนนต์ <Script> ใน Next.js เราได้เปิดตัวผ่าน API ที่ใช้งานง่ายซึ่งคล้ายกับองค์ประกอบ <script> แบบดั้งเดิม เมื่อใช้ Next.js นักพัฒนาแอปจะวางสคริปต์ของบุคคลที่สามไว้กับคอมโพเนนต์ใดก็ได้ในแอปพลิเคชัน และ 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 โดยยึดตามวิธีการติดตั้งที่แตกต่างกันของผู้ให้บริการบุคคลที่สาม(ประสบการณ์ของนักพัฒนาแอป)
  • กลยุทธ์การโหลดใดเหมาะสําหรับสคริปต์ของบุคคลที่สาม(ประสบการณ์ของผู้ใช้) แต่ละรายการมากที่สุด

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

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

สคริปต์ของบุคคลที่สามจํานวนมากมีการใช้งานในเว็บไซต์ 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 ในเว็บไซต์ Next.js คิดเป็น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 ซึ่งเมื่อแสดงในตัวอย่างการเปรียบเทียบ "Hello, World" ของ Next.js จะโหลดได้เร็วขึ้นมาก

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

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

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

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

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

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

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

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

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

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

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

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