프론트엔드 개발자
차영건
구조와 완성도로 가치를 만드는 프론트엔드 개발자입니다. 디자인 시스템과 공통 컴포넌트로 스타일·타입을 분리해 유지보수하기 쉬운 코드를 만들고, 인터랙션·폼 검증 같은 디테일과 끝까지 파고드는 트러블슈팅으로 서비스를 완성합니다.
소개
[변화를 두려워하지 않는 개발자]
익숙한 방식에 머무르지 않습니다. 새 스택이나 도구가 필요하면 문서와 예제로 빠르게 익히고, 프로젝트에 적용해 봅니다.
[실패를 무서워하지 않는 개발자]
막히면 멈추지 않습니다. 에러 로그와 원인부터 확인하고, 해결될 때까지 하나씩 좁혀 갑니다.
[단순함을 고민하는 개발자]
기능을 더하기 전에 꼭 필요한지부터 묻습니다. UI는 사용자 흐름을 방해하지 않게, 코드는 읽기 쉽게 유지하려고 합니다.
학력
상명대학교 천안캠퍼스
소프트웨어학과
2020.03 ~ 2026.02
학점 4.28 / 4.5
기술
Languages
- HTML5
- CSS3
- JavaScript
- TypeScript
Frameworks
- React
- Next.js
- React Native
Styling
- styled-components
- Emotion
- Tailwind CSS
State & Data
- Zustand
- React Query
Real-time
- WebSocket
- WebRTC
Testing
- Jest
Tools
- GitHub
- Slack
- Notion
- Figma
프로젝트
Fridgely
2026.01 — 2026.06
냉장고 관리 앱. BE 1명과 협업하여 Android 앱 FE를 단독 담당했습니다. Google Play 등록 완료, 지속 업데이트 예정입니다.
주요 성과
알림 설정 화면 성능 개선
서버 대기·전체 리렌더로 느렸던 알림 설정을, 낙관적 업데이트와 리렌더 범위 축소로 즉시 반응하게 바꿨습니다.
문제
알림 토글·옵션 변경이 서버 응답 후에야 UI에 반영됐고, 값 변경마다 화면 전체가 리렌더되며 TimePicker Sheet가 상시 마운트되어 저사양에서 버벅였습니다.
방법
React Query 낙관적 업데이트(onMutate/onError 롤백)로 입력을 즉시 반영하고, memo·콜백 안정화로 리렌더 범위를 줄였습니다. Sheet는 open 시에만 마운트하도록 바꿨습니다.
결과
설정 변경이 탭 즉시 반영되고, 저사양 기기에서도 알림 설정 화면의 터치 지연이 체감되지 않는 수준으로 줄었습니다.
이미지 업로드 최적화
원본 업로드로 느렸던 전송을, 업로드 전 리사이즈·압축으로 용량과 지연을 줄였습니다.
문제
프로필 이미지를 원본 그대로 올리면 용량이 커 전송이 길었고, 네이티브 리사이즈 실패 시 업로드가 끊길 수 있었습니다.
방법
긴 변 1280 리사이즈 + JPEG 0.8 압축 파이프라인을 두고, 실패 시 원본 fallback과 비JSON 에러 파싱을 보강했습니다.
결과
3회 측정 기준 용량 평균 96.1% 절감(약 2.9–3.6MB → 98–162KB), 업로드 체감 지연이 줄었습니다.
단위 선택 시트 터치 반응성 개선
시트 오픈 랙을 JS 애니메이션 부하로 보고, Native Driver 기반 Animated로 옮겼습니다.
문제
식재료 추가/수정에서 단위 선택 시 시트가 뜨기까지 반응이 늦었고, Tamagui 애니메이션과 폼 리렌더가 JS 스레드를 함께 잡아먹었습니다.
방법
시트를 RN Animated(translateY/opacity, useNativeDriver)로 전환하고, 연타 중복 실행과 핸들러 참조를 안정화했습니다.
결과
단위 선택 시트 오픈 시 터치 랙 해소되어, 폼 입력 중에도 시트가 바로 열리게 됐습니다.
FCM 토큰 동기화 최적화
토큰이 안 바뀌어도 매번 API를 치던 구조를, 변경 시에만 동기화하도록 바꿨습니다.
문제
앱 실행·인증 변화·Foreground 복귀마다 FCM 토큰을 서버에 보내, 변경이 없어도 네트워크 비용이 나갔습니다.
방법
시나리오별 동기화 로직과 lastSyncRef 캐시로 ‘실제 변경 시에만’ 전송하고, 성공 후 로컬을 갱신하는 success-first 구조로 맞췄습니다.
결과
불필요 FCM 동기화 호출이 줄고, 실패 시 재시도가 가능한 흐름을 유지했습니다.
JWT 식별자 추출 및 동기화 무결성
accessToken을 유저 키로 쓰다 생긴 중복 재등록을, JWT sub 기반 고정 ID로 해결했습니다.
문제
유저 식별자로 accessToken을 쓰면 갱신마다 다른 유저로 보여 FCM이 다시 등록됐고, 토큰 조회 시점에 값이 엇갈릴 레이스도 있었습니다.
방법
JWT payload에서 불변 sub를 stableUserId로 쓰고, 동기화 구간에 토큰을 한 번만 추출해 공유하도록 리팩터링했습니다.
결과
토큰 갱신 시 중복 FCM 재등록이 사라지고, 동기화 구간의 토큰 정합성이 맞춰졌습니다.
핵심 임팩트
- 입력 지연·시트 랙 등 체감 성능 이슈를 낙관적 업데이트·리렌더 축소로 개선해 저사양에서도 반응이 바로 오도록 맞춤
- 이미지 원본 업로드 병목을 리사이즈·압축 파이프라인으로 해결해 용량 평균 96.1% 절감 (약 3MB → 약 100KB)
- 실기기(Galaxy S21)에서 콜드 스타트 ~2.36s, 로그인→홈 ~1.19s, 홈 스크롤 60fps+ 측정으로 품질 검증
- features/shared로 API·인증을 정리하고 Jest 테스트 약 50개로 회귀를 방지
- Expo
- React Native
- TypeScript
- TanStack Query
- Zustand
- Tamagui
- FCM
- Jest
PlanHub
2025.04 — 2025.05
학생·IT 종사자를 위한 협업 플랫폼. GitHub 연동 일정 관리, AI 회의록 요약, 포트폴리오/README 자동 생성을 제공하는 SW 캡스톤 프로젝트입니다. FE 팀 내 디자인 시스템·공통 UI·온보딩·팀 관리 영역을 담당했습니다.
주요 성과
디자인 시스템 및 공통 컴포넌트 구축
제각각이던 버튼·인풋을 Theme 토큰과 공통 컴포넌트로 묶어, 팀이 같은 인터페이스로 화면을 조립하게 했습니다.
문제
화면마다 스타일·버튼·입력이 달라 동일 패턴을 매번 새로 만들었고, 팀 UI 속도·일관성이 떨어졌습니다.
방법
colors·text 토큰과 Theme 타입을 정의하고, Button/Input/Modal 등을 props로 변형 가능한 공통 컴포넌트(36+)로 설계했습니다.
결과
팀원이 동일 인터페이스로 UI를 조합할 수 있게 되어, 반복 구현이 줄고 화면 간 스타일 일관성이 맞춰졌습니다.
ModalPortal 및 범용 Modal 아키텍처
레이아웃에 갇히던 모달·드롭다운을 body 포탈로 빼고, 확인 모달을 하나로 통합했습니다.
문제
페이지 안 모달이 overflow·z-index에 잘리거나 가려졌고, 삭제/저장 확인 모달이 화면마다 중복됐습니다.
방법
document.body에 마운트하는 ModalPortal과 뷰포트 절대 위치 드롭다운을 두고, 범용 Modal로 확인 플로우를 통합했습니다.
결과
모달·드롭다운이 레이아웃에 잘리지 않고, 이후 기능에서도 같은 확인 UI를 재사용할 수 있게 됐습니다.
팀 생성 및 이메일 초대 플로우
여러 이메일 검증·초대 발송이 흩어져 있던 흐름을, 한 모달에서 끝나도록 묶었습니다.
문제
팀 생성 시 다중 이메일 검증·중복 피드백과, 생성 후 초대코드·메일 발송·캐시 갱신이 따로 놀기 쉬웠습니다.
방법
useEmailList로 검증 상태를 캡슐화하고, 생성 → 초대코드 → 메일 → invalidateQueries → 이동을 순차로 연결했습니다.
결과
팀 생성부터 초대까지를 한 모달에서 처리하고, 목록 갱신·페이지 이동까지 끊기지 않게 맞춰졌습니다.
Task 템플릿 가져오기 모달
템플릿 검색·선택·삭제 확인을 한 모달로 모으고, 성공 시 목록이 바로 갱신되게 했습니다.
문제
템플릿 불러오기·검색·선택·편집/삭제가 흩이 길고, 삭제 후 캘린더와 목록 동기화가 필요했습니다.
방법
목록 조회 + title 필터 + 단일 선택 UI를 모달에 두고, 삭제/수정은 범용 Modal 확인 후 invalidateQueries로 동기화했습니다.
결과
템플릿 작업을 한 화면에서 끝낼 수 있고, 변경 직후 목록·캘린더 상태가 맞게 반영됩니다.
핵심 임팩트
- 화면마다 제각각이던 UI를 Theme·공통 컴포넌트 36+로 정리해 팀 구현 속도와 일관성을 높임
- 모달 overflow/z-index 이슈를 Portal 구조로 해결하고, 확인 모달을 범용 컴포넌트로 통합
- 팀 생성→초대 메일까지 한 모달 플로우와 GitHub OAuth 온보딩을 구현
- React
- TypeScript
- TanStack Query
- Emotion
- React Router
HeartScore (MUVS)
2025.01 — 2025.08
피트니스 트레이너용 실시간 심박·운동 대시보드 웹앱. 외주 프로젝트로 임베디드 심박 센서·Spring 백엔드와 협업하며 FE를 단독 담당했습니다. 계약상 소스코드·GitHub 공개는 불가합니다. PWA로 iPad 등 태블릿 시연 환경에 최적화했습니다.
주요 성과
WebRTC 화면 공유 구현
별도 스트리밍 서버 없이, 브라우저만으로 트레이너 대시보드를 원격 공유하게 만들었습니다.
문제
iPad 대시보드를 뷰어 기기에서도 봐야 했지만 스트리밍 서버가 없었고, PeerConnection 중복·미정리로 누수 위험이 있었습니다.
방법
getDisplayMedia + REST Offer/Answer 폴링으로 시그널링하고, resetPeerConnection과 종료 시점(트랙 종료·로그아웃·수업 종료)에 연결을 일괄 정리했습니다.
결과
현장 시연에서 원격 뷰어로 대시보드를 볼 수 있게 됐고, 공유 종료 후에도 연결이 남아 있지 않도록 맞췄습니다.
시연 환경 IP 자동화
시연마다 IP를 손으로 바꾸던 세팅을, 자동 감지와 실패 시 수동 입력으로 단순화했습니다.
문제
센서·Spring이 로컬 Wi-Fi에 묶여 시연마다 .env·소켓·QR IP를 바꿔야 했고, 실패 원인 구분이 어려웠습니다.
방법
npm 스크립트로 Wi-Fi IP를 주입하고, Firebase에서 모뎀 IP를 읽어 연결한 뒤 타임아웃 시 수동 입력·자동 재연결을 두었습니다.
결과
시연 준비에서 IP 수작업을 줄였고, 일시 끊김도 재연결로 복구되는 흐름을 만들었습니다.
실시간 심박 대시보드 및 기기 재연결 UX
밴드가 끊겨도 빈 카드로 두지 않고, 자리에서 바로 다시 붙일 수 있게 했습니다.
문제
수업 중 연결이 끊기면 카드가 비고, 대시보드를 나가지 않고 재연결할 방법이 없었습니다. 인원 1~25명에 따라 밀도도 달랐습니다.
방법
Valid===3일 때 카드 안 ReconnectModal로 재페어링하고, 인원 구간별 카드/폰트 스케일과 zonePercent 유지를 적용했습니다.
결과
트레이너가 수업 중에도 끊긴 기기를 바로 다시 붙일 수 있고, 인원 규모에 맞는 가독성을 유지했습니다.
PWA·QR 회원가입·운동 기록 시각화
태블릿 시연용으로 앱처럼 보이게 하고, QR 가입과 운동 그래프를 붙였습니다.
문제
iPad 브라우저 UI가 시연을 방해했고, 회원 추가·기록 확인이 현장에서 번거로웠습니다.
방법
PWA fullscreen·SW, Wi-Fi 기반 가입 QR, recharts로 kcal·pts 추이 그래프를 구현했습니다.
결과
시연이 태블릿 앱에 가깝게 진행되고, 회원 추가와 최근 운동 기록을 현장에서 바로 보여줄 수 있게 됐습니다.
핵심 임팩트
- 스트리밍 서버 없이 WebRTC로 대시보드 원격 공유를 구현하고, 종료 시 연결을 정리해 누수를 막음
- 시연마다 IP를 수동 입력하던 환경을 자동 감지·fallback·재연결로 바꿔 세팅 시간을 줄임
- 밴드 끊김 시 빈 카드로 남던 UX를 카드 안 재페어링과 인원별 레이아웃으로 보완
- React
- JavaScript
- styled-components
- WebSocket
- WebRTC
- Axios
- PWA
- recharts
- React Router
물렐루야!
전국 연합 동아리 SW 해커톤 대상 - 물렐루야 (2024.09)
건강한 수분 섭취 습관 형성 서비스. 음료 종류별 개인 수분 섭취량 기록·관리와 루틴·통계 기능으로 지속 가능한 수분 섭취 습관을 돕는 웹 애플리케이션. 4인 팀(FE 2, BE 2)으로 참여해 구름톤 대상을 수상했습니다.
핵심 임팩트
- 짧은 해커톤 일정에 맞춰 초기 세팅·라우팅·공통 환경을 먼저 잡아 팀 개발 속도를 올림
- 랜딩·주요 인터랙션 UI를 구현해 수분 기록·기록 흐름을 사용자가 바로 이해하도록 맞춤
- 섭취 데이터 시각화·루틴/기록 화면으로 ‘얼마나 마셨는지’를 한눈에 보이게 구성 → 구름톤 대상(1위)
- React
- SCSS
- styled-components
- Tailwind CSS
- axios
포트폴리오
개인 포트폴리오 사이트. Next.js App Router와 Tailwind CSS로 미니멀한 UI를 구현했습니다.
- Next.js
- TypeScript
- Tailwind CSS
수상
전국 연합 동아리 SW 해커톤 대상 - 물렐루야
2024.09
구름톤
1위, 단장상