การเพิ่มประสิทธิภาพการโหลดสคริปต์ของบุคคลที่สามใน Next.js

ทำความเข้าใจวิสัยทัศน์เบื้องหลังคอมโพเนนต์สคริปต์ของ Next.js ซึ่งมอบโซลูชันในตัวที่ช่วยเพิ่มประสิทธิภาพในการโหลดสคริปต์ของบุคคลที่สาม

ลีน่า โซโฮนี
ลีนา โซโฮนี
ฮูสเซน จิร์เดห์
ฮูสเซน จิร์เดห์

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

สคริปต์จากบุคคลที่สามและผลกระทบต่อประสิทธิภาพ

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

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

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

การตรวจสอบ Lighthouse เพื่อกำจัดทรัพยากรที่บล็อกการแสดงผลและลดการใช้งานของบุคคลที่สาม

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

แม้จะมีแนวทางปฏิบัติที่ดีที่สุดที่จะช่วยลดผลกระทบจากบุคคลที่สาม แต่อาจมีบางคนที่ยังไม่ทราบวิธีนำไปใช้กับบุคคลที่สามทุกราย ปัญหานี้อาจซับซ้อนเนื่องจาก

  • โดยเฉลี่ยแล้ว เว็บไซต์ใช้บุคคลที่สาม 21 ถึง 23 ราย รวมถึงสคริปต์ ทั้งบนอุปกรณ์เคลื่อนที่และเดสก์ท็อป การใช้งานและคำแนะนำอาจแตกต่างกันในแต่ละกรณี
  • การใช้งานบุคคลที่สามจำนวนมากอาจแตกต่างกันไป โดยขึ้นอยู่กับว่ามีการใช้เฟรมเวิร์กหรือไลบรารี UI หนึ่งๆ หรือไม่
  • ไลบรารีของบุคคลที่สามใหม่ๆ จะมีเพิ่มเข้ามาเรื่อยๆ
  • ข้อกำหนดทางธุรกิจที่หลากหลายซึ่งเกี่ยวข้องกับบุคคลที่สามรายเดียวกันทำให้นักพัฒนาแอปกำหนดการใช้งานที่เป็นมาตรฐานได้ยาก

Aurora มุ่งเน้นที่สคริปต์ของบุคคลที่สาม

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

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

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

การจัดลำดับสคริปต์ของบุคคลที่สามที่ไม่มีคอมโพเนนต์ของเฟรมเวิร์ก

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

  1. ใช้แอตทริบิวต์ async หรือ defer กับแท็ก <script> ที่บอกให้เบราว์เซอร์โหลดสคริปต์บุคคลที่สามที่ไม่สำคัญโดยไม่บล็อกโปรแกรมแยกวิเคราะห์เอกสาร สคริปต์ที่ไม่จำเป็นสำหรับการโหลดหน้าเว็บครั้งแรกหรือการโต้ตอบครั้งแรกของผู้ใช้อาจถือว่าไม่สำคัญ

       <script src="https://example.com/script1.js" defer></script>
       <script src="https://example.com/script2.js" async></script>
    
  2. สร้างการเชื่อมต่อกับต้นทางที่จำเป็นตั้งแต่เนิ่นๆ โดยใช้การเชื่อมต่อล่วงหน้าและการดึงข้อมูล DNS ล่วงหน้า ซึ่งจะช่วยให้สคริปต์ที่สำคัญเริ่มดาวน์โหลดได้เร็วขึ้น

       <head>
           <link rel="preconnect" href="http://PreconnThis.com">
           <link rel="dns-prefetch" href="http://PrefetchThis.com">
       </head>
    
  3. การโหลดแบบ Lazy Loading ทรัพยากรของบุคคลที่สามและการฝังหลังจากเนื้อหาของหน้าหลักโหลดเสร็จแล้ว หรือเมื่อผู้ใช้เลื่อนลงไปที่ส่วนของหน้าที่รวมเนื้อหาไว้

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

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

