ทําความเข้าใจวิสัยทัศน์เบื้องหลังคอมโพเนนต์สคริปต์ของ 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-prefetch วิธีนี้ช่วยให้สคริปต์ที่สำคัญเริ่มดาวน์โหลดได้เร็วขึ้น
<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> และมีตัวเลือกในการตั้งค่าลําดับความสําคัญในการโหลดสคริปต์ของบุคคลที่สามโดยใช้แอตทริบิวต์ strategy
// Example for beforeInteractive:
<Script src="https://cdnjs.cloudflare.com/polyfill/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
: นี่เป็นกลยุทธ์เริ่มต้นที่ใช้และเทียบเท่ากับการโหลดสคริปต์ที่มีแอตทริบิวต์ defer ควรใช้กับสคริปต์ที่เบราว์เซอร์สามารถเรียกใช้ได้หลังจากที่หน้าเว็บมีการโต้ตอบ เช่น สคริปต์การวิเคราะห์ Next.js จะแทรกสคริปต์เหล่านี้ฝั่งไคลเอ็นต์และสคริปต์จะทํางานหลังจากที่หน้าเว็บได้รับการไฮเดรต ดังนั้น Next.js จะเลื่อนการโหลดสคริปต์ของบุคคลที่สามทั้งหมดที่กําหนดโดยใช้คอมโพเนนต์สคริปต์ เว้นแต่จะระบุไว้เป็นอย่างอื่น ซึ่งจะเป็นค่าเริ่มต้นที่มีประสิทธิภาพlazyOnload
: ตัวเลือกนี้อาจใช้เพื่อโหลดสคริปต์ที่มีลําดับความสําคัญต่ำแบบ Lazy Loading เมื่อเบราว์เซอร์ไม่มีการใช้งาน ไม่จำเป็นต้องใช้ฟังก์ชันการทำงานจากสคริปต์ดังกล่าวทันทีที่หน้าเว็บเป็นแบบอินเทอร์แอกทีฟ เช่น ปลั๊กอินแชทหรือโซเชียลมีเดีย
นักพัฒนาแอปสามารถบอก Next.js ได้ว่าแอปพลิเคชันใช้สคริปต์อย่างไรโดยระบุกลยุทธ์ ซึ่งช่วยให้เฟรมเวิร์กใช้การเพิ่มประสิทธิภาพและแนวทางปฏิบัติแนะนำเพื่อโหลดสคริปต์ไปพร้อมกับตรวจสอบลําดับการโหลดที่ดีที่สุด
เมื่อใช้คอมโพเนนต์สคริปต์ นักพัฒนาซอฟต์แวร์จะวางสคริปต์ของบุคคลที่สามไว้ที่ใดก็ได้ในแอปพลิเคชันสำหรับบุคคลที่สามที่โหลดช้า และที่ระดับเอกสารสำหรับสคริปต์ที่สำคัญ ซึ่งหมายความว่าคอมโพเนนต์สคริปต์อาจอยู่ร่วมกับคอมโพเนนต์ที่ใช้สคริปต์ หลังจากการไฮเดรต ระบบจะแทรกสคริปต์ลงในส่วนหัวของเอกสารที่แสดงผลครั้งแรกหรือที่ด้านล่างของเนื้อหา โดยขึ้นอยู่กับกลยุทธ์ที่ใช้
การวัดผลลัพธ์
เราใช้เทมเพลตสำหรับ แอป Commerce และบล็อกเริ่มต้นของ Next.js เพื่อสร้างแอปเดโม 2 แอปที่ช่วยวัดผลกระทบของการใช้สคริปต์ของบุคคลที่สาม บุคคลที่สามที่ใช้กันโดยทั่วไปสําหรับ Google Tag Manager และการฝังโซเชียลมีเดียจะรวมอยู่ในหน้าแอปเหล่านี้โดยตรงในตอนแรก จากนั้นจึงรวมผ่านคอมโพเนนต์สคริปต์ จากนั้นเราเปรียบเทียบประสิทธิภาพของหน้าเว็บเหล่านี้ใน WebPageTest
สคริปต์ของบุคคลที่สามในแอปคอมเมิร์ซ Next.js
มีการเพิ่มสคริปต์ของบุคคลที่สามลงในเทมเพลตแอป Commerce สำหรับการสาธิตตามที่ระบุไว้ด้านล่าง
การเปรียบเทียบต่อไปนี้แสดงความคืบหน้าของภาพสำหรับชุดเริ่มต้นใช้งาน Commerce ของ Next.js ทั้ง 2 เวอร์ชัน ดังที่เห็น LCP เกิดขึ้นเร็วขึ้นเกือบ 1 วินาทีเมื่อเปิดใช้คอมโพเนนต์สคริปต์ด้วยกลยุทธ์การโหลดที่เหมาะสม
สคริปต์ของบุคคลที่สามในบล็อก Next.js
เพิ่มสคริปต์ของบุคคลที่สามลงในแอปบล็อกเดโมตามที่ระบุไว้ด้านล่าง
ก่อน | หลัง |
---|---|
Google Tag Manager แบบแอซิงค์ | คอมโพเนนต์สคริปต์ที่มี strategy = lazyonload สําหรับสคริปต์แต่ละรายการ 4 รายการ |
ปุ่มติดตามของ Twitter แบบแอซิงค์ | |
ปุ่มติดตามของ YouTube แบบไม่ใช้ Async หรือเลื่อน | |
ปุ่มติดตามของ LinkedIn แบบไม่ใช้การทำงานแบบแอซิงค์หรือเลื่อน |
ดังที่เห็นในวิดีโอ First Contentful Paint (FCP) เกิดขึ้นที่ 0.9 วินาทีในหน้าเว็บที่ไม่มีคอมโพเนนต์สคริปต์ และ 0.4 วินาทีในหน้าเว็บที่มีคอมโพเนนต์สคริปต์
การพัฒนาคอมโพเนนต์สคริปต์ในอนาคต
แม้ว่าตัวเลือกกลยุทธ์สําหรับ afterInteractive
และ lazyOnload
จะมอบการควบคุมที่สําคัญเกี่ยวกับสคริปต์ที่บล็อกการแสดงผล แต่เรายังกําลังสํารวจตัวเลือกอื่นๆ ที่จะช่วยเพิ่มประโยชน์ของคอมโพเนนต์สคริปต์ด้วย
การใช้ผู้ปฏิบัติงานเกี่ยวกับเว็บ
Web Worker ใช้เพื่อเรียกใช้สคริปต์อิสระในเธรดเบื้องหลังได้ ซึ่งจะช่วยเพิ่มพื้นที่ว่างของเธรดหลักเพื่อจัดการกับงานการประมวลผลอินเทอร์เฟซผู้ใช้และปรับปรุงประสิทธิภาพ Web Worker เหมาะอย่างยิ่งสำหรับการประมวลผล JavaScript แทนการประมวลผล UI ออกจากเธรดหลัก สคริปต์ที่ใช้สำหรับการสนับสนุนลูกค้าหรือการตลาด ซึ่งปกติจะไม่โต้ตอบกับ UI อาจเป็นตัวเลือกที่ดีสำหรับการเรียกใช้ในเธรดแบ็กกราวด์ อาจใช้ไลบรารีของบุคคลที่สามที่มีน้ำหนักเบาอย่าง PartyTown เพื่อแยกสคริปต์ดังกล่าวไว้ในเว็บเวิร์กเกอร์
เมื่อติดตั้งใช้งานคอมโพเนนต์สคริปต์ Next.js ในปัจจุบัน เราขอแนะนำให้เลื่อนเวลาสคริปต์เหล่านี้ในเธรดหลักโดยตั้งค่ากลยุทธ์เป็น afterInteractive
หรือ lazyOnload
ในอนาคต เราขอแนะนําให้เปิดตัวตัวเลือกกลยุทธ์ใหม่ 'worker'
ซึ่งจะช่วยให้ Next.js ใช้ PartyTown หรือโซลูชันที่กําหนดเองเพื่อเรียกใช้สคริปต์ใน Web Worker ได้ เรายินดีรับฟังความคิดเห็นจากนักพัฒนาแอปเกี่ยวกับ RFC นี้
การลด 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 ที่แสดงความคิดเห็นเกี่ยวกับโพสต์นี้