현재 useEffect를 통해 매번 페이지가 렌더링 될 때마다 로그인 된 user의 정보를 불러왔는데 이 방식은 아직
CSR(Client Side Rendering) 방식이다.
CSR의 대해 간단하게 말해 보자면 CSR은 SPA로, Client 사이드에서 HTML을 먼저 받아와 JS가 동작하면서
데이터만을 주고 받으며 Client에서 렌더링을 해준다.
CSR 동작과정: HTML 다운로드 > JS 다운로드 > JS 실행 > DATA 서버로부터 받아옴 > Content로 확인 가능
CSR 장점
- 전통적인 방식인 SSR 처럼 전체 페이지를 요청하지 않고 필요한 부분만 변경하기 떄문에 렌더링 속도가 빠르다.
CSR 단점
- 브라우저가 없기 떄문에 html만 가져와서 검색에 노출되지 않음 (검색 엔진 최적화(SEO)가 안되어 있음)
- 페이지를 읽고 JS를 읽은 뒤 화면을 그리는 시간까지 모두 마쳐져야 사용자에게 비추어져서 초기 구동속도가 느리다.
SSR 장점
- 사용자에게 처음으로 보여줄 Content를 앞당길 수 있다.
- 검색 엔진 최적화(SEO) 가능
SSR 단점
- 필요한 부분만 수정하는 것이 아닌 새 페이지를 로딩하고 Render 해준다.
- 전체를 로딩하다보니 CSR 보다 느리고, 사용자 경험이 좋지 않다.
그럼 검색 엔진 최적화(SEO)와 사용자에게 빠른 인터렉션을 주기 위해 SSR과 CSR의 장점을 어떻게 활용하나?
먼저 SSR을 통해 페이지 전체의 정보를 모두 받아온 뒤 그 안에서는 CSR을 통해 필요한 부분만 수정해 준다면 렌더링 속도가 빨라지고
사용자 경험이 좋아지며 검색 엔진 최적화도 가능하다.
그럼 이제 CSR은 구현이 되었으니 next.js 에서 SSR을 구현 하려한다. 그전에 redux와 redux-saga를 사용하기 떄문에 이 기준을 두고 설명하겠다.
1. SSR을 적용하기 전에 next-redux-saga는 지워도 된다. 추후 버전 충돌을 예방하기 위해 디펜던시(Dependency)는 최대한 가볍게
가져가는 것이 좋다.
2. HYDRATE가 동작할 때 initStates들이 index user post 자체를 덮어씌울 수 있도록 구조를 작성
const rootReducer = (state, action) => {
switch (action.type) {
case HYDRATE:
console.log('HYDRATE', action);
return action.payload;
default: {
const combineReducer = combineReducers({
user,
post,
});
return combineReducer(state, action);
}
}
};
export default rootReducer; // _app.js에서 reducer로 사용된다!
[ redux wrapper for next.js 사용법 참고 ]
https://github.com/kirill-konshin/next-redux-wrapper
GitHub - kirill-konshin/next-redux-wrapper: Redux wrapper for Next.js
Redux wrapper for Next.js. Contribute to kirill-konshin/next-redux-wrapper development by creating an account on GitHub.
github.com
pages/index.js
import { END } from 'redux-saga';
import axios from 'axios';
import { wrapper } from '../store/configureStore';
const Home = () => {
...
};
export const getServerSideProps = wrapper.getServerSideProps((store) => async ({ req }) => {
console.log('getServerSideProps req: ', req);
const cookie = req ? req.headers.cookie : '';
axios.defaults.headers.Cookie = '';
if (req && cookie) {
axios.defaults.headers.Cookie = cookie;
}
store.dispatch({
type: LOAD_MY_INFO_REQUEST,
});
store.dispatch(END);
await store.sagaTask.toPromise();
});
export default Home;
1. next에서 제공하는 getServerSideProps를 통해 페이지가 렌더링 되지 전 프론트 서버가 먼저 실행되고 필요한 data를 먼저 가져올 수
있다.
2. 위는 로그인 정보를 불러오는 로직인데, 새로고침 하면 로그인이 풀리는 문제가 발생한다. 이유는 cors 문제와 비슷하게 브라우저에서
가지고 있는 cookie를 공유하지 못해서이다. 그래서 아래와 같은 코드를 추가해주었다.
const cookie = req ? req.headers.cookie : ''; // 요청이 있을 경우 header의 cookie를 넣어줌
axios.defaults.headers.Cookie = ''; // 기본 header의 cookie는 초기화 해주고
if (req && cookie) { // server의 요청이 있고, cookie가 있으면
axios.defaults.headers.Cookie = cookie; // header에 cookie를 넣어준다.
}
이렇게하면 next.js를 통한 server side rendering이 구현된다.
'e도서관 > Next.js' 카테고리의 다른 글
page와 레이아웃 (0) | 2022.01.09 |
---|---|
Next.js 시작하기 (0) | 2022.01.09 |
난 왜 Next.js를 썻는가? (0) | 2022.01.08 |