Nextjs

글 목록 가져오기

nextjs에서 서버쪽의 데이터를 가져와서(fetch) 이를 UI에 반영하는 방법을 살펴보겠습니다. 

소스코드

https://github.com/egoing/nextapp/commit/81574894fc05a40e6a0308c54d5cb1ce17d27037

server component

nextjs의 컴포넌트는 크게 server component와 client component로 구분됩니다. 특별한 처리를 하지 않으면 nextjs에서 컴포넌트는 server component 입니다.

위의 그림을 보면 S가 server, C가 client component의 사용 사례를 보여줍니다. 

서버 컴포넌트는 아래와 같은 경우에 사용합니다. 

  • 사용자와 상호작용하지 않는 경우
  • 백엔드에 엑세스하면서 보안적으로 위험한 정보를 주고 받는 경우

클라이언트 컴포넌트는 아래와 같은 경우 사용합니다. 

  • 서버 컴포넌트로 해결되지 않는 경우
  • 사용자와 상호작용하는 경우
  • useEffect, useState, onClick, onChange와 같은 API를 사용해야 하는 경우 
  • useRouter, useParams와 같은 nextjs의 client component API를 사용하는 경우
  •  

아래는 nextjs의 구분법

1. app/layout.js를 아래와 같이 편집합니다.

server component에서는 fetch를 사용할 때 useEffect를 사용하지 않습니다. 또 fetch를 이용할 때 await를 사용합니다. 

