Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Redis

สร้างตัวนับการดูแบบเรียลไทม์ด้วยส่วนประกอบเซิร์ฟเวอร์ React

ในบทช่วยสอนนี้ เราจะเข้าใจ React Server Components และด้วยความรู้ดังกล่าว เราจะสร้างตัวนับมุมมองแบบง่ายสำหรับแอปของคุณร่วมกัน อย่าลังเลที่จะข้ามไปที่การตั้งค่าโครงการหากคุณต้องการดำเนินการใช้งานต่อ

ทำความเข้าใจส่วนประกอบเซิร์ฟเวอร์ React

เพื่อให้เข้าใจถึงวิธีการทำงานของ React Server Components เราจะมาดูการเรนเดอร์ฝั่งไคลเอ็นต์ (CSR) และการเรนเดอร์ฝั่งเซิร์ฟเวอร์ (SSR) กันแบบคร่าวๆ

การแสดงผลฝั่งไคลเอ็นต์ (CSR)

ใน CSR งานการเรนเดอร์ส่วนใหญ่เกิดขึ้นในเบราว์เซอร์บนฝั่งไคลเอ็นต์:

  1. ผู้ใช้ร้องขอเว็บไซต์
  2. เซิร์ฟเวอร์ส่งไฟล์ HTML และลิงก์ไปยังไฟล์ CSS และ JS
  3. ลูกค้าดาวน์โหลดทรัพยากร JS
  4. ไคลเอนต์แสดงผลเพจโดยไม่มีเนื้อหา
  5. ไคลเอนต์ดึงข้อมูลจาก API ในเซิร์ฟเวอร์
  6. ลูกค้าเรนเดอร์เพจด้วยเนื้อหาอีกครั้ง

สร้างตัวนับการดูแบบเรียลไทม์ด้วยส่วนประกอบเซิร์ฟเวอร์ React

การเรนเดอร์ฝั่งเซิร์ฟเวอร์ (SSR)

ใน SSR เซิร์ฟเวอร์จะสร้างเนื้อหา HTML เต็มรูปแบบสำหรับแต่ละคำขอและส่งไปยังไคลเอนต์:

  1. ผู้ใช้ร้องขอเว็บไซต์
  2. เซิร์ฟเวอร์เรนเดอร์ไฟล์ HTML จริง แต่ยังไม่ได้โต้ตอบ
  3. ลูกค้าดาวน์โหลดทรัพยากร JS
  4. ในไคลเอนต์ ใช้ 03 ฟังก์ชัน ตัวฟังเหตุการณ์ สถานะและการโต้ตอบอื่นๆ ของส่วนประกอบ React จะแนบไปกับองค์ประกอบ DOM ที่มีอยู่ซึ่งสร้างโดยเซิร์ฟเวอร์ ซึ่งเรียกว่า ไฮเดรชั่น .
  5. ไคลเอนต์ดึงข้อมูลจาก API ในเซิร์ฟเวอร์
  6. ลูกค้าเรนเดอร์เพจด้วยเนื้อหาอีกครั้ง

สร้างตัวนับการดูแบบเรียลไทม์ด้วยส่วนประกอบเซิร์ฟเวอร์ React

ข้อดีของ SSR

  • SEO ที่ดีขึ้น :เนื่องจากโปรแกรมรวบรวมข้อมูลของเครื่องมือค้นหาสามารถอ่าน HTML ที่เรนเดอร์ได้อย่างสมบูรณ์ SSR จึงเป็นมิตรกับ SEO มากกว่า
  • การโหลดครั้งแรกเร็วขึ้น :เนื่องจากเนื้อหา HTML ที่สมบูรณ์ถูกเรนเดอร์และส่งจากเซิร์ฟเวอร์ ผู้ใช้จึงเห็นเนื้อหาของหน้าได้อย่างรวดเร็ว

ข้อเสียของ SSR

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

โต้ตอบส่วนประกอบเซิร์ฟเวอร์

RSC เป็นฟีเจอร์ใน React ที่อนุญาตให้คอมโพเนนต์สามารถเรนเดอร์ทั้งหมดบนเซิร์ฟเวอร์:

  1. เซิร์ฟเวอร์ดึงข้อมูล
  2. เซิร์ฟเวอร์เรนเดอร์แอปพร้อมเนื้อหา
  3. ลูกค้าดาวน์โหลดทรัพยากร JS
  4. ภาวะขาดน้ำเกิดขึ้นในลูกค้า

