แพ็กเกจ 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 และสคริปต์แท็กที่เชื่อมโยงไปยังผู้ปฏิบัติงานทำงานบนเว็บลดลง 92%

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

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

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

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

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