คอมโพเนนต์สคริปต์สร้างขึ้นบนแท็ก HTML <script> และมีตัวเลือกในการตั้งค่าลำดับความสำคัญในการโหลดสำหรับสคริปต์บุคคลที่สามโดยใช้แอตทริบิวต์กลยุทธ์

// Example for beforeInteractive:
<Script src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserverEntry%2CIntersectionObserver" strategy="beforeInteractive" />

// Example for afterInteractive (default):
<Script src="https://example.com/samplescript.js" />

// Example for lazyonload:
<Script src="https://connect.facebook.net/en_US/sdk.js" strategy="lazyOnload" />

แอตทริบิวต์กลยุทธ์มีได้ 3 ค่า

  1. beforeInteractive: ตัวเลือกนี้สามารถใช้กับสคริปต์สำคัญที่ควรทำงานก่อนที่หน้าเว็บจะโต้ตอบ Next.js จะช่วยให้แน่ใจว่ามีการแทรกสคริปต์ดังกล่าวลงใน HTML เริ่มต้นบนเซิร์ฟเวอร์ และทำงานก่อน JavaScript ที่จัดกลุ่มด้วยตนเอง การจัดการความยินยอม สคริปต์การตรวจจับบ็อต หรือไลบรารีตัวช่วยที่จำเป็นต่อการแสดงเนื้อหาที่สำคัญคือตัวเลือกที่ดีสำหรับกลยุทธ์นี้

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

  3. lazyOnload: ตัวเลือกนี้อาจใช้เพื่อโหลดสคริปต์ที่มีลำดับความสำคัญต่ำแบบ Lazy Loading เมื่อไม่มีการใช้งานเบราว์เซอร์ คุณไม่จำเป็นต้องใช้ฟังก์ชันสคริปต์ดังกล่าวทันทีที่หน้าเว็บมีการโต้ตอบ เช่น แชทหรือปลั๊กอินโซเชียลมีเดีย

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

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

การวัดผลกระทบ

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

สคริปต์ของบุคคลที่สามในแอปเชิงพาณิชย์ของ Next.js

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

ก่อน หลัง
Google Tag Manager แบบไม่พร้อมกัน คอมโพเนนต์ของสคริปต์ที่มีกลยุทธ์ = afterInteractive สำหรับสคริปต์ทั้งสอง
ปุ่มติดตามของ Twitter โดยไม่มีการซิงค์หรือเลื่อน
การกำหนดค่าสคริปต์และคอมโพเนนต์สคริปต์สำหรับเดโม 1 โดยมี 2 สคริปต์

การเปรียบเทียบต่อไปนี้จะแสดงความคืบหน้าของภาพสำหรับ Next.js commerce starter-kit ทั้ง 2 เวอร์ชัน ดังที่เห็น ภาวะ LCP เกิดขึ้นเร็วขึ้นเกือบ 1 วินาทีที่เปิดใช้คอมโพเนนต์สคริปต์ด้วยกลยุทธ์การโหลดที่ถูกต้อง

การเปรียบเทียบแถบฟิล์มที่แสดงการปรับปรุงใน LCP

สคริปต์ของบุคคลที่สามในบล็อก Next.js

มีการเพิ่มสคริปต์ของบุคคลที่สามลงในแอปบล็อกสาธิตตามที่ระบุไว้ด้านล่าง

ก่อน หลัง
Google Tag Manager แบบไม่พร้อมกัน องค์ประกอบสคริปต์ที่มีกลยุทธ์ = Lazyonload สำหรับแต่ละสคริปต์ทั้ง 4 สคริปต์
ปุ่มติดตามของ Twitter แบบไม่พร้อมกัน
ปุ่มติดตามของ YouTube แบบไม่ซิงค์หรือเลื่อน
ปุ่มติดตามใน LinkedIn โดยไม่มีการซิงค์หรือเลื่อน
การกำหนดค่าสคริปต์และคอมโพเนนต์ของสคริปต์สำหรับการสาธิต 2 โดยมีสคริปต์ 4 รายการ
วิดีโอแสดงความคืบหน้าในการโหลดหน้าดัชนีที่มีและไม่มีคอมโพเนนต์สคริปต์ FCP จะมีการปรับปรุง 0.5 วินาทีด้วยคอมโพเนนต์สคริปต์