หมายเหตุ: ส่วนประกอบเซิร์ฟเวอร์ถูกเรนเดอร์ทั้งหมดบนเซิร์ฟเวอร์ โดยจะไม่รวมอยู่ในบันเดิล JS และไม่ถูกไฮเดรต ดังนั้นขั้นตอนที่ 3 และ 4 จึงเกิดขึ้นกับส่วนประกอบของไคลเอ็นต์

สร้างตัวนับการดูแบบเรียลไทม์ด้วยส่วนประกอบเซิร์ฟเวอร์ React

ข้อดีของ RSC

  • การจัดการข้อมูลอย่างมีประสิทธิภาพ: การดึงข้อมูลจะถูกย้ายไปยังเซิร์ฟเวอร์ ใกล้กับฐานข้อมูลของคุณมากขึ้น สิ่งนี้ช่วยปรับปรุงประสิทธิภาพโดยการลบการส่งข้อมูลแบบไปกลับระหว่างไคลเอ็นต์-เซิร์ฟเวอร์
  • ขนาด JavaScript ที่ลดลงบนไคลเอนต์ :เนื่องจาก React Server Components ไม่ส่ง JavaScript ใดๆ ไปยังไคลเอนต์ ขนาดบันเดิลโดยรวมจึงลดลง และปรับปรุงประสิทธิภาพ
  • การโหลดหน้าเริ่มต้นเร็วขึ้น :คอมโพเนนต์การเรนเดอร์ล่วงหน้าบนเซิร์ฟเวอร์หมายความว่าไคลเอ็นต์ได้รับ HTML ที่เรนเดอร์เต็มรูปแบบเร็วขึ้น ซึ่งช่วยปรับปรุงเวลาในการใช้ First Contentful Paint (FCP)
  • SEO ที่ได้รับการปรับปรุง :เนื้อหาได้รับการเรนเดอร์ฝั่งเซิร์ฟเวอร์อย่างสมบูรณ์ ทำให้เครื่องมือค้นหารวบรวมข้อมูลและจัดทำดัชนีเนื้อหาได้ง่ายขึ้น

ความท้าทายของ RSC

  • สถานะและวงจรการใช้งาน :React Server Components ไม่มีสิทธิ์เข้าถึง API ของเบราว์เซอร์ (เช่น 13 , 20 ) เนื่องจากมีการแสดงผลบนเซิร์ฟเวอร์
  • ไม่มีการโต้ตอบฝั่งไคลเอ็นต์ :ส่วนประกอบเซิร์ฟเวอร์ React ไม่ได้มีไว้สำหรับการอัปเดตหรือการโต้ตอบแบบไดนามิก คุณต้องใช้คอมโพเนนต์ไคลเอ็นต์สำหรับส่วนโต้ตอบของแอปของคุณ

การใช้ส่วนประกอบเซิร์ฟเวอร์ React

โต้ตอบส่วนประกอบเซิร์ฟเวอร์ใน Next.js

ตามค่าเริ่มต้น Next.js ใช้ส่วนประกอบเซิร์ฟเวอร์ พวกมันถูกเรนเดอร์ด้วย 3 วิธีที่แตกต่างกัน:

  • การแสดงผลแบบคงที่ (ค่าเริ่มต้น): เส้นทางจะแสดงในเวลา เวลาสร้าง หรือในเบื้องหลังหลังการตรวจสอบความถูกต้องของข้อมูลอีกครั้ง
  • การแสดงผลแบบไดนามิก: เส้นทางจะแสดงผลสำหรับผู้ใช้แต่ละราย ณ เวลาที่ร้องขอ .
  • สตรีมมิ่ง: UI ถูกเรนเดอร์จากเซิร์ฟเวอร์อย่างต่อเนื่อง

เมื่อใดที่คุณควรใช้ ส่วนประกอบเซิร์ฟเวอร์ React ?

คุณควรใช้ React Server Components เมื่อ :

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

คุณไม่ควรตอบสนองส่วนประกอบเซิร์ฟเวอร์เมื่อ :

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

ข้อผิดพลาดทั่วไป

องค์ประกอบของไคลเอ็นต์ไม่ได้แสดงผลทั้งหมดบนไคลเอ็นต์

แสดงผลทั้งบนไคลเอนต์และเซิร์ฟเวอร์ มีชื่อว่า Client Components เพื่อแยกความแตกต่างจาก Server Components

38 คำสั่งสำหรับการดำเนินการของเซิร์ฟเวอร์

