- 기존 회사사이트는 php로 개발되어 있고 SEO가 각 페이지별로 잘 적용되어 있었습니다.
NextJS의 장점인 SEO를 적극 활용.- NextJS를 들어본 사람은 누구나 알고있는 SSR
- 가장 큰 이유! 기존 회사사이트 React(CSR) 폴더 구조와 불필요한 컴포넌트가 너무 많아 사이트 초기 렌더링 속도가 너무 느렸습니다.
(크롬네트워크3G적용후 홈페이지 로드시 약15초가 걸림..)
초기 사이즈를 줄이고자 lazy import 다 적용을 해도 초기 설계가 잘못 됐는지 큰 변화가 없었다.
결국 코드 전체 리팩토링을 생각을 했고 리팩토링 하는 기회에 NextJS로 전환하자고 생각하였다.- 리덕스와, useSWR, react-query등 (전)개발자가 공부하면서 개발한 사이트라 너무 여러가지 라이브러리가 존재했고
하나로 통일이 필요했습니다.
사실 NextJS를 전환하는 작업을 저와 같이 입사한 팀원과 사이트의 심각성을 느껴 개인적으로 기존 사이트 작업를 한뒤
시간이 남을 때 마다 작업을 하였다.
저는 생각보다 전환 작업이 쉬울거라고 생각하였고 2~3일이면 전부 전환이 가능하다고 생각했다.
하지만 기존 코드가 너무 불필요하게 컴포넌트가 많이 분리되어 있고 규칙성도 존재하지않아서 여기저기 다 엮여 있었기 때문에
1주일정도 시간이 걸렸던거 같습니다.
일단 CSR의 라우트 주소를 전부 NextJS /page 폴더에 복사 붙여넣기를 했습니다.
다른 코드들은 잘모르겠지만 저희는 /page 페이지에 만든 경로 파일에는
다른 로직 하나없이 오직 SSR,SEO,로직컴포넌트Index 기능만 하도록 하였다.
/component/main폴더 MainIndex.tsx를 생성해 UI컴포넌트와 여러 로직들을 모아둡니다.
이런식으로 진행을 하면 기존의 있던 많은 코드들을 어느정도 끌고와서 사용이 가능합니다.
- 일단.. 기존 코드에 window, document등 useEffect나 여러 로직에 사용되어 있었습니다.
NextJS는 클라이언트 로드가 되기전에 해당 이벤트를 사용하면 에러가 발생하기 때문에 하나하나 다 찾아내서 변경 해주었습니다.
- 이미지, 링크이동(Link), router query, params등 모두 문법이 다르기 때문에 찾아내서 바꿔주었습니다.
- undefined 에러시 정확히 어디서 어떻게 나왔는지 알수가 없음.
- CSS 깨짐.(SSR때문에 CSS깨짐 현상)
해결방법
- const RequestTitle = dynamic(() => import('../components/RequestTitle'), { ssr: false });
- 기존 리덕스, react-query 코드를 useSWR로 전부 통일(개인적으로 이작업이 굉장히 힘들었습니다.)
- ecosystem.config.js 배포 파일실행시 스크립트 next start 사용시 배포가 안되는 문제
해결방법(커스텀 server.js를 만들어 스크림트에 script: 'server/app.js' 실행)const { parse } = require('url'); const express = require('express'); const next = require('next'); const cors = require('cors'); const env = process.env.NODE_ENV || 'development'; const port = parseInt(process.env.PORT, 10) || 6800; const app = next({ dev: env === 'development' }); const handle = app.getRequestHandler(); app.prepare().then(() => { const server = express(); server.use(cors()); server.get('*', (req, res) => { handle(req, res, parse(req.url, true)); }); server.listen(port, err => { if (err) throw err; console.info(`> Ready on port ${port}`); }); }); ``
- 저희 사이트는 웹뷰기반 어플리케이션도 존재 했기 때문에 디바이스별 체크하는 라이브러리를 사용했습니다.
SSR로 인해 해당 라이브러리가 잘 작동이 안되었고 직접 UserAgent를 이용해 체크하는 로직 생성후 모두 바꿔주었습니다.App.getInitialProps = async (appContext: AppContext) => { const userAgent = appContext?.ctx?.req ? await appContext?.ctx?.req?.headers?.['user-agent'] : navigator?.userAgent; const mobile = (await userAgent?.indexOf('Mobi')) > -1 ? true : false; const app = (await userAgent?.indexOf('IWAPP')) > -1 ? true : false; const iPhone = (await userAgent?.indexOf('iPhone')) > -1 ? true : false; const Android = (await userAgent?.indexOf('Android')) > -1 ? true : false; };
전환하면서 어려운점도 많고 생각보다 고쳐야할 부분이 너무 많아 포기를 할까 생각했지만 꾸준히 점심시간에도 작업하였다.
5일정도를 거쳐 전부 다 전환하였고 배포후에 사이트 로드 속도를 확인하니 3g 네트워크 환경에서도 약3~4초 정도로 엄청나게 줄었습니다.
SSR로 인해 SEO로 적용하기 쉽고 속도도 빨라지고 배포시 빌드 컴파일 속도가 빨라지고 전반적으로 다 빨라졌다.
스타트업 회사를 경험하다가 어느정도 환경이 가추어진 회사로 입사하고 나니 기존에 있는 코드가 너무 지저분해 보여 나름 큰 작업을 결심하였다.
세상에 깔끔한 코드는 없다고 어디선가 들었지만 리팩토링은 꼭 필요하다고 생각이 들고 폴더구조도 깔끔해지고 컴포넌트들도 많이 줄어드니
지저분한 책상을 오랜만에 치운 기분이 들었다.