Computer >> 컴퓨터 >  >> 프로그래밍 >> Redis

React 서버 구성 요소를 사용하여 실시간 조회 카운터 구축

이 튜토리얼에서는 React Server 구성 요소를 이해하고 해당 지식을 바탕으로 앱에 대한 간단한 뷰 카운터를 함께 구축합니다. 구현을 진행하려면 프로젝트 설정으로 이동하세요.

React 서버 구성 요소 이해

React Server 구성 요소의 작동 방식을 이해하기 위해 클라이언트 측 렌더링(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. 클라이언트에서 hydrateRoot() 사용 React 구성 요소의 함수, 이벤트 리스너, 상태 및 기타 상호 작용은 서버에서 생성된 기존 DOM 요소에 연결되며, 이를 하이드레이션이라고 합니다. .
  5. 클라이언트는 서버의 API에서 데이터를 가져옵니다.
  6. 클라이언트가 콘텐츠가 포함된 페이지를 다시 렌더링합니다.

React 서버 구성 요소를 사용하여 실시간 조회 카운터 구축

SSR의 장점

  • 더 나은 SEO :검색 엔진 크롤러는 완전히 렌더링된 HTML을 읽을 수 있으므로 SSR은 SEO 친화적입니다.
  • 초기 로드 속도 향상 :완전한 HTML 콘텐츠가 서버에서 렌더링되어 전송되므로 사용자는 페이지의 콘텐츠를 빠르게 볼 수 있습니다.

SSR의 단점

  • 느린 탐색 :각 새 페이지 요청에는 서버에서 HTML을 완전히 다시 로드하기 위한 왕복 통신이 필요합니다.
  • 서버 부하 증가 :서버가 페이지 렌더링 작업의 대부분을 수행하므로 여러 요청을 처리하려면 더 많은 리소스가 필요할 수 있습니다.

React 서버 구성 요소

RSC는 구성 요소가 서버에서 완전히 렌더링될 수 있도록 하는 React의 기능입니다.

  1. 서버가 데이터를 가져옵니다.
  2. 서버가 콘텐츠와 함께 앱을 렌더링합니다.
  3. 클라이언트가 JS 리소스를 다운로드합니다.
  4. 수화는 클라이언트에서 발생합니다.

참고: 서버 구성 요소는 서버에서 완전히 렌더링되며 JS 번들에 포함되지 않으며 수화되지 않습니다. 따라서 클라이언트 구성요소에 대해 3단계와 4단계가 수행됩니다.

React 서버 구성 요소를 사용하여 실시간 조회 카운터 구축

RSC의 장점

  • 효율적인 데이터 처리: 데이터 가져오기는 데이터베이스에 더 가까운 서버로 이동됩니다. 이는 클라이언트-서버 왕복을 제거하여 성능을 향상시킵니다.
  • 클라이언트의 JavaScript 크기 감소 :React Server 구성 요소는 클라이언트에 JavaScript를 전송하지 않으므로 전체 번들 크기가 줄어들어 성능이 향상됩니다.
  • 더 빠른 초기 페이지 로드 :서버에서 구성요소를 사전 렌더링하면 클라이언트가 완전히 렌더링된 HTML을 더 빠르게 수신하여 FCP(First Contentful Paint) 시간이 단축됩니다.
  • 향상된 SEO :콘텐츠가 서버측에서 완전히 렌더링되므로 검색 엔진이 콘텐츠를 더 쉽게 크롤링하고 색인을 생성할 수 있습니다.

RSC의 과제

  • 상태 및 수명 주기 :React Server 구성 요소는 브라우저 API(예:useState)에 액세스할 수 없습니다. , useEffect ), 서버에서 렌더링되기 때문입니다.
  • 클라이언트측 상호작용 없음 :React Server 구성 요소는 동적 업데이트나 상호 작용을 위한 것이 아닙니다. 앱의 대화형 부분에는 클라이언트 구성요소를 사용해야 합니다.

React 서버 구성요소 사용

Next.js의 React 서버 구성요소

