Vue.js 미드레벨 기술면접

Vue.js 미드레벨 (3~7년) 종합 5문항 조회수 106 · 2026-05-29 (금) 19:11:02
1 성능 최적화
Medium

Q. Vue 3 애플리케이션에서 사용자 입력에 따라 실시간으로 필터링되는 대용량 리스트(10,000개 이상 항목)를 렌더링할 때 발생하는 성능 문제를 해결하기 위한 방법을 설명해주세요. computed 속성 사용, debounce/throttle 적용, 그리고 메모이제이션 전략을 포함하여 답변해주세요.

A. 모범답안

먼저 필터링 로직을 computed 속성으로 구현하여 Vue의 캐싱 메커니즘을 활용합니다. 사용자 입력에는 debounce를 적용해 불필요한 재계산을 방지하고(예: 300ms 지연), 필터링된 결과가 여전히 많다면 가상 스크롤링을 적용합니다. 추가로 복잡한 필터 조건의 경우 useMemo나 shallowRef를 활용해 중간 계산 결과를 캐싱하고, 리스트 항목에 key를 올바르게 설정하여 Vue의 diff 알고리즘이 효율적으로 동작하도록 합니다. 필요시 Web Worker로 필터링 로직을 오프로드하여 메인 스레드 블로킹을 방지할 수 있습니다.

핵심 포인트
  • • computed 속성으로 필터링 로직 캐싱
  • • debounce/throttle로 입력 이벤트 최적화
  • • 가상 스크롤링 적용으로 실제 DOM 노드 수 제한
  • • 적절한 key 바인딩으로 diff 알고리즘 최적화
  • • Web Worker 활용한 백그라운드 처리
Follow-up 질문

가상 스크롤링 라이브러리를 직접 구현한다면 어떤 요소들을 고려해야 하며, 동적 높이를 가진 아이템을 처리하는 방법은 무엇인가요?

2 설계 패턴
Hard

Q. 여러 페이지에서 사용되는 복잡한 필터 UI(날짜 범위, 다중 선택, 검색어 등)의 상태를 URL 쿼리 파라미터와 동기화하면서 브라우저 뒤로가기/앞으로가기를 지원해야 합니다. Vue Router와 Composable을 활용한 설계 방법과 상태 직렬화/역직렬화 전략, 그리고 초기 로드 시 URL에서 상태를 복원하는 로직을 어떻게 구현하시겠습니까?

A. 모범답안

먼저 useRouteQuery 같은 Composable을 만들어 route.query와 양방향 바인딩되는 ref를 반환하도록 구현합니다. watchEffect를 사용해 필터 상태 변경 시 router.replace로 URL을 업데이트하되, 히스토리 스택을 쌓지 않도록 합니다. 복잡한 객체는 JSON.stringify로 직렬화하거나 qs 라이브러리로 중첩 구조를 처리하고, onMounted에서 route.query를 파싱해 초기 상태를 복원합니다. 상태 변경과 URL 업데이트 간 무한 루프를 방지하기 위해 내부 플래그나 watch의 flush: 'post' 옵션을 활용하며, 유효하지 않은 쿼리 파라미터는 기본값으로 fallback하는 validation 로직을 포함합니다.

핵심 포인트
  • • Composable 패턴으로 URL-상태 동기화 로직 캡슐화
  • • router.replace 사용으로 불필요한 히스토리 생성 방지
  • • 직렬화/역직렬화 전략과 유효성 검증
  • • watch/watchEffect의 무한 루프 방지
  • • 브라우저 네비게이션 이벤트 처리
Follow-up 질문

같은 페이지에서 여러 개의 독립적인 필터 섹션이 있고, 각각 다른 URL 파라미터 네임스페이스를 사용해야 한다면 어떻게 설계하시겠습니까?

3 트러블슈팅
Medium

Q. Vue 3 프로젝트에서 API 응답 데이터를 reactive로 감싸서 사용하고 있는데, 특정 중첩된 객체의 속성을 업데이트해도 UI가 반응하지 않는 문제가 발생했습니다. 이런 문제가 발생할 수 있는 원인들과 디버깅 방법, 그리고 해결 방안을 설명해주세요.

A. 모범답안

주요 원인은 API 응답에 non-reactive 객체(Date, Map, Set 등)가 포함되어 있거나, 깊은 중첩 구조에서 일부 객체가 markRaw로 마킹되었거나, Object.freeze가 적용된 경우입니다. Vue DevTools의 Reactivity 탭에서 해당 객체의 반응성 상태를 확인하고, console.log(toRaw(data))로 원본 객체를 검사합니다. 해결 방법으로는 문제가 되는 속성만 ref로 분리하거나, 업데이트 시 Object.assign이나 스프레드 연산자로 새 객체를 생성하거나, 깊은 복사 후 재할당하는 방법이 있습니다. 또한 배열의 경우 인덱스 직접 할당 대신 splice나 Vue.set 패턴을 사용해야 할 수 있습니다.

