본문 바로가기
Web Study/Next.js

코딩애플 - 배포와 최적화에 대해, 회원가입에 대한 기초

by 쿠리의일상 2023. 6. 28.

Next.js 의 특성

리액트는 CSR으로 처음에는 브라우저가 빈 html 파일 받고 후에 렌더링이 진행되면서 내용이 채워진다.

하지만 Next 는 모든 페이지를 미리 렌더링하는 SSR 이므로 각 페이지의 html 을 미리 생성하게 된다. 차차 css 와 js 와 연결되고 브라우저에 의해 페이지가 로드되면 자바스크립트 코드가 실행되어 유저와 상호작용이 가능해지는 것이다.

이러한 과정을 hydration 이라고 한다.

  • SSG (Static Site Generation) : 빌드 타임에 html 에 생성되어 매 요청마다 이를 재사용
    • SEO 에 유리
    • 데이터가 바뀌지 않는 페이지에 사용
  • SSR (Server Side Rendering) : 유저의 요청마다 html 을 생성

 

 

배포를 위한 빌드

Next.js 로 작성한 코드들을 html, css, js 로 변환하는 과정

npm run build

클라우드에 해당 빌드 파일을 올리고 npm run start (실제 서버 구동) 해주면 된다.

 

Next.js 의 렌더링 방식  - static rendering / dynamic rendering

https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic-rendering

 

Rendering: Static and Dynamic | Next.js

In Next.js, a route can be statically or dynamically rendered. By default, Next.js statically renders routes to improve performance. This means all the rendering work is done ahead of time and can be served from a Content Delivery Network (CDN) geographica

nextjs.org

build 를 해보면 아래와 같이 각 페이지 라우팅마다 희안한 문자가 보이는 것을 볼 수 있다.

이는 렌더링의 종류를 나눠둔 것이며,

  • 동그라미 - static rendering (기본값)
  • 람다 - dynamic rendering

 

static rendering 

기본값이며, npm run build 할 때 만들어진 html 페이지 그대로 유저에게 보내주는 페이지이다.

그 결과 캐싱되어 후에 요청이 들어와도 캐싱된 내용이 재사용된다.

페이지에 특별한 기능이 없기에 빠른 전송 속도로 보내준다.

dynamic rendering 

람다 기호로 표시하며, 유저가 페이지에 접속할 때마다 html 을 새로 만들어서 보내주는 페이지이다.

이는 fetch 처리한 페이지나 다이나믹 라우팅을 사용한 부분에 자동으로 설정된다.

+ 다이나믹 렌더링으로 자동 설정되는 동적 함수가 존재

 

문제는 dynamic rendering 처리가 되어야할 곳이 static 처리가 되었을 때

위의 이미지를 다시 확인하면 /list 페이지는 DB에서 게시글을 읽어오는 과정이 있으므로 dynamic 처리가 되어야하지만 static 처리로 되어 있다. 이는 npm run start 를 했을 때 게시글이 작성/수정/삭제 될 때 오류를 발생할 수 있기 때문에 (static은 위에서 기재했듯이 npm run build 할 때 그 html 을 그대로 보여주므로!)

static -> dynamic 로 바꾸는 방법

해당 페이지 내 키워드 dynamic 을 사용한 변수를 생성해주면 된다.

export const dynamic = 'force-dynamic';

 

dynamic rendering 은 매번 html 페이지를 새로 만들어주므로

서버나 DB 부담이 많아지는 단점이 존재한다.

이는 캐싱 기능을 사용하여 부하를 낮춰 최적화를 해준다.

캐싱 : 결과를 잠깐 저장해두고 재사용하는 방식

 

GET 요청 결과를 캐싱하기

서버 컴포넌트 안에서만 가능하다.

// GET 요청을 캐싱하기
await fetch(url); // OK, force-cache 는 기본값이므로 생략이 가능
await fetch(url, { cache : 'force-cache'}); // OK

// 만약에 캐싱을 하기 싫다면 (실시간 요청이 중요한 경우)
await fetch(url, { cache : 'no-store'});

// 캐싱된 데이터를 갱신시켜주기
await fetch(url, { next : {revalidate : 60}}); // 60초마다 캐싱된 데이터를 갱신

 

 

DB 정보를 캐싱하려면?

1. 원래 작성했던 컴포넌트의 몽고디비에 접근하는 부분을 서버 api 로 한단계 더 빼두고

컴포넌트 안에선 위처럼 fetch 로 해당 DB를 읽어오는 api 를 불러와주는 방식으로 우회해준다.

2. revalidate 예약 변수를 사용하여 페이지 단위로 캐싱하기

export const revalidate = 60;

해당 명령어를 써주면 페이지가 60초마다 static rendering 처리가 된다고 한다.

+ on-demand revalidation
revalidate 과정을 필요에 따라 진행하는 방식
특정 상황에 렌더링을 재실행하는 것이 가능해진다! (ex. 게시글을 올린 다음 렌더링을 실행하게끔)
api 안 handler에서 받아준 response에 .revalidate() 메서드로 조정이 가능하다.

https://nextjs.org/docs/pages/building-your-application/data-fetching/incremental-static-regeneration

 

Data Fetching: Incremental Static Regeneration | Next.js

Next.js allows you to create or update static pages after you’ve built your site. Incremental Static Regeneration (ISR) enables you to use static-generation on a per-page basis, without needing to rebuild the entire site. With ISR, you can retain the ben

nextjs.org

 

 

 

브라우저의 쿠키 저장소(검사 > 네트워크 > 쿠키)를 사용하여 회원 정보를 담아둔다.

해당 쿠키는 서버에 자동으로 전송되므로 서버측에서 회원 정보를 확인할 수 있는 것이다.

회원 정보를 담는 방법

1. session 방식

session id 만 담아준다.

유저의 GET, POST 요청마다 로그인 상태를 체크 가능하다는 장점이 존재

다만 DB 조회가 잦아져 부하가 발생할 수 있다. ---> redis 라는 session id 보관용 DB(입출력이 빠름)를 사용하곤 한다.

 

2. token 방식 (Json Web Token, JWT)

아이디, 로그인 날짜, 유효기간 등의 정보를 암호화하여 담아준다.

기본적으로 DB를 조회할 필요가 없어서 부하가 적고, 유저가 많거나 마이크로서비스 운영 중에 사용하기 좋다.

다만, 토큰이 다른 사람에게 복사되었을 때 직접 처리가 불가능하고 DB를 사용하여 토큰을 확인하는 작업을 추가해주면 session id 방식을 사용하는 것과 다를바가 없어지게 된다는 단점이 존재

 

OAuth

다른 사이트의 회원정보를 대여하여 사이트를 운용할 수 있는 방식 (소셜 로그인이라고 부름)

Next.js 에선 NextAuth.js / Auth.js 라이브러리가 존재하여 직접 구현할 필요가 없음