export default async function RootLayout({ children }) {
  const resp = await fetch('http://localhost:9999/topics/') 
  const topics = await resp.json();

2. 글목록을 생성합니다. 

          {topics.map(topic=>{
            return <li key={topic.id}><Link href={`/read/${topic.id}`}>{topic.title}</Link></li>
          })}

app/layout.js의 전체코드는 아래와 같습니다. 

import Link from 'next/link'
import './globals.css'
export const metadata = {
  title: 'WEB tutorial',
  description: 'Generated by egoing',
}
export default async function RootLayout({ children }) {
  const resp = await fetch('http://localhost:9999/topics/') 
  const topics = await resp.json();
  return (
    <html>
      <body>
        <h1><Link href="/">WEB</Link></h1>
        <ol>
          {topics.map(topic=>{
            return <li key={topic.id}><Link href={`/read/${topic.id}`}>{topic.title}</Link></li>
          })}
        </ol>
        {children}
        <ul>
          <li><Link href="/create">create</Link></li>
          <li><Link href="/update/id">update</Link></li>
          <li><button>delete</button></li>
        </ul>
      </body>
    </html>
  )
}

실험

console.log를 이용해서 출력해보세요.

export default async function RootLayout({ children }) {
  const resp = await fetch('http://localhost:9999/topics/') 
  const topics = await resp.json();
  console.log('page/layout.js/topics', topics)

출력 결과가 개발자 도구의 콘솔에서는 나타나지 않고, 터미널에서만 출력 됩니다. 

서버 컴포넌트는 모든 작업을 서버 쪽에서 처리하고, 그 결과인 html 코드만 클라이언트로 전송합니다. 이것을 서버쪽에서 랜더링을 한다고해서 server side rendering이라고 합니다. 

좋은 점

  • 간결한 코드: useEffect와 useState와 같은 훅을 사용하지 않아도 되므로, 코드가 더 간결하고 이해하기 쉬워집니다. 이로 인해 코드 유지 관리가 쉬워지고, 버그 발생 확률이 줄어들 수 있습니다.
  • 빠른 데이터 엑세스: 데이터베이스와 같은 자원에 접근해야 하는 경우, 서버 컴포넌트는 서버와 데이터베이스가 가까운 위치에서 작동하므로, 더 빠른 속도로 필요한 데이터에 접근할 수 있습니다.
  • 보안: 서버 컴포넌트는 클라이언트에 민감한 정보(예: 데이터베이스 비밀번호)를 전송하지 않습니다. 이로 인해, 필요한 작업을 안전하게 처리하면서 동시에 클라이언트의 보안을 유지할 수 있습니다.
  • 향상된 성능: 서버 컴포넌트는 클라이언트로 JavaScript 코드를 전송하지 않습니다. 이는 전송되는 데이터의 양을 줄이고, 클라이언트의 부하를 줄임으로써 웹사이트의 전반적인 성능을 향상시키는데 도움이 됩니다.

 

댓글

댓글 본문
  1. 한 번 보고는 이해 못 해서 몇 번 더 봄
  2. 인절미후후
    > 언젠가는 무조건 한번 Javascript 파일에 대한 실행은 공통적인데 왜 초반 로딩 속도에 있어서 차이가 나는지 궁금합니다.

    원하시는 답변자가 아니지만 제 이해로 말씀드리자면 html 로 구성된 랜더링이 내려오는것과
    클라측에서 받은 html 을 구성후 java script 를 실행하는데 속도차이가 분명히 존재하는거라 생각됩니다.
    다만 여기서 리소스를 어디서 가져올지 캐시를 어떻게 할지는 CSR, SSR 대비 차이가 존재합니다.
    다만 이걸 다 파악하면서 대응하지도 않기도 하죠 - 꽤나 어려운 영역이기도 하다고 생각합니다.

    대체로라는 말로 빠르다 느리다를 얘기할수 있는건 아니고 경우에 따라 다를것 같아요
    ai 한테 물어서 받은 답변도 대체로 비슷하네요

    >>>
    CSR (Client-Side Rendering):

    CSR은 클라이언트 측에서 웹 페이지를 동적으로 렌더링합니다. 초기 페이지 로드 시에는 서버에서 HTML, CSS 및 JavaScript 파일을 받아옵니다.
    이후 JavaScript가 실행되면, 클라이언트는 데이터를 가져와서 웹 페이지의 내용을 동적으로 업데이트합니다.
    CSR은 초기 로드 시에는 렌더링이 빠르고, 웹 애플리케이션의 전체 구조가 클라이언트에 로드되기 때문에 사용자 경험이 향상될 수 있습니다. 그러나 데이터와 JavaScript 파일을 다운로드하는 과정이 추가되어 초기 로드 속도가 느릴 수 있습니다.

    SSR (Server-Side Rendering):

    SSR은 서버에서 웹 페이지를 렌더링하여 클라이언트에 전달합니다. 즉, 클라이언트가 서버로부터 완전히 렌더링된 HTML을 받아오게 됩니다.
    초기 로드 시에는 CSR에 비해 렌더링 속도가 느릴 수 있습니다. 그러나 사용자가 페이지를 요청할 때마다 서버에서 새로운 HTML을 생성하므로, 초기 로드 이후의 페이지 내비게이션은 빠를 수 있습니다.
    SSR은 일반적으로 SEO (Search Engine Optimization)에 유리하며, 초기 로드 시에는 렌더링이 완료된 페이지를 보여줌으로써 초기 로드 시간을 단축할 수 있습니다.
    속도 차이는 대부분 초기 로드와 관련이 있습니다. CSR은 초기 로드 시에는 빠르지만, 추가적인 데이터 및 자원 로딩이 필요하므로 초기 로드 이후의 사용자 경험이 SSR에 비해 느릴 수 있습니다. SSR은 초기 로드 시에는 느릴 수 있지만, 사용자가 페이지를 이동할 때마다 서버에서 새로운 페이지를 렌더링하기 때문에 사용자 경험이 일관되고 빠를 수 있습니다.
    대화보기
    • 김승완
      SSR과 CSR의 속도 차이에 대한 고민을 하다가 풀리지 않는 것이 있어 이고잉님께 질문 드립니다.
      두 방식 모두 결국에는 사용자에게 첫 UI를 보여주기 위해서는 html 을 채워넣기 위한 Javascript 코드를 실행해야 한다고 이해했습니다, 이것이 SSR의 방식에서는 서버 측에서 이루어져 완성된 html이 클라이언트에게 보내지고 CSR의 방식에서는 클라이언트 브라우저에서 이루어지는 것입니다.
      언젠가는 무조건 한번 Javascript 파일에 대한 실행은 공통적인데 왜 초반 로딩 속도에 있어서 차이가 나는지 궁금합니다. 강의에서 말씀해주신 api 서버와 백엔드 서버와의 물리적 거리 이외에도, 대체로 서버 컴퓨터의 Javascript 연산 속도가 클라이언트 브라우저의 연산 속도보다 빠르거나 하는 그러한 이유가 따로 있을까요???
    • Hoon Ko
      20231018
    • 어흥
      230813