ตามค่าเริ่มต้น Next.js จะใช้ Server Components ดังนั้นคุณไม่จำเป็นต้องระบุอะไรเลย หากคุณต้องการใช้ Client Components ให้เพิ่ม 43 คำสั่งในการประกาศขอบเขตระหว่างโมดูลเซิร์ฟเวอร์และไคลเอนต์ 57 เป็นคำสั่งที่แตกต่างไปจากเดิมอย่างสิ้นเชิงซึ่งใช้สำหรับ การทำงานของเซิร์ฟเวอร์ ซึ่งอยู่นอกเหนือขอบเขตของบล็อกโพสต์นี้

การตั้งค่าโครงการ

เราจะใช้เทมเพลตบล็อกจาก Vercel:

pnpm create next-app --example https://github.com/vercel/examples/tree/main/solutions/blog blog

คุณสามารถเรียกใช้ตัวอย่างในเครื่องและดูว่ามีลักษณะอย่างไร:

cd blog
pnpm dev

มาติดตั้ง 60 กัน :

pnpm add @upstash/redis

การตั้งค่าสภาพแวดล้อม

  1. ไปที่ Upstash Console → Redis และสร้างฐานข้อมูลใหม่:

สร้างตัวนับการดูแบบเรียลไทม์ด้วยส่วนประกอบเซิร์ฟเวอร์ React

  1. เลื่อนลงไปที่ส่วน REST API สลับไปที่ 72 แล้วคัดลอกตัวแปรสภาพแวดล้อมสำหรับขั้นตอนถัดไป:

สร้างตัวนับการดูแบบเรียลไทม์ด้วยส่วนประกอบเซิร์ฟเวอร์ React

  1. สร้าง 89 ไฟล์และวางตัวแปรสภาพแวดล้อมของคุณ:
UPSTASH_REDIS_REST_URL=<YOUR_URL>
UPSTASH_REDIS_REST_TOKEN=<YOUR_TOKEN>

ตั้งค่าองค์ประกอบมุมมอง

สร้าง 92 :

import { headers } from 'next/headers'
import { Redis } from "@upstash/redis"
 
const redis = Redis.fromEnv();
 
async function view(slug: string, ip: string) {
 // Hash the IP address to anonymize it
 const buf = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(ip));
 const hash = Array.from(new Uint8Array(buf)).map((b) => b.toString(16).padStart(2, "0")).join("");
 // Deduplicate views
 const newView = await redis.set(`deduplicate:${hash}:${slug}`, true, {
 nx: true, // Only set the key if it doesn't exist
 ex: 24 * 60 * 60, // Expire the key after 24 hours
 });
 if (newView) {
 await redis.incr(`pageviews:${slug}`); // Increment the view count
 }
}
 
export default async function Views({ slug }: { slug: string }) {
 // Get the IP address of the user
 const header = headers()
 const ip = (header.get('x-forwarded-for') ?? '127.0.0.1').split(',')[0]
 // Increment the view count
 await view(slug, ip)
 // Get the view count
 const views = await redis.get<number>(`pageviews:${slug}`) || 0
 return (
 <p className="text-sm text-neutral-600 dark:text-neutral-400">
 {views} views
 </p>
 )
}
 

นำเข้าและแสดงส่วนประกอบมุมมอง

แก้ไข 109 :

...
import Views from 'app/components/views'
...
 <div className="flex justify-between items-center mt-2 mb-8 text-sm">
 <p className="text-sm text-neutral-600 dark:text-neutral-400">
 {formatDate(post.metadata.publishedAt)}
 </p>
 <Views slug={post.slug} />
 </div>
...

ไปที่ http://localhost:3000/blog/vim เพื่อดูการทำงานของตัวนับการดู:

สร้างตัวนับการดูแบบเรียลไทม์ด้วยส่วนประกอบเซิร์ฟเวอร์ React

การเปรียบเทียบกับการตั้งค่าส่วนประกอบไคลเอนต์

ลองอ่านบล็อกโพสต์ของเรา "การเพิ่มตัวนับมุมมองในบล็อก Next.js ของคุณ" เพื่อดูการใช้งานกับส่วนประกอบของไคลเอ็นต์

นอกเหนือจากคุณประโยชน์อื่นๆ ที่กล่าวถึงในส่วนที่แล้ว โดยใช้ React Server Components:

  • ลบความจำเป็นของ API ที่แยกต่างหาก
  • ให้มุมมองแบบรวมที่เรียบง่ายของส่วนประกอบและตรรกะพร้อมประโยชน์ของการตรวจสอบประเภท

ปรับใช้

คุณสามารถปรับใช้เว็บไซต์ของคุณกับ Vercel ด้วยคำสั่งต่อไปนี้:

vercel

คำสุดท้าย

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