การสร้างเว็บไซต์อีคอมเมิร์ซขนาดใหญ่ขึ้นใหม่ด้วย Next.js (กรณีศึกษา)
เผยแพร่แล้ว: 2022-03-10ที่บริษัท Unplatform ของเรา เราได้สร้างไซต์อีคอมเมิร์ซมานานหลายทศวรรษแล้ว ในช่วงหลายปีที่ผ่านมา เราได้เห็นสแต็กเทคโนโลยีวิวัฒนาการจากหน้าที่แสดงผลของเซิร์ฟเวอร์ด้วย JavaScript และ CSS เล็กน้อย ไปจนถึงแอปพลิเคชัน JavaScript แบบเต็มรูปแบบ
แพลตฟอร์มที่เราใช้สำหรับไซต์อีคอมเมิร์ซของเรานั้นใช้ ASP.NET และเมื่อผู้เยี่ยมชมเริ่มคาดหวังการโต้ตอบที่มากขึ้น เราได้เพิ่ม React สำหรับส่วนหน้า แม้ว่าการผสมผสานแนวคิดของเว็บเฟรมเวิร์กของเซิร์ฟเวอร์เช่น ASP.NET กับเฟรมเวิร์กเว็บฝั่งไคลเอ็นต์อย่าง React จะทำให้สิ่งต่าง ๆ ซับซ้อนมากขึ้น แต่เราค่อนข้างพอใจกับโซลูชันนี้ นั่นคือจนกว่าเราจะไปที่การผลิตกับลูกค้าที่มีการเข้าชมสูงสุดของเรา ตั้งแต่เริ่มถ่ายทอดสด เราประสบปัญหาด้านประสิทธิภาพ Core Web Vitals มีความสำคัญ ยิ่งกว่านั้นในอีคอมเมิร์ซ ในการศึกษาของ Deloitte นี้: Milliseconds Make Millions ผู้วิจัยได้วิเคราะห์ข้อมูลไซต์บนมือถือของ 37 แบรนด์ที่แตกต่างกัน ด้วยเหตุนี้ พวกเขาจึงพบว่าการปรับปรุงประสิทธิภาพ 0.1 วินาทีอาจทำให้ Conversion เพิ่มขึ้น 10%
เพื่อลดปัญหาด้านประสิทธิภาพ เราต้องเพิ่มเซิร์ฟเวอร์พิเศษจำนวนมาก (ที่ไม่ได้จัดทำงบประมาณ) และต้องแคชหน้าในพร็อกซีย้อนกลับอย่างจริงจัง สิ่งนี้ทำให้เราต้องปิดการใช้งานฟังก์ชั่นบางส่วนของเว็บไซต์ เราลงเอยด้วยโซลูชันที่ซับซ้อนและมีราคาแพง ซึ่งในบางกรณีก็ให้บริการเฉพาะบางหน้าเท่านั้น
เห็นได้ชัดว่านี่ไม่ใช่ความรู้สึกที่ถูกต้อง จนกว่าเราจะพบ Next.js Next.js เป็นเว็บเฟรมเวิร์กที่ใช้ React ที่ให้คุณสร้างเพจแบบสแตติกได้ แต่คุณยังสามารถใช้การเรนเดอร์ฝั่งเซิร์ฟเวอร์ได้ ทำให้เหมาะสำหรับอีคอมเมิร์ซ สามารถโฮสต์บน CDN เช่น Vercel หรือ Netlify ซึ่งส่งผลให้ เวลาแฝงลดลง Vercel และ Netlify ยังใช้ฟังก์ชันแบบไร้เซิร์ฟเวอร์สำหรับการแสดงผลฝั่งเซิร์ฟเวอร์ ซึ่งเป็นวิธีที่มีประสิทธิภาพที่สุดในการขยายขนาด
ความท้าทาย
การพัฒนาด้วย Next.js นั้นยอดเยี่ยม แต่ก็มีความท้าทายอยู่บ้าง ประสบการณ์สำหรับนักพัฒนาซอฟต์แวร์กับ Next.js เป็นสิ่งที่คุณต้องสัมผัสให้ได้ โค้ดที่คุณเขียนจะ แสดงภาพได้ทันทีในเบราว์เซอร์ของคุณ และประสิทธิภาพการทำงานก็เพิ่มขึ้นอย่างรวดเร็ว นี่เป็นความเสี่ยงเช่นกัน เนื่องจากคุณสามารถจดจ่อกับประสิทธิภาพการทำงานมากเกินไป และละเลยการบำรุงรักษาโค้ดของคุณ เมื่อเวลาผ่านไป สิ่งนี้และลักษณะที่ไม่ได้พิมพ์ของ JavaScript สามารถนำไปสู่การลดระดับของ codebase ของคุณ จำนวนบั๊กเพิ่มขึ้นและประสิทธิภาพการทำงานเริ่มลดลง
นอกจากนี้ยังอาจเป็นสิ่งที่ท้าทายใน ด้านรันไทม์ของสิ่งต่างๆ การเปลี่ยนแปลงเพียงเล็กน้อยในโค้ดของคุณอาจทำให้ประสิทธิภาพและ Core Web Vitals อื่นๆ ลดลงได้ นอกจากนี้ การใช้การเรนเดอร์ฝั่งเซิร์ฟเวอร์โดยประมาทอาจนำไปสู่ค่าบริการที่ไม่คาดคิด
มาดูบทเรียนของเราที่ได้รับจากการเอาชนะความท้าทายเหล่านี้กันดีกว่า
- ทำให้ Codebase ของคุณเป็นแบบโมดูลาร์
- ผ้าสำลีและจัดรูปแบบโค้ดของคุณ
- ใช้ TypeScript
- วางแผนสำหรับประสิทธิภาพและวัดประสิทธิภาพ
- เพิ่มการตรวจสอบประสิทธิภาพให้กับประตูคุณภาพของคุณ
- เพิ่มการทดสอบอัตโนมัติ
- จัดการการพึ่งพาของคุณอย่างจริงจัง
- ใช้บริการรวบรวมบันทึก
- ฟังก์ชันเขียนซ้ำของ Next.js ช่วยให้นำไปใช้ได้เพิ่มขึ้น
บทเรียนที่ได้รับ: ปรับแต่ง Codebase ของคุณให้เป็นโมดูล
เฟรมเวิร์กส่วนหน้าเช่น Next.js ทำให้ง่ายต่อการเริ่มต้นในทุกวันนี้ คุณเพียงแค่เรียกใช้ npx create-next-app และคุณสามารถเริ่มเขียนโค้ดได้ แต่ถ้าคุณไม่ระวังและเริ่มตีโค้ดโดยไม่ได้คิดถึงการออกแบบ คุณอาจจะจบลงด้วยโคลนก้อนใหญ่
เมื่อคุณเรียกใช้ npx create-next-app
คุณจะมีโครงสร้างโฟลเดอร์ดังนี้ (นี่คือโครงสร้างตัวอย่างส่วนใหญ่):
/public logo.gif /src /lib /hooks useForm.js /api content.js /components Header.js Layout.js /pages Index.js
เราเริ่มใช้โครงสร้างเดียวกัน เรามีโฟลเดอร์ย่อยในโฟลเดอร์ส่วนประกอบสำหรับส่วนประกอบที่ใหญ่กว่า แต่ส่วนประกอบส่วนใหญ่อยู่ในโฟลเดอร์ส่วนประกอบรูท แนวทางนี้ไม่มีอะไรผิดปกติ และเหมาะสำหรับโครงการขนาดเล็ก อย่างไรก็ตาม เนื่องจากโครงการของเราเติบโตขึ้น การให้เหตุผลเกี่ยวกับส่วนประกอบและตำแหน่งที่ใช้งานยากขึ้น เรายังพบส่วนประกอบที่ไม่ได้ใช้เลยด้วยซ้ำ! นอกจากนี้ยังส่งเสริมก้อนโคลนขนาดใหญ่ เนื่องจากไม่มีคำแนะนำที่ชัดเจนว่าโค้ดใดควรขึ้นอยู่กับโค้ดอื่นใด
เพื่อแก้ปัญหานี้ เราตัดสินใจปรับ โครงสร้างโค้ดเบสและจัดกลุ่มโค้ดตามโมดูลการทำงาน (คล้ายกับโมดูล NPM) แทนที่จะเป็นแนวคิดทางเทคนิค:
/src /modules /catalog /components productblock.js /checkout /api cartservice.js /components cart.js
ในตัวอย่างเล็กๆ นี้มีโมดูลการชำระเงินและโมดูลแค็ตตาล็อก การจัดกลุ่มโค้ดด้วยวิธีนี้ทำให้สามารถค้นพบได้ดีขึ้น: เพียงแค่ดูที่โครงสร้างโฟลเดอร์ คุณก็จะทราบอย่างแน่ชัดว่ามีฟังก์ชันประเภทใดในฐานรหัสและจะหาได้จากที่ใด ยังทำให้ การให้เหตุผลเกี่ยวกับการพึ่งพาอาศัยกันง่ายขึ้น มาก ในสถานการณ์ก่อนหน้านี้ มีการพึ่งพากันระหว่างส่วนประกอบมากมาย เรามีคำขอดึงสำหรับการเปลี่ยนแปลงในการชำระเงินที่ส่งผลกระทบต่อส่วนประกอบแคตตาล็อกด้วย สิ่งนี้เพิ่มจำนวนความขัดแย้งในการรวมและทำให้การเปลี่ยนแปลงยากขึ้น
แนวทางแก้ไขที่ได้ผลดีที่สุดสำหรับเราคือทำให้การพึ่งพาอาศัยกันระหว่างโมดูลต่างๆ ให้น้อยที่สุด (ถ้าคุณต้องการการพึ่งพาจริงๆ ให้ตรวจสอบให้แน่ใจว่ามีทิศทางเดียว) และแนะนำระดับ "โครงการ" ที่เชื่อมโยงทุกอย่างเข้าด้วยกัน:
/src /modules /common /atoms /lib /catalog /components productblock.js /checkout /api cartservice.js /components cart.js /search /project /layout /components /templates productdetail.js cart.js /pages cart.js
ภาพรวมของโซลูชันนี้:
ระดับโปรเจ็กต์ประกอบด้วยโค้ดสำหรับเลย์เอาต์ของไซต์อีคอมเมิร์ซและเทมเพลตหน้า ใน Next.js ส่วนประกอบของเพจเป็นแบบแผนและให้ผลลัพธ์เป็นเพจที่มีอยู่จริง จากประสบการณ์ของเรา หน้าเหล่านี้มักจะต้องใช้การใช้งานแบบเดิมซ้ำ นั่นคือเหตุผลที่เราแนะนำแนวคิดของ "เทมเพลตหน้า" เทมเพลตหน้าใช้ส่วนประกอบจากโมดูลต่างๆ เช่น เทมเพลตหน้ารายละเอียดผลิตภัณฑ์จะใช้ส่วนประกอบจากแค็ตตาล็อกเพื่อแสดงข้อมูลผลิตภัณฑ์ แต่ยังเพิ่มส่วนประกอบในรถเข็นจากโมดูลการชำระเงินด้วย
เรายังมีโมดูลทั่วไป เนื่องจากยังมีโค้ดบางส่วนที่จำเป็นต้องใช้ซ้ำโดยโมดูลการทำงาน ประกอบด้วยอะตอมธรรมดาที่เป็นส่วนประกอบ React ที่ใช้เพื่อให้รูปลักษณ์และความรู้สึกสอดคล้องกัน นอกจากนี้ยังมีรหัสโครงสร้างพื้นฐาน คิดถึง hooks ตอบสนองทั่วไปหรือรหัสไคลเอ็นต์ GraphQL
คำเตือน : ตรวจสอบให้แน่ใจว่ารหัสในโมดูลทั่วไปนั้นเสถียรและคิดให้รอบคอบเสมอก่อนที่จะเพิ่มรหัสที่นี่ เพื่อป้องกันรหัสพันกัน
ไมโครฟรอนต์เอนด์
ในโซลูชันที่ใหญ่กว่าหรือเมื่อทำงานกับทีมต่างๆ การแยกแอปพลิเคชันออกเป็นส่วนย่อยที่เรียกว่าไมโครฟรอนท์ก็สมเหตุสมผล กล่าวโดยย่อ นี่หมายถึงการแยกแอปพลิเคชันออกเป็นหลายแอปพลิเคชันที่มีอยู่จริงซึ่งโฮสต์อย่างอิสระบน URL ที่แตกต่างกัน ตัวอย่างเช่น checkout.mydomain.com
และ catalog.mydomain.com สิ่งเหล่านี้จะถูกรวมเข้าด้วยกันโดยแอปพลิเคชันอื่นที่ทำหน้าที่เป็นพร็อกซี
ฟังก์ชันการเขียนซ้ำของ Next.js นั้นยอดเยี่ยมสำหรับสิ่งนี้ และการใช้งานในลักษณะนี้ได้รับการสนับสนุนโดย Multi Zones ที่เรียกว่า
ประโยชน์ของหลายโซนคือทุกโซนจัดการการพึ่งพาของตัวเอง นอกจากนี้ยังช่วยให้พัฒนา codebase แบบทีละส่วนได้ง่ายขึ้น: หาก Next.js หรือ React เวอร์ชันใหม่หลุดออกมา คุณสามารถอัปเกรดโซนทีละรายการแทนที่จะต้องอัปเกรดโค้ดเบสทั้งหมดพร้อมกัน ในองค์กรที่มีหลายทีม สิ่งนี้สามารถลดการพึ่งพาระหว่างทีมได้อย่างมาก
อ่านเพิ่มเติม
- “โครงสร้างโครงการ Next.js” Yannick Wittwer, Medium
- “คู่มือปี 2021 เกี่ยวกับการจัดโครงสร้างโปรเจ็กต์ Next.js ของคุณในวิธีที่ยืดหยุ่นและมีประสิทธิภาพ” Vadorequest, Dev.to
- “ไมโครฟรอนท์เอนด์” ไมเคิล เกียร์ส
บทเรียนที่ได้รับ: ผ้าสำลีและจัดรูปแบบโค้ดของคุณ
นี่คือสิ่งที่เราได้เรียนรู้ในโครงการก่อนหน้านี้: หากคุณทำงานใน codebase เดียวกันกับหลาย ๆ คนและไม่ได้ใช้ฟอร์แมตเตอร์ โค้ดของคุณจะไม่สอดคล้องกันในเร็วๆ นี้ แม้ว่าคุณจะใช้รูปแบบการเขียนโค้ดและกำลังทบทวนอยู่ ในไม่ช้า คุณจะเริ่มสังเกตเห็นรูปแบบการเขียนโค้ดที่แตกต่างกัน ซึ่งทำให้โค้ดดูยุ่งเหยิง
linter จะตรวจสอบโค้ดของคุณสำหรับปัญหาที่อาจเกิดขึ้น และตัวจัดรูปแบบจะตรวจสอบให้แน่ใจว่าโค้ดมีรูปแบบที่สอดคล้องกัน เราใช้ ESLint และสวยกว่า และคิดว่ามันยอดเยี่ยม คุณไม่จำเป็นต้องคิดถึงรูปแบบการเข้ารหัส ซึ่งช่วยลดภาระด้านความรู้ความเข้าใจในระหว่างการพัฒนา
โชคดีที่ Next.js 11 รองรับ ESLint ทันที (https://nextjs.org/blog/next-11) ทำให้ตั้งค่าได้ง่ายสุดด้วยการเรียกใช้ npx next lint ซึ่งช่วยคุณประหยัดเวลาได้มากเพราะมาพร้อมกับการกำหนดค่าเริ่มต้นสำหรับ Next.js ตัวอย่างเช่น มีการกำหนดค่าส่วนขยาย ESLint สำหรับ React แล้ว ยิ่งไปกว่านั้น ยังมาพร้อมกับส่วนขยายเฉพาะ Next.js ใหม่ที่จะตรวจพบปัญหากับโค้ดของคุณที่อาจส่งผลกระทบต่อ Core Web Vitals ของแอปพลิเคชันของคุณ! ในย่อหน้าต่อมา เราจะพูดถึงประตูคุณภาพที่สามารถช่วยคุณป้องกันการพุชโค้ดไปยังผลิตภัณฑ์ที่ทำให้ Core Web Vitals ของคุณเสียหายโดยไม่ได้ตั้งใจ ส่วนขยายนี้ให้คำติชมแก่คุณเร็วขึ้นมาก ทำให้เป็นส่วนเสริมที่ยอดเยี่ยม
อ่านเพิ่มเติม
- “ESLint” Next.js เอกสาร
- “ESLint” เว็บไซต์อย่างเป็นทางการ
บทเรียนที่ได้รับ: ใช้ TypeScript
เมื่อส่วนประกอบได้รับการแก้ไขและจัดองค์ประกอบใหม่ เราสังเกตเห็นว่าอุปกรณ์ประกอบฉากบางส่วนไม่ได้ใช้งานอีกต่อไป นอกจากนี้ ในบางกรณี เราพบข้อบกพร่องเนื่องจากอุปกรณ์ประกอบฉากที่หายไปหรือไม่ถูกต้องถูกส่งผ่านไปยังส่วนประกอบ
TypeScript เป็น superset ของ JavaScript และเพิ่มประเภท ซึ่งช่วยให้คอมไพเลอร์ตรวจสอบโค้ดของคุณแบบสแตติก เหมือนกับ linter บนสเตียรอยด์
ในช่วงเริ่มต้นของโครงการ เราไม่เห็นคุณค่าของการเพิ่ม TypeScript เรารู้สึกว่ามันเป็นเพียงนามธรรมที่ไม่จำเป็น อย่างไรก็ตาม เพื่อนร่วมงานคนหนึ่งของเรามีประสบการณ์ที่ดีกับ TypeScript และโน้มน้าวให้เราลองใช้มัน โชคดีที่ Next.js มีการรองรับ TypeScript ที่ยอดเยี่ยมและ TypeScript ให้คุณเพิ่มลงในโซลูชันของคุณทีละน้อย ซึ่งหมายความว่าคุณไม่จำเป็นต้องเขียนใหม่หรือแปลง codebase ทั้งหมดของคุณในครั้งเดียว แต่คุณสามารถเริ่มใช้งานได้ทันทีและค่อยๆ แปลง codebase ที่เหลืออย่างช้าๆ
เมื่อเราเริ่มย้ายส่วนประกอบไปยัง TypeScript เราพบปัญหาเกี่ยวกับค่าที่ไม่ถูกต้องถูกส่งผ่านไปยังส่วนประกอบและฟังก์ชัน นอกจากนี้ ลูปความคิดเห็นของนักพัฒนาซอฟต์แวร์สั้นลง และคุณจะได้รับแจ้งปัญหาก่อนที่จะเรียกใช้แอปในเบราว์เซอร์ ประโยชน์ที่สำคัญอีกประการหนึ่งที่เราพบคือทำให้การ refactor code ง่ายขึ้นมาก: ง่ายต่อการดูว่ามีการใช้รหัสที่ใด และคุณมองเห็นส่วนประกอบและรหัสที่ไม่ได้ใช้ทันที กล่าวโดยย่อ ประโยชน์ของ TypeScript:
- ลดจำนวนแมลง
- ทำให้การ refactor code ของคุณง่ายขึ้น
- รหัสอ่านง่ายขึ้น
อ่านเพิ่มเติม
- “TypeScript,” Next.js Docs
- TypeScript เว็บไซต์อย่างเป็นทางการ
บทเรียนที่ได้รับ: วางแผนเพื่อประสิทธิภาพและวัดประสิทธิภาพ
Next.js รองรับการแสดงผลล่วงหน้าประเภทต่างๆ: การสร้างแบบคงที่และการแสดงผลฝั่งเซิร์ฟเวอร์ เพื่อประสิทธิภาพที่ดีที่สุด ขอแนะนำให้ใช้การสร้างแบบคงที่ ซึ่งเกิดขึ้นระหว่างเวลาสร้าง แต่ไม่สามารถทำได้เสมอไป นึกถึงหน้ารายละเอียดสินค้าที่มีข้อมูลสต็อก ข้อมูลประเภทนี้เปลี่ยนแปลงบ่อยและการเรียกใช้งานบิลด์ทุกครั้งไม่สามารถปรับขนาดได้ดี โชคดีที่ Next.js ยังรองรับโหมดที่เรียกว่า Incremental Static Regeneration (ISR) ซึ่งยังคงสร้างเพจแบบสแตติก แต่จะสร้างขึ้นใหม่ในเบื้องหลังทุกๆ x วินาที เราได้เรียนรู้ว่าโมเดลนี้ใช้งานได้ดีกับแอปพลิเคชันขนาดใหญ่ ประสิทธิภาพยังคงยอดเยี่ยม ต้องใช้เวลา CPU น้อยกว่าการเรนเดอร์ฝั่งเซิร์ฟเวอร์ และลดเวลาในการสร้าง: เพจจะถูกสร้างขึ้นในคำขอแรกเท่านั้น สำหรับทุกหน้าที่คุณเพิ่ม คุณควรนึกถึงประเภทของการแสดงผลที่จำเป็น ขั้นแรก ให้ดูว่าคุณสามารถใช้การสร้างแบบคงที่ได้หรือไม่ หากไม่เป็นเช่นนั้น ให้ไปที่ Incremental Static Regeneration และหากไม่สามารถทำได้เช่นกัน คุณยังสามารถใช้การเรนเดอร์ฝั่งเซิร์ฟเวอร์ได้
Next.js จะกำหนดประเภทของการเรนเดอร์โดยอัตโนมัติโดยพิจารณาจากการขาด getServerSideProps
และ getInitialProps
บนเพจ เกิดข้อผิดพลาดได้ง่าย ซึ่งอาจทำให้หน้าเว็บแสดงผลบนเซิร์ฟเวอร์แทนที่จะสร้างแบบสแตติก ผลลัพธ์ของบิลด์ Next.js แสดงให้เห็นว่าหน้าใดใช้การเรนเดอร์ประเภทใด ดังนั้นอย่าลืมตรวจสอบสิ่งนี้ นอกจากนี้ยังช่วยตรวจสอบการผลิตและติดตามประสิทธิภาพของเพจและเวลาของ CPU ที่เกี่ยวข้อง ผู้ให้บริการโฮสต์ส่วนใหญ่จะเรียกเก็บเงินจากคุณตามเวลาของ CPU ซึ่งจะช่วยป้องกันไม่ให้เกิดความประหลาดใจอันไม่พึงประสงค์ใดๆ ฉันจะอธิบายวิธีที่เราตรวจสอบสิ่งนี้ในบทเรียนที่เรียนรู้: ใช้ย่อหน้าบริการการรวมบันทึก
ขนาดมัด
เพื่อให้มีประสิทธิภาพที่ดี จำเป็นต้องย่อขนาดบันเดิลให้น้อยที่สุด Next.js มีคุณสมบัติมากมายที่พร้อมจะช่วยได้ เช่น การแยกโค้ดอัตโนมัติ เพื่อให้แน่ใจว่ามีการโหลดเฉพาะ JavaScript และ CSS ที่จำเป็นเท่านั้นสำหรับทุกหน้า นอกจากนี้ยังสร้างบันเดิลที่แตกต่างกันสำหรับไคลเอนต์และสำหรับเซิร์ฟเวอร์ อย่างไรก็ตาม สิ่งสำคัญคือต้องจับตาดูสิ่งเหล่านี้ ตัวอย่างเช่น หากคุณนำเข้าโมดูล JavaScript ในทางที่ผิด เซิร์ฟเวอร์ JavaScript อาจไปอยู่ในบันเดิลไคลเอ็นต์ ซึ่งจะเพิ่มขนาดบันเดิลไคลเอ็นต์และทำให้ประสิทธิภาพลดลงอย่างมาก การเพิ่มการพึ่งพา NPM อาจส่งผลกระทบอย่างมากต่อขนาดบันเดิล
โชคดีที่ Next.js มาพร้อมกับเครื่องมือวิเคราะห์บันเดิลที่ให้ข้อมูลเชิงลึกว่าโค้ดใดใช้ส่วนใดของบันเดิล
อ่านเพิ่มเติม
- “Next.js + Webpack Bundle Analyzer” Vercel, GitHub
- “การดึงข้อมูล” Next.js Docs
บทเรียนที่ได้รับ: เพิ่มการตรวจสอบประสิทธิภาพให้กับประตูคุณภาพของคุณ
ประโยชน์ที่สำคัญอย่างหนึ่งของการใช้ Next.js คือความสามารถในการสร้างเพจแบบสแตติกและเพื่อให้สามารถปรับใช้แอปพลิเคชันกับขอบ (CDN) ได้ ซึ่งจะส่งผลให้ประสิทธิภาพการทำงานและ Web Vitals ยอดเยี่ยม เราได้เรียนรู้ว่าแม้ด้วยเทคโนโลยีที่ยอดเยี่ยมอย่าง Next.js การได้รับและรักษาคะแนน lighthouse ที่ยอดเยี่ยมนั้นเป็นเรื่องยากจริงๆ เกิดขึ้นหลายครั้งหลังจากที่เราปรับใช้การเปลี่ยนแปลงในการผลิต คะแนนประภาคารลดลงอย่างมาก ในการควบคุมกลับคืนมา เราได้เพิ่มการทดสอบประภาคารอัตโนมัติในเกทคุณภาพของเรา ด้วย Github Action คุณสามารถเพิ่มการทดสอบ lighthouse ให้กับคำขอดึงของคุณโดยอัตโนมัติ เรากำลังใช้ Vercel และทุกครั้งที่สร้างคำขอดึง Vercel จะปรับใช้กับ URL แสดงตัวอย่าง และเราใช้การดำเนินการ Github เพื่อเรียกใช้การทดสอบ lighthouse กับการปรับใช้นี้
หากคุณไม่ต้องการตั้งค่าการดำเนินการ GitHub ด้วยตนเอง หรือหากคุณต้องการดำเนินการเพิ่มเติม คุณสามารถพิจารณาบริการตรวจสอบประสิทธิภาพของบริษัทอื่น เช่น DebugBear Vercel ยังมีคุณลักษณะ Analytics ซึ่งวัด Web Vitals หลักของการปรับใช้จริงในเวอร์ชันที่ใช้งานจริงของคุณ Vercel Analytics รวบรวมการวัดจากอุปกรณ์ของผู้เยี่ยมชมของคุณ ดังนั้นคะแนนเหล่านี้จึงเป็นสิ่งที่ผู้เยี่ยมชมของคุณประสบอยู่จริงๆ ในขณะที่เขียน Vercel Analytics ใช้งานได้กับการปรับใช้จริงเท่านั้น
บทเรียนที่เรียนรู้: เพิ่มการทดสอบอัตโนมัติ
เมื่อ codebase มีขนาดใหญ่ขึ้น จะยากต่อการพิจารณาว่าการเปลี่ยนแปลงโค้ดของคุณอาจทำให้ฟังก์ชันการทำงานที่มีอยู่เสียหายหรือไม่ จากประสบการณ์ของเรา จำเป็นต้องมีชุดการทดสอบตั้งแต่ต้นจนจบที่ดีเพื่อเป็นตาข่ายนิรภัย แม้ว่าคุณจะมีโครงการขนาดเล็ก แต่ก็สามารถทำให้ชีวิตของคุณง่ายขึ้นมากเมื่อคุณมีการทดสอบควันขั้นพื้นฐานอย่างน้อย เราใช้ Cypress สำหรับสิ่งนี้และชอบมันมาก การใช้ Netlify หรือ Vercel เพื่อปรับใช้คำขอ Pull ของคุณโดยอัตโนมัติในสภาพแวดล้อมชั่วคราวและเรียกใช้การทดสอบ E2E ของคุณนั้นประเมินค่าไม่ได้
เราใช้ cypress-io/GitHub-action
เพื่อเรียกใช้การทดสอบ Cypress กับคำขอดึงของเราโดยอัตโนมัติ การทดสอบที่ละเอียดยิ่งขึ้นโดยใช้ Enzyme หรือ JEST ขึ้นอยู่กับประเภทของซอฟต์แวร์ที่คุณกำลังสร้าง ข้อเสียคือสิ่งเหล่านี้มีความเกี่ยวข้องมากขึ้นกับโค้ดของคุณและต้องการการบำรุงรักษาที่มากขึ้น
บทเรียนที่ได้รับ: จัดการการพึ่งพาของคุณอย่างจริงจัง
การจัดการการขึ้นต่อกันจะใช้เวลานาน แต่โอ้ กิจกรรมที่สำคัญมากเมื่อรักษาฐานโค้ด Next.js ขนาดใหญ่ NPM ทำให้การเพิ่มแพ็คเกจเป็นเรื่องง่ายและดูเหมือนว่าจะมีแพ็คเกจสำหรับทุกอย่างในทุกวันนี้ เมื่อมองย้อนกลับไป หลายครั้งที่เราแนะนำจุดบกพร่องใหม่หรือประสิทธิภาพการทำงานลดลง มีบางอย่างที่เกี่ยวข้องกับแพ็คเกจ NPM ใหม่หรือที่อัปเดต
ดังนั้น ก่อนติดตั้งแพ็คเกจ คุณควรถามตัวเองดังต่อไปนี้:
- คุณภาพของบรรจุภัณฑ์คืออะไร?
- การเพิ่มแพ็คเกจนี้มีความหมายต่อขนาดชุดรวมของฉันอย่างไร
- แพ็คเกจนี้จำเป็นจริง ๆ หรือมีทางเลือกอื่นหรือไม่?
- แพ็คเกจยังคงได้รับการดูแลอย่างแข็งขันหรือไม่?
เพื่อให้ขนาดบันเดิลมีขนาดเล็กและเพื่อลดความพยายามในการรักษาการขึ้นต่อกันเหล่านี้ สิ่งสำคัญคือต้องรักษาจำนวนการพึ่งพาให้น้อยที่สุด ตัวตนในอนาคตของคุณจะขอบคุณเมื่อคุณดูแลซอฟต์แวร์
เคล็ดลับ : ส่วนขยาย VSCode ของต้นทุนการนำเข้าจะแสดงขนาดของแพ็คเกจที่นำเข้าโดยอัตโนมัติ
ติดตามเวอร์ชันของ Next.js
การติดตาม Next.js & React เป็นสิ่งสำคัญ ไม่เพียงแต่จะให้คุณเข้าถึงคุณลักษณะใหม่ ๆ เท่านั้น แต่เวอร์ชันใหม่ยังรวมถึงการแก้ไขจุดบกพร่องและการแก้ไขสำหรับปัญหาด้านความปลอดภัยที่อาจเกิดขึ้น โชคดีที่ Next.js ทำให้การอัพเกรดเป็นเรื่องง่ายอย่างเหลือเชื่อด้วยการจัดหา Codemods (https://nextjs.org/docs/advanced-features/codemods สิ่งเหล่านี้คือการแปลงโค้ดอัตโนมัติที่จะอัปเดตโค้ดของคุณโดยอัตโนมัติ
อัปเดตการพึ่งพา
ด้วยเหตุผลเดียวกัน การรักษาเวอร์ชัน Next.js และ React ให้เป็นจริงเป็นสิ่งสำคัญ การอัปเดตการขึ้นต่อกันอื่นๆ ก็เป็นสิ่งสำคัญเช่นกัน Dependabot ของ Github (https://github.com/dependabot) สามารถช่วยได้ที่นี่ มันจะสร้าง Pull Requests โดยอัตโนมัติพร้อมการขึ้นต่อกันที่อัปเดต อย่างไรก็ตาม การอัปเดตการพึ่งพาอาจทำให้สิ่งต่างๆ เสียหายได้ ดังนั้นการทดสอบแบบ end-to-end แบบอัตโนมัติที่นี่สามารถช่วยชีวิตได้จริงๆ
บทเรียนที่ได้เรียนรู้: ใช้บริการ A Log Aggregation
เพื่อให้แน่ใจว่าแอปทำงานอย่างถูกต้องและเพื่อค้นหาปัญหาล่วงหน้า เราพบว่าจำเป็นอย่างยิ่งที่จะต้องกำหนดค่าบริการการรวมบันทึก Vercel อนุญาตให้คุณเข้าสู่ระบบและดูบันทึก แต่สิ่งเหล่านี้จะสตรีมแบบเรียลไทม์และจะไม่คงอยู่ นอกจากนี้ยังไม่สนับสนุนการกำหนดค่าการแจ้งเตือนและการแจ้งเตือน
ข้อยกเว้นบางอย่างอาจใช้เวลานานกว่าจะปรากฎ ตัวอย่างเช่น เราได้กำหนดค่า Stale-While-Revalidate สำหรับหน้าใดหน้าหนึ่งโดยเฉพาะ เมื่อถึงจุดหนึ่ง เราสังเกตเห็นว่าหน้าต่างๆ ไม่ได้รับการรีเฟรชและมีการเสิร์ฟข้อมูลเก่า หลังจากตรวจสอบการบันทึกของ Vercel เราพบว่ามีข้อยกเว้นเกิดขึ้นระหว่างการแสดงผลพื้นหลังของหน้า การใช้บริการการรวมบันทึกและการกำหนดค่าการแจ้งเตือนข้อยกเว้น เราจะสามารถระบุสิ่งนี้ได้เร็วกว่ามาก
บริการการรวมบันทึกยังมีประโยชน์ในการตรวจสอบขีดจำกัดของแผนการกำหนดราคาของ Vercel หน้าการใช้งานของ Vercel ยังให้ข้อมูลเชิงลึกแก่คุณในเรื่องนี้ แต่การใช้บริการรวมบันทึกช่วยให้คุณเพิ่มการแจ้งเตือนได้เมื่อถึงเกณฑ์ที่กำหนด การป้องกันดีกว่าการรักษา โดยเฉพาะอย่างยิ่งเมื่อพูดถึงการเรียกเก็บเงิน
Vercel นำเสนอการผสานการทำงานแบบนอกกรอบกับบริการการรวมบันทึก ซึ่งมี Datadog, Logtail, Logalert, Sentry และอื่นๆ อีกมากมาย
อ่านเพิ่มเติม
- “บูรณาการ” Vercel
บทเรียนที่ได้เรียนรู้: ฟังก์ชันการเขียนซ้ำของ Next.js ทำให้เกิดการยอมรับที่เพิ่มขึ้น
เว้นแต่จะมีปัญหาร้ายแรงกับเว็บไซต์ปัจจุบัน ลูกค้าจำนวนไม่มากจะรู้สึกตื่นเต้นที่จะเขียนเว็บไซต์ใหม่ทั้งหมด แต่ถ้าคุณสามารถเริ่มต้นด้วยการสร้างใหม่เฉพาะหน้าที่สำคัญที่สุดในแง่ของ Web Vitals? นั่นคือสิ่งที่เราทำให้กับลูกค้ารายอื่น แทนที่จะสร้างเว็บไซต์ใหม่ทั้งหมด เราสร้างเฉพาะหน้าเว็บที่สำคัญที่สุดสำหรับ SEO และการแปลงเท่านั้น ในกรณีนี้คือหน้ารายละเอียดผลิตภัณฑ์และหมวดหมู่ ด้วยการสร้างสิ่งเหล่านั้นขึ้นมาใหม่ด้วย Next.js ประสิทธิภาพก็เพิ่มขึ้นอย่างมาก
ฟังก์ชันการเขียนซ้ำ Next.js นั้นยอดเยี่ยมสำหรับสิ่งนี้ เราสร้างส่วนหน้า Next.js ใหม่ที่มีหน้าแค็ตตาล็อกและปรับใช้กับ CDN หน้าอื่นที่มีอยู่ทั้งหมดจะถูกเขียนใหม่โดย Next.js ไปยังเว็บไซต์ที่มีอยู่ วิธีนี้ทำให้คุณสามารถเริ่มได้รับประโยชน์จากไซต์ Next.js ด้วยวิธีที่ไม่ยุ่งยากหรือมีความเสี่ยงต่ำ
อ่านเพิ่มเติม
- “เขียนใหม่” Next.js Docs
อะไรต่อไป?
เมื่อเราเปิดตัวโครงการเวอร์ชันแรกและเริ่มทำการทดสอบประสิทธิภาพอย่างจริงจัง เรารู้สึกตื่นเต้นกับผลลัพธ์ที่ได้ ไม่เพียงแต่เวลาตอบสนองของหน้าเพจและ Web Vitals ดีขึ้นกว่าเมื่อก่อนมาก แต่ค่าใช้จ่ายในการดำเนินการก็เป็นเพียงเศษเสี้ยวของเมื่อก่อน โดยทั่วไป Next.js และ JAMStack ช่วยให้คุณสามารถขยายขนาดด้วยวิธีที่คุ้มค่าที่สุด
การเปลี่ยนจากสถาปัตยกรรมแบบแบ็คเอนด์ไปเป็นแบบ Next.js เป็นขั้นตอนใหญ่ เส้นโค้งการเรียนรู้นั้นค่อนข้างสูงชัน และในตอนแรก สมาชิกในทีมบางคนรู้สึกว่าอยู่นอกเขตสบายของตนจริงๆ การปรับเปลี่ยนเล็กๆ น้อยๆ ที่เราทำ บทเรียนที่ได้จากบทความนี้ ช่วยได้มากในเรื่องนี้ นอกจากนี้ ประสบการณ์การพัฒนาด้วย Next.js ยังช่วยเพิ่มประสิทธิภาพการทำงานที่น่าทึ่งอีกด้วย วงจรคำติชมของนักพัฒนาซอฟต์แวร์นั้นสั้นอย่างไม่น่าเชื่อ!
อ่านเพิ่มเติม
- “กำลังดำเนินการผลิต” Next.js Docs