원티드 프리온보딩 챌린지 - CSR / SSR with Next.js

date
Jul 2, 2023
slug
wanted-frontend-challenge-7
author
status
Public
tags
Next.js
summary
CSR/SSR, 그리고 NextJS 분석
type
Post
thumbnail
스크린샷 2023-07-02 오후 8.45.15.png
updatedAt
Jul 2, 2023 01:49 PM
category
 

📝 문제

📌
Assignment) 개인 블로그에 아래 질문에 대한 포스팅을 하고 링크를 제출해주세요.
  • CSR(Client-side Rendering)이란 무엇이며, 그것의 장단점에 대하여 설명해주세요.
  • SPA(Single Page Application)로 구성된 웹 앱에서 SSR(Server-side Rendering)이 필요한 이유에 대하여 설명해주세요.
  • Next.js 프로젝트에서 yarn start(or npm run start) 스크립트를 실행했을 때 실행되는 코드를 Next.js Github 레포지토리에서 찾은 뒤, 해당 파일에 대한 간단한 설명을 첨부해주세요.
    • https://nextjs.org/docs/getting-started (Next.js 세팅 가이드)
    • https://github.com/vercel/next.js/ (Next.js Github 레포지토리)
    • _document.js_app.jsgetServerSideProps 같은 요소들에 대해 설명을 요구하는 과제가 아닙니다. 오히려 Next.js 코드 베이스 내부를 살펴보라는 의미입니다.
    • 사전과제 여부나 제출된 과제 퀄리티가 수강 가능 여부 및 이후의 과정에 영향을 미치지는 않을 것이나, 3번 과제를 해보는 것이 큰 학습이 될 것이라고 확신합니다. 반드시 한번 살펴보시길 권장드립니다.
    • 제출 전 과제가 유효한 Public 한 링크인지 다시 한번 확인 부탁드립니다.

과제 제출

  • 수행하신 과제는 챌린지 시작 후 전달될 안내에 따라 링크로 제출해주시고, 학습 수준 파악 및 강의 진행을 위해 사용될 예정입니다.
 

📝 과제

📌 1번, CSR(Client-side Rendering)이란 무엇이며, 그것의 장단점에 대하여 설명해주세요.

 

CSR

  • CSR은 클라이언트가 웹 렌더링에 필요한 주요 로직들(JS 등)을 초기 접속시 한번에 모두 내려받음
  • 사용자의 행동에 따라 이미 다운 받아진 JS 번들을 통해 서버로부터 데이터를 가져오거나, 화면을 렌더링

장점

  • 쉬운 페이지 전환
    • 서버에 추가적인 요청없이 작동
  • 네이티브 애플리케이션과 유사하게 작동
    • 브라우저 화면을 새로 고칠 필요없이 다른 페이지로 이동 가능

단점

  • 보안 문제
    • API 요청/응답을 통해 백엔드 구조 및 민감한 정보가 노출 될 수 있음
  • 초기 로딩 시간
    • 초기 페이지 로딩시에 주요 번들을 전부 내려받기 때문에, 초기 로딩시에 시간이 소요됨
  • SEO최적화 문제
    • 일부 검색 엔진(네이버 등)과 같은 곳에서는 CSR로 구성된 웹 사이트를 분석하지 못함
  • 호환성 문제
    • 구형 브라우저 등에서 번들에 포함된 일부 JS 스펙이 작동되지 않을 수 있음
 

📌 2번, SPA(Single Page Application)로 구성된 웹 앱에서 SSR(Server-side Rendering)이 필요한 이유에 대하여 설명해주세요.

 
  • 보안
    • 중요한 데이터 요청을 서버단에서 처리하여 중요 정보를 감출 수 있음
  • 브라우저 호환성
    • 대부분의 렌더링을 브라우저에서 처리하고 마크업 파일만 내려주기 때문에, 대부분의 브라우저에서 호환성이 높음
  • SEO 성능
    • 검색엔진의 크롤러가 작동할 때, 어떤 웹 사이트인지 메타데이터를 포함해서 전달할 수 있음
  • 초기 로딩 속도
    • 프리렌더링, 캐싱 등의 전략을 통해 처음 웹 사이트에 접속하는 유저의 로딩 시간을 단축시킬 수 있음
  • 서버 리소스 활용
    • 클라이언트 기기 성능에 영향을 받지 않고, 사이트를 렌더링하여 클라이언트에 내려줄 수 있음
 
 

