본문 바로가기
etc/개발 세미나

[원티드] 프리온보딩 프론트엔드 챌린지 7월 - 사전과제

by 1two13 2023. 7. 7.
728x90
반응형

원티드 7월 챌린지에 참여하게 된 이유는 Next.js에 대해 공부해보고 싶어서였다. 

2주동안 주2회 3시간씩 진행이 되는 실시간 강의이다보니깐 깊게 배우지는 못해도 얻어가는 게 분명히 있을거라고 생각했다. 

 

 

사전과제는 총 3개였다. 

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

 

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

이 질문에 대해서는 면접 스터디를 준비하면서 정리해 둔게 있었다.

 

CSR은 최초 로드 시 필요한 파일들을 전부 받고, 사용자 인터렉션에 따라 클라이언트 단에서 필요한 데이터를 서버로부터 비동기적으로 받아와 렌더링해주는 방식이다.

 

초반에 뼈대만 다운받기 때문에, 즉 초기 로딩 시 HTML 파일이 비어있기 때문에, 검색 엔진 크롤러(SEO)에게 적절한 컨텐츠를 제공하는 것이 어렵다는 단점과 초기 화면의 렌더링 속도가 느리다는 단점이 있다. 

 

하지만 필요한 데이터만 가져와서 업데이트할 수 있기 때문에 사용자 경험이 향상될 수 있고, 초기 렌더링 이후에는 클라이언트 측에서 대부분의 작업을 처리하기 때문에 서버 부하가 감소한다는 장점이 있다. 

 

 

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

먼저 SSR은 서버가 완전하게 만들어진 HTML 파일을 받아서 렌더링하는 방식으로 CSR의 단점을 극복할 수 있다. 

하지만 서버에서 페이지를 렌더링하기 때문에 서버의 부하가 증가한다는 단점이 있다. 그리고 SSR은 초기 렌더링만 처리하기 때문에, 클라이언트 측에서 추가적인 상호작용을 위한 JS 코드를 작성해야 할 수 있다. 

 

SPA로 구성된 웹 앱들은 기본적으로 CSR이기 때문에 CSR의 단점을 극복하기 위해 SSR이 필요하다. 

SSR을 사용하면 검색 엔진 최적화 초기 로딩 속도 개선에 이점이 있다.

 

1. 검색 엔진 최적화

이는 결국 사용자 경험을 개선하는데 도움을 준다. 

 

2. 초기 로딩 속도 개선

SPA는 기본적으로 CSR이기 때문에 자바스크립트를 로드하면서 사용자가 이탈되지 않도록 해야한다. 

 

 

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

1. Next.js를 먼저 설치했다.

npx create-next-app my-app

2. npm run start 명령어로 실행되는 코드를 Next.js 깃헙 레포에서 찾아봤다. 

next-start.ts 파일이고, packages > next > src > cli > next-start.ts 경로를 통해 확인할 수 있다. 

#!/usr/bin/env node

import arg from 'next/dist/compiled/arg/index.js'
import { startServer } from '../server/lib/start-server'
import { getPort, printAndExit } from '../server/lib/utils'
import isError from '../lib/is-error'
import { getProjectDir } from '../lib/get-project-dir'
import { CliCommand } from '../lib/commands'
import { resolve } from 'path'
import { PHASE_PRODUCTION_SERVER } from '../shared/lib/constants'
import loadConfig from '../server/config'

const nextStart: CliCommand = async (argv) => {
  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 {
    args = arg(validArgs, { argv })
  } catch (error) {
    if (isError(error) && error.code === 'ARG_UNKNOWN_OPTION') {
      return printAndExit(error.message, 1)
    }
    throw error
  }
  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)
  }

  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

  const config = await loadConfig(
    PHASE_PRODUCTION_SERVER,
    resolve(dir || '.'),
    undefined,
    undefined,
    true
  )

  await startServer({
    dir,
    isDev: false,
    hostname: host,
    port,
    keepAliveTimeout,
    useWorkers: !!config.experimental.appDir,
  })
}

export { nextStart }

코드를 보면 --help와 같은 옵션에 대한 실행 내용이 있고, 옵션을 줄여 쓰기 위해 alias 설정까지 하나하나 해주는 것을 확인할 수 있다.

그리고 import를 보면 { startServer } 객체를 가져와 적용하는 것을 확인할 수 있다.

즉, startServer 함수를 실행하기 위해 여러 값들을 설정하고, 해당 함수로 넘겨주고 있는 것이다. 

3. startServer 객체를 import 해오는 파일로 가보면(packages > next > src > server > lib > start-server.ts) createServer 메서드를 사용하여 서버를 활성화해준다는 것을 알 수 있다.

 

npm start 명령어를 실행했을 때 실행되는 파일들을 살펴볼 수 있는 계기가 되었다. 

그리고 Next.js는 단순히 소스코드만 작성되어 있는 것이 아닌, 서버까지 구동시키는 풀스택 앱이라는 것을 알게 되었다. 

Next.js를 직접 사용해보면 이 매력을 더 알 수 있게 되지 않을까라고 생각한다. 

 


질문이나 잘못된 점은 댓글로 남겨주세요 :)💖

728x90
반응형

댓글