기본적으로 Next.js는 서버 구성 요소를 사용합니다. 3가지 다른 방식으로 렌더링됩니다:

  • 정적 렌더링(기본값): 경로는 빌드 시간에 렌더링됩니다. , 또는 데이터 재검증 후 백그라운드에서.
  • 동적 렌더링: 경로는 요청 시간에 각 사용자에 대해 렌더링됩니다. .
  • 스트리밍: UI는 서버에서 점진적으로 렌더링됩니다.

언제 React 서버 구성요소를 사용해야 할까요? ?

다음과 같은 경우 React 서버 구성요소를 사용해야 합니다 :

  • 자주 변경되지 않는 정적, 비대화형 콘텐츠가 있습니다.
  • 클라이언트에 전송되는 JavaScript를 줄여 성능을 향상시키고 싶습니다.
  • SEO는 애플리케이션에 중요합니다.
  • 과중한 데이터 가져오기 또는 계산 작업을 서버로 오프로드하려고 합니다.

다음과 같은 경우에는 React 서버 구성요소를 사용하면 안 됩니다 :

  • 구성요소에는 클라이언트측 상호작용, 상태 또는 후크가 필요합니다.
  • 브라우저 API에 대한 액세스가 필요하거나 실시간 업데이트가 필요합니다.
  • 클라이언트측 로직이나 사용자별 콘텐츠가 많이 포함된 복잡한 페이지를 구축하고 있습니다.

일반적인 함정

클라이언트 구성요소는 클라이언트에서 완전히 렌더링되지 않습니다.

클라이언트와 서버 모두에서 렌더링됩니다. 서버 구성 요소와 구별하기 위해 클라이언트 구성 요소라고 합니다.

‘use server’ 지시문은 서버 작업을 위한 것입니다

기본적으로 Next.js는 서버 구성 요소를 사용하므로 아무것도 지정할 필요가 없습니다. 클라이언트 구성 요소를 사용하려면 ‘use client’을 추가하세요. 서버와 클라이언트 모듈 간의 경계를 선언하는 지시문입니다. ‘use server’ 서버 작업에 사용되는 완전히 다른 지시어입니다. , 이는 이 블로그 게시물의 범위를 벗어납니다.

프로젝트 설정

Vercel의 블로그 템플릿을 사용하겠습니다:

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

예제를 로컬에서 실행하여 어떻게 보이는지 확인할 수 있습니다:

cd blog
pnpm dev

@upstash/redis을 설치해 봅시다 :

pnpm add @upstash/redis

환경 설정

  1. Upstash 콘솔 → Redis로 이동하여 새 데이터베이스를 생성하세요:

React 서버 구성 요소를 사용하여 실시간 조회 카운터 구축

  1. REST API 섹션까지 아래로 스크롤하고 .env으로 전환합니다. 탭을 클릭하고 다음 단계를 위해 환경 변수를 복사하세요.

React 서버 구성 요소를 사용하여 실시간 조회 카운터 구축

  1. .env 만들기 파일을 작성하고 환경 변수를 붙여넣으세요.
UPSTASH_REDIS_REST_URL=<YOUR_URL>
UPSTASH_REDIS_REST_TOKEN=<YOUR_TOKEN>

설정 보기 구성 요소

/app/components/views.tsx 생성 :

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>
 )
}
 

보기 구성 요소 가져오기 및 표시

/app/blog/[slug]/page.tsx 수정 :

...
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 구성 요소를 사용하면 다음과 같은 이점이 있습니다.

  • 별도의 API가 필요하지 않게 되었습니다.
  • 유형 검사의 이점과 함께 구성 요소 및 해당 논리에 대한 간단하고 통합된 보기를 제공합니다.

배포

다음 명령을 사용하여 사이트를 Vercel에 배포할 수 있습니다:

vercel

마지막 한마디

서버 구성 요소와 클라이언트 구성 요소의 장점을 결합하면 응용 프로그램의 성능과 상호 작용 사이에서 적절한 균형을 유지할 수 있습니다. 이 가이드가 언제 React Server 구성 요소를 효과적으로 활용해야 하는지에 대한 정보를 바탕으로 결정을 내리는 데 도움이 되기를 바랍니다.