📌 3번, Next.js 프로젝트에서 yarn start(or npm run start) 스크립트를 실행했을 때 실행되는 코드를 Next.js Github 레포지토리에서 찾은 뒤, 해당 파일에 대한 간단한 설명을 첨부해주세요.

 

nextJS 프로젝트

yarn start는 어떤 명령어인지 찾아보기
"scripts": { // ... "start": "next start" },
  • yarn start 실행시 → next start
 

next start 는 어떻게 실행되는가

Vercel/next 레포에서 찾아보기
"workspaces": [ "packages/*" ],
  • 모노레포로 구성되어 있으며, 찾고자하는 next 명령어 에 대한 정보는 packages/에 있을 것으로 보임.
  • packages/ 에 속한 다양한 레포
    • create-next-app
    • next
    • next-swc
    • … 등
  • packages/nextpackage.json
// bin: 패키지내 실행 가능한 명령어 경로 "bin": { "next": "./dist/bin/next" },
  • packages/next/src/bin/next에서 찾을 수 있음
 

packages/next/src/bin/next

next는 어떻게 실행되는 명령어인지 찾아보기
  • 주요코드
// 의존성 체크 ;['react', 'react-dom'].forEach((dependency) => { try { // When 'npm link' is used it checks the clone location. Not the project. require.resolve(dependency) } catch (err) { console.warn( `The module '${dependency}' was not found. Next.js requires that you include it in 'dependencies' of your 'package.json'. To add it, run 'npm install ${dependency}'` ) } })
  • 명령어 옵션
// 버전 // --version 옵션이 있을 경우, 버전을 출력하고 프로세스를 종료함 if (args['--version']) { console.log(`Next.js v${process.env.__NEXT_VERSION}`) process.exit(0) }
// help if (!foundCommand && args['--help']) { console.log(` Usage $ next <command> Available commands ${Object.keys(commands).join(', ')} Options --version, -v Version number --help, -h Displays this message For more information run a command with the --help flag $ next build --help `) process.exit(0) }
// 그 외 명령어들 commands[command]() .then((exec) => exec(forwardedArgs)) .then(() => { if (command === 'build') { // ensure process exits after build completes so open handles/connections // don't cause process to hang process.exit(0) } })
  • 명령어
// next/src/lib/commands.ts export type CliCommand = (argv?: string[]) => void export const commands: { [command: string]: () => Promise<CliCommand> } = { build: () => Promise.resolve(require('../cli/next-build').nextBuild), start: () => Promise.resolve(require('../cli/next-start').nextStart), export: () => Promise.resolve(require('../cli/next-export').nextExport), dev: () => Promise.resolve(require('../cli/next-dev').nextDev), lint: () => Promise.resolve(require('../cli/next-lint').nextLint), telemetry: () => Promise.resolve(require('../cli/next-telemetry').nextTelemetry), info: () => Promise.resolve(require('../cli/next-info').nextInfo), 'experimental-compile': () => Promise.resolve(require('../cli/next-build').nextBuild), 'experimental-generate': () => Promise.resolve(require('../cli/next-build').nextBuild), }
 

yarn start

그래서 yarn start를 입력하면,
  • next/src/lib/commands.ts 에 따라 next/src/cli/next-start’가 실행됨
  • next/src/cli/next-start
    • next-start에 의해 실행되는 코드
    • 주요코드
// .. // 서버 환경 정보 가져오기 const dir = getProjectDir(args._[0]) const host = args['--hostname'] const port = getPort(args) //... // 서버 실행 await startServer({ dir, isDev: false, hostname: host, port, keepAliveTimeout, useWorkers: !!config.experimental.appDir, })
 
chat
Chat으로 물어보세요!
chat-bubble
채팅으로 물어보세요
안녕하세요!
프론트엔드 개발자, 봉승우입니다.
저에 대해 궁금하신 것이 있나요?
너는 어떤 사람이야?
너가 진행한 프로젝트를 간략히 소개해줘
너의 학업은 어때?
가장 어려웠던 프로젝트는 뭐였어?
어떤 특허를 가지고 있어?