미리보기
기본 정보
👀 시각적으로 데이터를 나타내고 기록하는 것을 좋아하는 프론트엔드 개발자입니다. 📊 성능 최적화, 새로운 거 학습, 수치화 및 시각화에 관심이 많습니다. 🍀 "꾸준함"과 "함께"에 큰 가치를 두고 있고, 공유를 통해 했던 고민들을 해결할 수 있는 개발자가 목표입니다.
기술 스택
React, Next.js, TypeScript, JavaScript, Sass, react-query, github-actions, MySQL
프로젝트
Roadmaker 📚 - 학습 로드맵 작성 + 공유 커뮤니티
개인
2024.03. ~ 2024.04.
🛣 Roadmaker: 공부 로드맵을 CHATGPT를 이용해 초안을 작성하거나 유저들 간 공유를 통해 동기부여를 할 수 있는 커뮤니티
(🎥 시현영상)
✨ 기존 프로젝트에서 성능 최적화에 집중하여 nextjs 마이그레이션을 진행했습니다.
🍀 깃허브: 해당 서비스의 스펙을 살펴보실 수 있습니다.
🔗 링크: 서비스를 사용해보실 수 있습니다. (2024.8.17 기준 서버 도메인을 닫아서 일시적으로 이용 불가합니다.)
서비스 소개
로드맵 생성 : rich-editor인 tiptap-editor와 그래프 커스터마이징이 가능한 reactflow를 통해 학습 로드맵을 생성
로드맵 참여 및 진행 : 로드맵에 참여하고 진행도를 업데이트
댓글 작성 : tiptap-editor를 연동한 댓글 작성 기능, 유튜브, 코드블럭 등 첨부 가능
검색 기능: 키워드가 제목에 포함된 로드맵 검색
기술 스택
Nextjs (app router)+ Typescript
Tanstack Query, zustand
Mantine, Styled Components
Tiptap editor, reactflow
Vercel
Commitlint
next auth
최적화 요소 (Performance 전반 : 67 ➡ 94로 개선)
LCP : 1.5s ➡ 1.0s
Cumulative Layout shift : 0.883 ➡ 0.061
lighthouse를 통해 성능을 개선할 수 있는 지표들을 확인
렌더링 과정에 blocking 요소로 작용하는 inline css 제거
메인 페이지 게시물을 불러오는 과정에서 LCP 지표가 좋지 않음 확인
화면에 게시물이 로드되기 전 영역을 빈 화면이 아닌 skeleton ui로 대체
Next Image를 활용하여 white-label 처리한 백엔드에서 이미지 preload
불필요한 리랜더링 최소화
재사용되는 node와 edge의 스타일의 로드맵 컴포넌트를 memo로 memoize.
memoization을 과도하게 사용하는 성급한 최적화를 인식하여, 수정 및 변경 사항이 많은 값들은 useEffect로 대체
로드맵 위치 연산과 같은 무거운 연산은 useMemo로 memoize.
마운트 시 로드맵 높이 동적으로 계산
reactflow의 로드맵을 그리기 위해서는 height와 width를 px 단위로 제공해야 했습니다.
이전 해결 방식
overflow영역 스크롤 : 2개의 스크롤을 만들어 유저가 컨트롤을 하기 어려웠고, 스크롤 바 스타일을 일정하게 하기 위한 추가적인 작업이 필요
px 값 고정 : 커스터마이징의 정도가 높은 라이브러리 특성 상, 로드맵의 height과 width에 따라 남거나 잘리는 영역이 생성
도입한 해결 방식
마운트 시 로드맵의 양끝단에 위치한 노드들의 height과 width를 동적으로 계산
커밋 컨벤션 강화
기존 프로젝트에서는 암묵적인 합의로 커밋 컨벤션을 지키고자 했습니다.
하지만 한 달이라는 짧은 기간 내 많은 수정 사항이 오가고, 내용 파악에 어려움이 있었음
commitlint과 husky 도입으로 강제하여 pr와 커밋 메시지 포멧을 유지
app router의 parellel routing 도입
내 정보 페이지에는
사용자 프로필
과사용자가 작성하거나 '좋아요'를 누른 로드맵 리스트
로 구성되어 있었습니다.프로필을 열람하고 수정하는 영역은 로드맵 리스트와 독립적으로 컨트롤/업데이트가 필요한 상황
작성하거나 '좋아요'를 누른 로드맵들을 요청하는데 한번에 프로필 정보, 로드맵 정보를 불러오는데 페이지 로딩 속도에 부정적 영향을 미치는 상황
parellel routing으로 준비되는대로 영역의 콘텐츠를 보여줘서 페이지 로딩 속도 인지 개선
Vinylify 🎶 - spotify api를 활용한 음악 검색/재생 1인 리액트 프로젝트
f-lab
2024.05. ~ 2024.07.
🔗링크에서 spotify 프리미엄 구독 시 앱 기능을 사용할 수 있습니다.
🍀깃허브에서 해당 서비스의 스펙을 살펴보실 수 있습니다.
서비스 소개
내 최근 최다 재생 목록 20곡
내 최근 최다 재생 목록 20곡 기반 추천 20곡
곡 현재 기기에 재생/중지
현재 재생 곡 가사 보기
현재 재생 곡 아티스트 정보 보기
앨범, 아티스트, 트랙, 플레이리스트 검색
기술 스택
React + Typescript
State management & data fetching : Tanstack query | Ky
Build & Deployment : Vercel
Code Quality & Version Control : Commitlint | Yarn | Vite
Error tracking & Monitoring : Sentry
Styling : Sass
APIs : Spotify | Genius
web scraping : cheerio
최적화
폰트 최적화
google cdn으로 폰트를 불러오는 방식이 블로킹을 야기한다는 것을 파악
WOFF2 Format으로 압축하고 fallback 폰트를 제공하여 FOIT/ FOUT 방지
스켈레톤 UI를 활용
infiniteScroll로 검색 항목 리스트를 너무 빨리 스크롤 시 빈 화면이 보인다는 문제 파악
fetch 중인 항목들이 로딩 중일 경우, 이전 게시물을 유지하고 로딩 중 게시물 부분을 스켈레톤 그리드로 대체
Semantic HTML을 고려한 개발
Accessibility 개선과, 정보 비대칭을 줄이기 위해 적절한 태그를 구분하고 aria 정보를 제공하며 코드 작성
음악 재생 시간을 나타내는 진행 바를 <progress/> 태그로 구현
재생과 중지 button의 aria-label에 해당 곡 제목을 제공하여 screen reader 컨텐츠 정보 제공
공식 개발문서를 통한 API와 상태코드 이해 및 조치
영문으로 된 개발 문서와 자료를 문제없이 읽고 해결 방안을 도출
아티스트 이름 배열을 재귀적으로 잘라 요청을 보냄으로써 400 에러 해결
spotify api docs에 의하면, 검색 시 회당 아티스트 정보 호출 api가 제한 50명으로 제한되어 한꺼번에 요청 시 TOO MANY REQUESTS 에러 발생한다는 것을 파악
Set으로 중복 제거 후, 재귀적으로 20명의 아티스트 정보를 나누어 요청을 처리
자바스크립트 언어 특성을 고려한 코드 관심사 분리
tanstack 쿼리 키 관리 및 컴포넌트 작성 시 '함수는 일급 객체'라는 특성을 고려하여 코드 작성
컴파운드 컴포넌트 패턴을 모방하여, 관련 함수 컴포넌트에 프로퍼티로 참조할 수 있도록 관심사 하나로 분류
예: <CardSkeleton/>을 참조할 경우 <Card.Skeleton/>으로 접근 가능하도록 패턴 구현
tanstack 쿼리키 또한 함수의 프로퍼티로 키를 반환하는 함수를 추가하여 쿼리에 관련된 관심사 하나로 분류
디바운스 커스텀 훅
사용자가 검색 입력창에 일정 기간동안 action을 취하지 않을 시 요청을 하도록 debounce 도입
연속적으로 동일한 요청을 하나의 요청만 처리하도록 부하를 줄임
실시간 웹스크래핑
spotify api는 가사에 대한 api는 미제공한다는 아쉬움이 있음
자바스크립트 기반 웹스크래핑 cheerio 라이브러리를 통해 genius 사이트의 노래 가사를 실시간 제공
포트폴리오
자격증
제47회 SQL 개발자(SQLD) 자격증
취득 | Kdata 데이터자격검정
2022.11.
TOEFL IBT
109/120 | ETS
2020.07.
교육
F-lab
사설 교육 | 프론트엔드 멘토링 과정
2024.05. ~ 현재 | 재학 중
Krafton Jungle
사설 교육 | 크래프톤 정글 2기
2023.04. ~ 2023.08. | 졸업
The University of Queensland, Brisbane
대학교(학사) | Bachelor of Arts,Psychology
2016.08. ~ 2020.07. | 졸업