728x90
CSR(Client-side Rendering)이란 무엇이며, 그것의 장단점에 대하여 설명해주세요.
SPA(Single Page Application)로 구성된 웹 앱에서 SSR(Server-side Rendering)이 필요한 이유에 대하여 설명해주세요.
Next.js 프로젝트에서 yarn start(or npm run start) 스크립트를 실행했을 때 실행되는 코드를 Next.js Github 레포지토리에서 찾은 뒤, 해당 파일에 대한 간단한 설명을 첨부해주세요.

❓상황

원티드 프리온보딩 챌린지 7월 참가하여 주어진 사전과제가 있었다.

사전과제를 못했는데, 강의 이후에 다시한번 과제를 내주셨다.

 

두번째 과제인 history API를 이용한 react-router-dom의 간단한 기능을 구현했고,

첫번째 과제인 Next.js을 배우기 위해 학습하면 좋은 주제를 블로그에 정리한다.

 

🐸 설치

Next.js

yarn create next-app

 

🧮 정리

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

기존에는 클라이언트 측에서 html 요청하면 서버 측에서 브라우저에 렌더링할 파일(html, css, js 등)을 모두 렌더링 한 이후, 전달해주는 SSR방식으로 렌더링을 진행했다.

SSR 방식은 클라이언트 측에서 요청할 때 마다 서버측에서 렌더링한 이후 html 전달해주며, 사용자의 요청에 따라 새로운 html 파일을 렌더링하여 클라이언트에 전달해주기 때문에 플리커 현상이 발생하며, 서버 부하에 영향을 주었다.

 

이를 해소하기 위해 클라이언트 측에서 html 요청하면, 서버 측에서 html, css, js 파일을 전송해주고 클라이언트 측에서 js 파일을 실행시켜 렌더링하는 CSR방식이 사용되었다.

CSR 방식의 장점은 서버에 부하가 적다는 장점이 있다.

단점으로는 빈 html 파일을 전송받기 때문에 검색 최적화에 악영향을 주었다.

 

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

CSR 방식에서 서버의 부하를 더 적게 만들 수 있는 방법이 있는데 바로 SPA로 구성하는 것이다.

SPA는 서버측에서 전달받은 js 파일로 사용자의 인터렉션마다 동적으로 반응하여 부분적으로 렌더링이 가능하게 되었다.

 

위에서 서술했듯이 맨 처음 서버에서 빈 html을 전달받기 때문에 SEO에 악영향을 주었다.

그 이유는 빈 html으로 검색 결과를 보여주기 때문에 검색할 때 좋지 않다는 단점이다.

 

그렇다면 이 문제를 해소하기 위해서는 CSR에서 SSR 되돌아가야한다.

그렇게 되면 기존의 서버의 부하를 감소시켜준다는 장점이 사라지게 된다.

 

이를 해소하기 위해 Next.js는 SPA + SSR을 구성하게 되었다.

 

클라이언트 측에서 서버 측에 html 파일을 요청하면, 서버 측에서는 html을 렌더링하여 전달해주는 SSR 방식을 사용한다.

여기서 중요한 점은 html만 렌더링해서 보내주고, 사용자 요청마다 다시 부분적으로 렌더링하는 SPA로 구성되어

처음 렌더링할 때 서버에서 렌더링하고 이후에는 사용자 요청마다 부분적으로 렌더링하게 되어 서버의 부하를 줄일 수 있다. 또한, 미리 서버 측에서 각 페이지 마다 html 파일을 만들어서 전달해주기 때문에 SEO에도 문제가 없어지게 되었다. 

 

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

 

Next.js 설치하고 yarn start 또는 npm run start 스크립트를 실행하면 Next.js에서 서버를 실행하여 브라우저에서 우리가 작업한 코드들이 화면에 표현된다.

 

yarn start 또는 npm run start 스크립트를 실행하면 어떤 코드가 실행될까?

 

GitHub - vercel/next.js: The React Framework

The React Framework. Contribute to vercel/next.js development by creating an account on GitHub.

github.com

 

const nextStart: CliCommand = async (argv) => {
  // validArgs는 스크립트의 옵션의 타입을 보여준다.
  const validArgs: arg.Spec = {
    // Types
    '--help': Boolean,
    '--port': Number,
    '--hostname': String,
    '--keepAliveTimeout': Number,

    // Aliases
    '-h': '--help',
    '-p': '--port',
    '-H': '--hostname',
  }
  let args: arg.Result<arg.Spec>
  try {
  	// arg 함수를 통해 스크립트 명령줄 파싱을 한다.
    args = arg(validArgs, { argv })
  } catch (error) {
  	// 만약 error가 발생하거나 알려지지않은 옵션을 사용한 경우 에러를 출력하고 종료한다.
    if (isError(error) && error.code === 'ARG_UNKNOWN_OPTION') {
      return printAndExit(error.message, 1)
    }
    throw error
  }
  // 만약 명령줄에 --help를 입력했다면 아래 콘솔을 출력한다.
  if (args['--help']) {
    console.log(`
      Description
        Starts the application in production mode.
        The application should be compiled with \`next build\` first.

      Usage
        $ next start <dir> -p <port>

      <dir> represents the directory of the Next.js application.
      If no directory is provided, the current directory will be used.

      Options
        --port, -p          A port number on which to start the application
        --hostname, -H      Hostname on which to start the application (default: 0.0.0.0)
        --keepAliveTimeout  Max milliseconds to wait before closing inactive connections
        --help, -h          Displays this message
    `)
    process.exit(0)
  }

  // 디렉토리 경로, host와 port 번호를 가져온다. 
  const dir = getProjectDir(args._[0])
  const host = args['--hostname']
  const port = getPort(args)

  // 인수로부터 연결 유지 시간을 가져온다.
  const keepAliveTimeoutArg: number | undefined = args['--keepAliveTimeout']
  // 만약 유효하지 않는 연결 유지 시간이라면, 에러를 출력한다.
  if (
    typeof keepAliveTimeoutArg !== 'undefined' &&
    (Number.isNaN(keepAliveTimeoutArg) ||
      !Number.isFinite(keepAliveTimeoutArg) ||
      keepAliveTimeoutArg < 0)
  ) {
    printAndExit(
      `Invalid --keepAliveTimeout, expected a non negative number but received "${keepAliveTimeoutArg}"`,
      1
    )
  }

  const keepAliveTimeout = keepAliveTimeoutArg
    ? Math.ceil(keepAliveTimeoutArg)
    : undefined

  // config를 구성한다.
  const config = await loadConfig(
    PHASE_PRODUCTION_SERVER,
    resolve(dir || '.'),
    undefined,
    undefined,
    true
  )

  // 명령 인수와 config로 서버를 실행한다
  await startServer({
    dir,
    isDev: false,
    hostname: host,
    port,
    keepAliveTimeout,
    useWorkers: !!config.experimental.appDir,
  })
}

export { nextStart }
복사했습니다!