핵심 포인트
  • • non-reactive 객체 타입 확인 (Date, Map, Set 등)
  • • Vue DevTools로 반응성 상태 디버깅
  • • markRaw, Object.freeze 사용 여부 체크
  • • 불변성 패턴으로 새 객체 생성
  • • 배열 조작 시 반응형 메서드 사용
Follow-up 질문

대용량 데이터에서 일부만 반응형이 필요한 경우, shallowRef와 triggerRef를 활용한 최적화 전략은 무엇인가요?

4 코드 리뷰
Medium

Q. 팀원이 작성한 Vue 컴포넌트에서 watch 내부에서 또 다른 watch를 동적으로 생성하고, computed 속성 내부에서 외부 상태를 직접 변경하는 코드를 발견했습니다. 이런 패턴의 문제점을 설명하고, 올바른 리팩토링 방향을 제시해주세요.

A. 모범답안

watch 내부에서 동적으로 watch를 생성하면 메모리 누수가 발생하고 cleanup이 복잡해지며, 의도치 않은 중복 실행이 발생할 수 있습니다. computed 내부에서 상태를 변경하면 순수 함수 원칙을 위반하고 무한 루프나 예측 불가능한 동작을 야기합니다. 동적 의존성 추적이 필요하다면 watchEffect를 사용하고, 여러 소스를 감시해야 한다면 watch의 배열 형태나 중첩된 watchEffect를 사용합니다. computed는 항상 순수 함수로 유지하고, 상태 변경은 watch나 메서드에서 처리해야 합니다. watch 생성 시 반환된 stop 함수를 onUnmounted에서 호출하여 명시적으로 cleanup 합니다.

핵심 포인트
  • • 동적 watch 생성으로 인한 메모리 누수 위험
  • • computed의 부수효과 금지 원칙
  • • watchEffect로 동적 의존성 처리
  • • 명시적인 cleanup 로직 필요성
  • • 반응형 시스템의 예측 가능성 유지
Follow-up 질문

watch의 immediate, deep, flush 옵션들이 실행 순서와 성능에 미치는 영향을 설명하고, 각각 어떤 상황에서 사용해야 하나요?

5 시스템 설계
Hard

Q. 다국어 지원(i18n)이 필요한 대규모 Vue 3 애플리케이션에서 번역 파일의 지연 로딩, 언어 전환 시 상태 유지, 그리고 동적으로 추가되는 번역 키를 지원하는 i18n 시스템을 설계해야 합니다. vue-i18n을 사용한다고 가정할 때, 번들 크기 최적화와 사용자 경험을 고려한 아키텍처를 제안해주세요.

A. 모범답안

라우트별로 번역 파일을 분리하고 Vue Router의 lazy loading과 함께 동적 import로 필요한 번역만 로드합니다. 전역 i18n 인스턴스는 공통 번역만 포함하고, 각 라우트 컴포넌트에서 onBeforeMount 시 해당 언어팩을 i18n.global.mergeLocaleMessage로 병합합니다. 언어 전환 시에는 localStorage에 선택 언어를 저장하고, Pinia 스토어로 전역 언어 상태를 관리하며, Suspense와 함께 비동기 번역 로딩 중 fallback UI를 표시합니다. 동적 번역 키는 API에서 받아와 런타임에 추가하되, 캐싱 전략을 적용하고, 개발 환경에서는 missing key를 감지하여 로그를 남깁니다. 번들 분석 도구로 번역 파일 크기를 모니터링하고, 사용되지 않는 번역은 tree-shaking으로 제거합니다.

핵심 포인트
  • • 라우트 기반 번역 파일 코드 스플리팅
  • • 동적 import와 mergeLocaleMessage 활용
  • • Suspense로 비동기 로딩 상태 처리
  • • localStorage와 전역 상태 관리 조합
  • • 런타임 번역 추가 및 캐싱 전략
  • • 번들 크기 최적화와 모니터링
Follow-up 질문

SSR 환경에서 사용자의 Accept-Language 헤더를 기반으로 초기 언어를 설정하고, 클라이언트 hydration 시 언어 불일치를 방지하는 방법은 무엇인가요?

댓글 0

로그인 후 댓글을 작성할 수 있습니다.

아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!