ทำความเข้าใจวิสัยทัศน์เบื้องหลังคอมโพเนนต์สคริปต์ของ Next.js ซึ่งมอบโซลูชันในตัวที่ช่วยเพิ่มประสิทธิภาพในการโหลดสคริปต์ของบุคคลที่สาม
ประมาณ 45% ของคำขอจากเว็บไซต์ที่แสดงบนอุปกรณ์เคลื่อนที่และเดสก์ท็อปเป็นคำขอของบุคคลที่สาม โดยมี 33% เป็นสคริปต์ ขนาด เวลาในการตอบสนอง และการโหลดสคริปต์ของบุคคลที่สามอาจส่งผลกระทบต่อประสิทธิภาพของเว็บไซต์อย่างมาก คอมโพเนนต์สคริปต์ Next.js มาพร้อมกับแนวทางปฏิบัติที่ดีที่สุดและค่าเริ่มต้นที่ช่วยให้นักพัฒนาซอฟต์แวร์แนะนำสคริปต์ของบุคคลที่สามในแอปพลิเคชันของตน รวมถึงแก้ไขปัญหาด้านประสิทธิภาพที่อาจเกิดขึ้นได้ทันที
สคริปต์จากบุคคลที่สามและผลกระทบต่อประสิทธิภาพ
สคริปต์ของบุคคลที่สามช่วยให้นักพัฒนาเว็บใช้ประโยชน์จากโซลูชันที่มีอยู่เพื่อใช้ฟีเจอร์ทั่วไปและลดเวลาในการพัฒนาได้ แต่ผู้สร้างสคริปต์เหล่านี้มักจะไม่มีสิ่งจูงใจใดๆ ที่จะพิจารณาผลกระทบด้านประสิทธิภาพที่มีต่อเว็บไซต์ที่เข้าชม สคริปต์เหล่านี้ยังเป็นกล่องดำสำหรับนักพัฒนาซอฟต์แวร์ที่ใช้สคริปต์ดังกล่าวด้วย
สคริปต์จะพิจารณาไบต์ของบุคคลที่สามจำนวนมากที่เว็บไซต์ดาวน์โหลดในหมวดหมู่ต่างๆ ของคำขอของบุคคลที่สาม โดยค่าเริ่มต้น เบราว์เซอร์จะจัดลําดับความสําคัญของสคริปต์ตามตำแหน่งในเอกสาร ซึ่งอาจทําให้การค้นหาหรือการเรียกใช้สคริปต์สําคัญต่อประสบการณ์ของผู้ใช้ล่าช้า
ควรโหลดไลบรารีของบุคคลที่สามที่จำเป็นสำหรับเลย์เอาต์ไว้ตั้งแต่เนิ่นๆ เพื่อแสดงผลหน้าเว็บ ควรเลื่อนบุคคลที่สามที่ไม่จำเป็นต้องใช้ในการแสดงผลครั้งแรกเพื่อไม่ให้บล็อกการประมวลผลอื่นๆ ในเทรดหลัก Lighthouse มีการตรวจสอบ 2 รายการเพื่อแจ้งเกี่ยวกับการบล็อกการแสดงผลหรือสคริปต์การบล็อกเทรดหลัก
สิ่งสำคัญคือต้องพิจารณาลำดับการโหลดทรัพยากรของหน้าเว็บ เพื่อไม่ให้ทรัพยากรที่สำคัญล่าช้า และทรัพยากรที่ไม่สำคัญไม่บล็อกทรัพยากรที่สำคัญ
แม้จะมีแนวทางปฏิบัติที่ดีที่สุดที่จะช่วยลดผลกระทบจากบุคคลที่สาม แต่อาจมีบางคนที่ยังไม่ทราบวิธีนำไปใช้กับบุคคลที่สามทุกราย ปัญหานี้อาจซับซ้อนเนื่องจาก
- โดยเฉลี่ยแล้ว เว็บไซต์ใช้บุคคลที่สาม 21 ถึง 23 ราย รวมถึงสคริปต์ ทั้งบนอุปกรณ์เคลื่อนที่และเดสก์ท็อป การใช้งานและคำแนะนำอาจแตกต่างกันในแต่ละกรณี
- การใช้งานบุคคลที่สามจำนวนมากอาจแตกต่างกันไป โดยขึ้นอยู่กับว่ามีการใช้เฟรมเวิร์กหรือไลบรารี UI หนึ่งๆ หรือไม่
- ไลบรารีของบุคคลที่สามใหม่ๆ จะมีเพิ่มเข้ามาเรื่อยๆ
- ข้อกำหนดทางธุรกิจที่หลากหลายซึ่งเกี่ยวข้องกับบุคคลที่สามรายเดียวกันทำให้นักพัฒนาแอปกำหนดการใช้งานที่เป็นมาตรฐานได้ยาก
Aurora มุ่งเน้นที่สคริปต์ของบุคคลที่สาม
ส่วนหนึ่งของการทำงานร่วมกันของ Aurora กับเครื่องมือและเฟรมเวิร์กของเว็บโอเพนซอร์สคือการมอบเครื่องมือเริ่มต้นที่มีประสิทธิภาพและเครื่องมือที่ได้รับความคิดเห็นเพื่อช่วยให้นักพัฒนาซอฟต์แวร์ปรับปรุงประสบการณ์ของผู้ใช้ในด้านต่างๆ เช่น ประสิทธิภาพ การช่วยเหลือพิเศษ ความปลอดภัย และความพร้อมของอุปกรณ์เคลื่อนที่ ในปี 2021 เรามุ่งเน้นที่การช่วยสแต็กเฟรมเวิร์กในการปรับปรุงประสบการณ์ของผู้ใช้และเมตริก Core Web Vitals
หนึ่งในขั้นตอนสําคัญที่สุดในการบรรลุเป้าหมายในการปรับปรุงประสิทธิภาพของเฟรมเวิร์ก ซึ่งเกี่ยวข้องกับการค้นคว้าลำดับการโหลดที่เหมาะสมของสคริปต์ของบุคคลที่สามใน Next.js เฟรมเวิร์ก เช่น Next.js จะมีตำแหน่งเฉพาะตัวเพื่อให้มีค่าเริ่มต้นและฟีเจอร์ที่เป็นประโยชน์ ซึ่งช่วยให้นักพัฒนาซอฟต์แวร์โหลดทรัพยากรต่างๆ ได้อย่างมีประสิทธิภาพ รวมถึงบุคคลที่สามด้วย เราได้ศึกษา HTTP Archive และ ข้อมูล Lighthouse จำนวนมาก เพื่อค้นหาว่าบุคคลที่สามรายใดบ้างที่บล็อกการแสดงผลมากที่สุดในเฟรมเวิร์กต่างๆ
เราได้สร้างคอมโพเนนต์สคริปต์เพื่อแก้ปัญหาที่บล็อกเทรดหลักบล็อกสคริปต์ของบุคคลที่สามซึ่งใช้ในแอปพลิเคชัน คอมโพเนนต์นี้รวมฟีเจอร์ลำดับเพื่อให้นักพัฒนาซอฟต์แวร์ควบคุมการโหลดสคริปต์ของบุคคลที่สามได้ดียิ่งขึ้น
การจัดลำดับสคริปต์ของบุคคลที่สามที่ไม่มีคอมโพเนนต์ของเฟรมเวิร์ก
คำแนะนำที่มีอยู่เพื่อลดผลกระทบของสคริปต์การบล็อกการแสดงผลมีวิธีการโหลดและจัดลำดับสคริปต์ของบุคคลที่สามอย่างมีประสิทธิภาพดังต่อไปนี้
ใช้แอตทริบิวต์
async
หรือdefer
กับแท็ก<script>
ที่บอกให้เบราว์เซอร์โหลดสคริปต์บุคคลที่สามที่ไม่สำคัญโดยไม่บล็อกโปรแกรมแยกวิเคราะห์เอกสาร สคริปต์ที่ไม่จำเป็นสำหรับการโหลดหน้าเว็บครั้งแรกหรือการโต้ตอบครั้งแรกของผู้ใช้อาจถือว่าไม่สำคัญ<script src="https://example.com/script1.js" defer></script> <script src="https://example.com/script2.js" async></script>
สร้างการเชื่อมต่อกับต้นทางที่จำเป็นตั้งแต่เนิ่นๆ โดยใช้การเชื่อมต่อล่วงหน้าและการดึงข้อมูล DNS ล่วงหน้า ซึ่งจะช่วยให้สคริปต์ที่สำคัญเริ่มดาวน์โหลดได้เร็วขึ้น
<head> <link rel="preconnect" href="http://PreconnThis.com"> <link rel="dns-prefetch" href="http://PrefetchThis.com"> </head>
การโหลดแบบ 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 ค่า
beforeInteractive
: ตัวเลือกนี้สามารถใช้กับสคริปต์สำคัญที่ควรทำงานก่อนที่หน้าเว็บจะโต้ตอบ Next.js จะช่วยให้แน่ใจว่ามีการแทรกสคริปต์ดังกล่าวลงใน HTML เริ่มต้นบนเซิร์ฟเวอร์ และทำงานก่อน JavaScript ที่จัดกลุ่มด้วยตนเอง การจัดการความยินยอม สคริปต์การตรวจจับบ็อต หรือไลบรารีตัวช่วยที่จำเป็นต่อการแสดงเนื้อหาที่สำคัญคือตัวเลือกที่ดีสำหรับกลยุทธ์นี้afterInteractive
: กลยุทธ์นี้เป็นกลยุทธ์เริ่มต้นที่นำมาใช้ และเทียบเท่ากับการโหลดสคริปต์ที่มีแอตทริบิวต์ที่เลื่อนเวลาออกไป ควรใช้กับสคริปต์ที่เบราว์เซอร์เรียกใช้ได้หลังจากหน้าเว็บมีการโต้ตอบ เช่น สคริปต์การวิเคราะห์ Next.js แทรกสคริปต์เหล่านี้ในฝั่งไคลเอ็นต์ และทำงานหลังจากที่หน้าเว็บได้รับการไฮไลต์แล้ว ดังนั้น สคริปต์ของบุคคลที่สามทั้งหมดที่กำหนดโดยการใช้คอมโพเนนต์สคริปต์จะถูกเลื่อนออกไปโดย Next.js จึงจะมีค่าเริ่มต้นที่รัดกุม ยกเว้นกรณีที่ระบุไว้เป็นอย่างอื่นlazyOnload
: ตัวเลือกนี้อาจใช้เพื่อโหลดสคริปต์ที่มีลำดับความสำคัญต่ำแบบ Lazy Loading เมื่อไม่มีการใช้งานเบราว์เซอร์ คุณไม่จำเป็นต้องใช้ฟังก์ชันสคริปต์ดังกล่าวทันทีที่หน้าเว็บมีการโต้ตอบ เช่น แชทหรือปลั๊กอินโซเชียลมีเดีย
นักพัฒนาซอฟต์แวร์สามารถแจ้งให้ Next.js ทราบว่าแอปพลิเคชันของตนใช้สคริปต์อย่างไรโดยระบุกลยุทธ์ วิธีนี้จะช่วยให้เฟรมเวิร์กใช้การเพิ่มประสิทธิภาพและแนวทางปฏิบัติแนะนำเพื่อโหลดสคริปต์โดยที่ยังได้ลำดับการโหลดที่ดีที่สุด
นักพัฒนาซอฟต์แวร์จะใช้คอมโพเนนต์ของสคริปต์เพื่อวางสคริปต์ของบุคคลที่สามไว้ที่ใดก็ได้ในแอปพลิเคชันสำหรับบุคคลที่สามที่โหลดล่าช้า และในระดับเอกสารสำหรับสคริปต์ที่สำคัญ ซึ่งหมายความว่าคอมโพเนนต์ของสคริปต์อาจมีตำแหน่งร่วมกับคอมโพเนนต์ดังกล่าวโดยใช้สคริปต์ หลังจากเติมน้ำแล้ว สคริปต์จะถูกแทรกลงในส่วนหัวของเอกสารที่แสดงผลครั้งแรก หรือที่ด้านล่างของเนื้อหา ขึ้นอยู่กับกลยุทธ์ที่ใช้
การวัดผลกระทบ
เราใช้เทมเพลตสำหรับแอปเชิงพาณิชย์และบล็อกเริ่มต้นของ Next.js เพื่อสร้างแอปเดโม 2 แอปที่จะช่วยวัดผลกระทบของการรวมสคริปต์ของบุคคลที่สาม บุคคลที่สามที่ใช้กันโดยทั่วไปสำหรับ Google Tag Manager และการฝังโซเชียลมีเดียจะรวมอยู่ในหน้าเว็บของแอปเหล่านี้โดยตรงก่อนแล้วจึงผ่านคอมโพเนนต์สคริปต์ จากนั้นเราได้เปรียบเทียบประสิทธิภาพของหน้าเว็บเหล่านี้บน WebPageTest
สคริปต์ของบุคคลที่สามในแอปเชิงพาณิชย์ของ Next.js
มีการเพิ่มสคริปต์ของบุคคลที่สามลงในเทมเพลตแอปเชิงพาณิชย์สำหรับการสาธิตตามที่ระบุไว้ด้านล่าง
การเปรียบเทียบต่อไปนี้จะแสดงความคืบหน้าของภาพสำหรับ Next.js commerce starter-kit ทั้ง 2 เวอร์ชัน ดังที่เห็น ภาวะ LCP เกิดขึ้นเร็วขึ้นเกือบ 1 วินาทีที่เปิดใช้คอมโพเนนต์สคริปต์ด้วยกลยุทธ์การโหลดที่ถูกต้อง
สคริปต์ของบุคคลที่สามในบล็อก Next.js
มีการเพิ่มสคริปต์ของบุคคลที่สามลงในแอปบล็อกสาธิตตามที่ระบุไว้ด้านล่าง
ก่อน | หลัง |
---|---|
Google Tag Manager แบบไม่พร้อมกัน | องค์ประกอบสคริปต์ที่มีกลยุทธ์ = Lazyonload สำหรับแต่ละสคริปต์ทั้ง 4 สคริปต์ |
ปุ่มติดตามของ Twitter แบบไม่พร้อมกัน | |
ปุ่มติดตามของ YouTube แบบไม่ซิงค์หรือเลื่อน | |
ปุ่มติดตามใน LinkedIn โดยไม่มีการซิงค์หรือเลื่อน |
ตามที่เห็นในวิดีโอ 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 จะช่วยนักพัฒนาซอฟต์แวร์โดยทำดังนี้
- ช่วยให้ใส่แท็กสคริปต์ยอดนิยมได้ง่ายขึ้น
- ตรวจสอบว่าเฟรมเวิร์กใช้กลยุทธ์ที่เหมาะสมที่สุดขั้นสูงสุด
บทสรุป
โดยปกติแล้ว สคริปต์ของบุคคลที่สามจะสร้างขึ้นเพื่อใส่คุณลักษณะที่เฉพาะเจาะจงในเว็บไซต์ที่ใช้งาน เพื่อลดผลกระทบของสคริปต์ที่ไม่สำคัญ เราขอแนะนำให้เลื่อนการทำงานออกไป ซึ่งคอมโพเนนต์สคริปต์ Next.js จะทำหน้าที่โดยค่าเริ่มต้น นักพัฒนาซอฟต์แวร์มั่นใจว่าการรวมสคริปต์จะไม่ทำให้ฟังก์ชันสำคัญล่าช้าลงจนกว่าจะใช้กลยุทธ์ beforeInteractive
อย่างชัดแจ้ง นักพัฒนาเฟรมเวิร์กยังสามารถพิจารณาสร้างฟีเจอร์เหล่านี้ในเฟรมเวิร์กอื่นๆ ได้เช่นเดียวกับคอมโพเนนต์สคริปต์ Next.js เรากำลังพยายามสำรวจองค์ประกอบที่คล้ายกันกับทีม Nuxt.js นอกจากนี้ เรายังหวังที่จะปรับปรุงองค์ประกอบของสคริปต์ให้ครอบคลุมกรณีการใช้งานอื่นๆ อีกด้วยตามความคิดเห็นที่ได้รับ
บริการรับรองคำให้การ
ขอขอบคุณ Kara Erickson, Janicklas Ralph, Katie Hempenius, Philip Walton, Jeremy Wagner และ Addy Osmani ที่แสดงความคิดเห็นเกี่ยวกับโพสต์นี้