ตามที่เห็นในวิดีโอ First Contentful Paint (FCP) จะปรากฏขึ้นที่ 0.9 วินาทีในหน้าเว็บโดยไม่มีคอมโพเนนต์สคริปต์ และ 0.4 วินาทีที่มีคอมโพเนนต์สคริปต์

ขั้นตอนต่อไปของคอมโพเนนต์สคริปต์

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

การใช้ Web Worker

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

เมื่อใช้งานคอมโพเนนต์สคริปต์ Next.js อยู่ เราขอแนะนำให้เลื่อนเวลาสคริปต์เหล่านี้ไปไว้ในชุดข้อความหลักโดยตั้งค่ากลยุทธ์เป็น afterInteractive หรือ lazyOnload ในอนาคตเราขอเสนอ 'worker' ซึ่งเป็นตัวเลือกกลยุทธ์ใหม่ ซึ่งจะช่วยให้ Next.js ใช้ PartyTown หรือโซลูชันที่กำหนดเองเพื่อเรียกใช้สคริปต์ใน Web Worker ได้ เรายินดีรับฟังความคิดเห็นจากนักพัฒนาซอฟต์แวร์เกี่ยวกับ RFC นี้

ลด CLS

การฝังของบุคคลที่สาม เช่น โฆษณา วิดีโอ หรือการฝังฟีดโซเชียลมีเดียอาจทำให้เลย์เอาต์เปลี่ยนแปลงเมื่อโหลดแบบ Lazy Loading ซึ่งจะส่งผลต่อประสบการณ์ของผู้ใช้และเมตริก Cumulative Layout Shift (CLS) สําหรับหน้าเว็บ คุณย่อ CLS ได้โดยระบุขนาดของคอนเทนเนอร์ที่จะโหลดการฝัง

คอมโพเนนต์สคริปต์อาจใช้เพื่อโหลดเนื้อหาที่ฝังซึ่งอาจทำให้เกิดการเปลี่ยนเลย์เอาต์ได้ ทั้งนี้เรากำลังพิจารณาที่จะเพิ่ม CLS เพื่อให้มีตัวเลือกการกำหนดค่าที่จะช่วยลด CLS ได้ ตัวเลือกนี้อาจใช้งานได้ภายในคอมโพเนนต์สคริปต์เองหรือเป็นคอมโพเนนต์ร่วม

ส่วนประกอบของ Wrapper

ไวยากรณ์และกลยุทธ์การโหลดสำหรับการรวมสคริปต์ของบุคคลที่สามยอดนิยม เช่น Google Analytics หรือ Google Tag Manager (GTM) มักจะได้รับการแก้ไข ซึ่งสามารถครอบคลุมเพิ่มเติมในคอมโพเนนต์ Wrapper แต่ละรายการสำหรับสคริปต์แต่ละประเภท นักพัฒนาซอฟต์แวร์จะสามารถใช้ชุดแอตทริบิวต์เฉพาะแอปพลิเคชัน (เช่น รหัสติดตาม) ได้เพียงไม่กี่ชุด องค์ประกอบของ Wrapper จะช่วยนักพัฒนาซอฟต์แวร์โดยทำดังนี้

  1. ช่วยให้ใส่แท็กสคริปต์ยอดนิยมได้ง่ายขึ้น
  2. ตรวจสอบว่าเฟรมเวิร์กใช้กลยุทธ์ที่เหมาะสมที่สุดขั้นสูงสุด

บทสรุป

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

บริการรับรองคำให้การ

ขอขอบคุณ Kara Erickson, Janicklas Ralph, Katie Hempenius, Philip Walton, Jeremy Wagner และ Addy Osmani ที่แสดงความคิดเห็นเกี่ยวกับโพสต์นี้