KIMPRO는 김치프리미엄과 가상화폐 시세 변동을 실시간으로 제공하는 서비스입니다. 국내 거래소 업비트, 빗썸과 해외 거래소 바이낸스의 암호화폐 시세를 비교하여, 여러 수치들을 차트, 테이블 등으로 시각화하였습니다.
'김치 프리미엄'의 'KIMP'와 '프로페셔널'의 'PRO'를 조합하여 KIMPRO를 저희 서비스 이름으로 정하였으며, 이름에 걸맞게 김치 프리미엄을 유저들에게 프로페셔널하게 제공하고자 합니다.
김치 프리미엄(Kimchi premium), 김프는 한국에서 거래되는 암호화폐의 시세가 해외 거래소 시세와 비교해 얼마나 높은가를 뜻하는 단어입니다. 해외 거래소보다 높을 경우 '김치 프리미엄이 끼어 있다.' 비슷한 정도로 낮아질 경우 '김치 프리미엄이 빠졌다.'라고 표현합니다.
기능 | 내용 |
---|---|
김프 차트 ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ | 사용자가 원하는 차트를 셀렉트박스로 선택할 수 있으며, 업비트/빗썸 김치프리미엄과 바이낸스 비트코인 차트를 실시간으로 보여줍니다. |
코인 차트 | 코인 테이블에서 선택한 코인 정보와 시세 차트를 실시간으로 보여줍니다. |
코인 테이블 | 사용자가 원하는 거래소를 셀렉트박스로 선택할 수 있으며, 업비트/빗썸 코인의 이름, 현재가, 전일대비, 고가/저가대비, 거래량, 그리고 각각 코인마다 바이낸스와의 김치프리미엄을 실시간으로 보여줍니다. 또한 각 카테고리별 오름/내림차순 정렬과 코인 검색 기능을 지원합니다. |
위젯 | S&P 500, NASDAQ, KOSPI, KOSDAQ, 금 선물 시세, 전일대비를 수치 및 차트로 보여주며, 캐러셀 형태로 구현하였습니다. |
채팅 | 사이트 이용자들과 실시간 채팅을 할 수 있으며, 로컬스토리지로 부여받은 닉네임으로 소통할 수 있습니다. (로그인 x) |
다크/라이트 모드 | 토글 버튼을 통해 서비스 전체의 색상을 다크 또는 라이트로 설정할 수 있으며, 상태를 로컬스토리지로 저장합니다. |
헤더 | 환율(USD/KRW), 암호화폐/거래소 개수, 전체 시가총액, 24시간 거래량, BTC 점유율, 즉 암호화폐 시장과 관련된 전체적인 수치를 보여줍니다. |
아키텍처(Architecture) |
---|
Lighthouse BEFORE | Lighthouse AFTER |
---|---|
항목 | 웹 성능 최적화 전 | 웹 성능 최적화 후 |
---|---|---|
Performance Score | 26 | 89 |
First Contentful Paint | 0.5s | 0.5s |
Total Blocking Time | 1,670ms | 90ms |
Speed Index | 9.5s | 1.6s |
Largest Contentful Paint | 4.7s | 1.7s |
Cumulative Layout Shift | 0.227 | 0.086 |
- React.memo로 불필요한 리렌더링 개선
- useCallback, useMemo로 메모이제이션
- windowing으로 첫 렌더링 시 보이는 코인만 DOM에 표시
- webpack으로 bunle size 최적화
- 렌더링 전 layout 유지하여 layout shift 최소화
- Code Splitting, Lazy Loading, Suspense
- Lottie로 애니메이션 최적화
- API 캐싱을 통해 네트워크 대역폭 절약
- throttle로 Socket 부하 분산
- react-icons 라이브러리 대신 svg 사용
위와 같은 작업들을 통해 Performace Score 26점 -> 89점으로 개선하였고, TBT, SI, LCP, CLS에서도 유의미한 성과를 보였습니다!
|
|
|
어승준 팀장 (FE) |
서지수 팀원 (FE) |
박나영 팀원 (FE) |
이름 | 역할 | 개발 내용 |
---|---|---|
어승준 | FE 팀장 |
- 기능 구현 - 코인 테이블 - Upbit WebSocket API 연동 및 테이블 적용 - Binance 데이터와 매칭 및 김프 계산 - 검색 기능 구현 - 코인 차트 - Upbit Candlestick API 연동 및 시세 차트 적용 - 선택한 코인 정보 표시 - 채팅 - 실시간 메시지 주고받기 - 이전 대화 가져오기 - 닉네임 랜덤 생성 및 변경 - 스크롤 맨 아래로 이동하기 - 헤더 - coinlore API를 통해 global coin 정보 표시 - 성능 개선 - React.memo로 불필요한 리렌더링 개선 - useCallback, useMemo로 메모이제이션 - throttle로 Socket 부하 분산 - Code Splitting, Lazy Loading, Suspense - Lottie로 애니메이션 최적화 - react-icons 라이브러리 대신 svg 사용 - API 캐싱을 통해 네트워크 대역폭 절약 |
서지수 | FE 팀원 |
- 기능 구현 - 코인 테이블 - Bithumb websocket api 연동 및 테이블 적용 - coingecko api를 이용한 Bithumb 코인명, 아이콘 매칭 - 테이블 컴포넌트화 및 정렬 기능 구현 - 코인 차트 - Bithumb candlestick api 연동 및 시세 차트 적용 - 선택한 코인 정보 표시 - 시세 차트 컴포넌트화 - Upbit, Bithumb api 타입 통일을 통한 컴포넌트화 개선 - 성능 개선 - windowing을 통한 첫 렌더링 시 보이는 코인만 dom에 표시 - React.memo를 이용한 시세 차트, 테이블 불필요한 리렌더링 개선 - react-icons 라이브러리 대신 svg 사용 |
박나영ㅤ | FE 팀원 ㅤ |
- 기능 구현 - 실시간 환율 스트리밍 - 실시간 환율을 크롤링한 정보를 클라이언트에게 Server-Sent Events를 통해 전송하는 백엔드 서버 구축 - 위젯 - 서브지표 api 연동 및 차트 적용 - 캐러셀 구현 - 김프 차트 - tradingview 위젯 적용 - 셀렉트 박스로 심볼값 제공 - 다크/라이트 모드 - 디자인 시스템 구축 - Theme Provider로 공통 스타일 속성 관리구현 - 성능 개선 - 웹팩을 이용한 번들 사이즈 최적화 - React.memo과 컴포넌트 분리로 불필요한 리렌더링 개선 - Suspense로 비동기처리 관리 - 렌더링 전 레이아웃 유지하여 layout shift 최소화 |
폴더 구조 보기
📦Final-Project
┣ 📂src
┃ ┣ 📂@types
┃ ┃ ┣ 📜binance.types.ts
┃ ┃ ┣ 📜bithumb.types.ts
┃ ┃ ┣ 📜common.types.ts
┃ ┃ ┗ 📜upbit.types.ts
┃ ┣ 📂api
┃ ┃ ┣ 📂bithumb
┃ ┃ ┃ ┣ 📜fetchBithumbCandlestick.ts
┃ ┃ ┃ ┗ 📜fetchBithumbTicker.ts
┃ ┃ ┣ 📂coingecko
┃ ┃ ┃ ┗ 📜getCoingeckoData.ts
┃ ┃ ┣ 📂upbit
┃ ┃ ┃ ┣ 📜fetchUpbitDayCandle.ts
┃ ┃ ┃ ┗ 📜fetchUpbitMarketCode.ts
┃ ┃ ┣ 📜getChartWidgetData.ts
┃ ┃ ┣ 📜getGlobalCoinData.ts
┃ ┃ ┣ 📜getNickname.ts
┃ ┃ ┗ 📜getTickerWidgetData.ts
┃ ┣ 📂assets
┃ ┃ ┗ 📂images
┃ ┃ ┃ ┣ 📜Caret-Down.svg
┃ ┃ ┃ ┣ ...
┃ ┃ ┃ ┗ 📜usdt.svg
┃ ┣ 📂components
┃ ┃ ┣ 📂ChartLeft
┃ ┃ ┃ ┣ 📂ChartInfo
┃ ┃ ┃ ┃ ┣ 📜ChartInfo.tsx
┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┃ ┣ 📂TradingViewWidget
┃ ┃ ┃ ┃ ┣ 📜TradingViewWidget.tsx
┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┃ ┣ 📜ChartLeft.constant.ts
┃ ┃ ┃ ┣ 📜ChartLeft.styles.ts
┃ ┃ ┃ ┣ 📜ChartLeft.tsx
┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┣ 📂ChartRight
┃ ┃ ┃ ┣ 📂ChartCoinInfo
┃ ┃ ┃ ┃ ┣ 📜ChartCoinInfo.styles.ts
┃ ┃ ┃ ┃ ┣ 📜ChartCoinInfo.tsx
┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┃ ┣ 📂ChartContent
┃ ┃ ┃ ┃ ┣ 📜ChartContent.styles.ts
┃ ┃ ┃ ┃ ┣ 📜ChartContent.tsx
┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┃ ┣ 📜ChartRight.styles.ts
┃ ┃ ┃ ┣ 📜ChartRight.tsx
┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┣ 📂ChatBox
┃ ┃ ┃ ┣ 📜ChatBox.styles.ts
┃ ┃ ┃ ┣ 📜ChatBox.tsx
┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┣ 📂ChatBtn
┃ ┃ ┃ ┣ 📜ChatBtn.styles.ts
┃ ┃ ┃ ┣ 📜ChatBtn.tsx
┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┣ 📂CustomSelect
┃ ┃ ┃ ┣ 📜CustomSelect.styles.ts
┃ ┃ ┃ ┣ 📜CustomSelect.tsx
┃ ┃ ┃ ┣ 📜CustomSelect.types.ts
┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┣ 📂LoadingAnimation
┃ ┃ ┃ ┣ 📜LoadingAnimation.styles.ts
┃ ┃ ┃ ┣ 📜LoadingAnimation.tsx
┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┣ 📂Message
┃ ┃ ┃ ┣ 📜Message.styles.ts
┃ ┃ ┃ ┣ 📜Message.tsx
┃ ┃ ┃ ┣ 📜Message.types.ts
┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┣ 📂SendMessage
┃ ┃ ┃ ┣ 📜SendMessage.styles.ts
┃ ┃ ┃ ┣ 📜SendMessage.tsx
┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┣ 📂Table
┃ ┃ ┃ ┣ 📂TableBox
┃ ┃ ┃ ┃ ┣ 📂CoinList
┃ ┃ ┃ ┃ ┃ ┣ 📂CoinChange
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜CoinChange.tsx
┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┃ ┃ ┃ ┣ 📂CoinHighest
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜CoinHighest.tsx
┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┃ ┃ ┃ ┣ 📂CoinInfo
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜CoinInfo.tsx
┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┃ ┃ ┃ ┣ 📂CoinKimp
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜CoinKimp.tsx
┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┃ ┃ ┃ ┣ 📂CoinLowest
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜CoinLowest.tsx
┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┃ ┃ ┃ ┣ 📂CoinPrice
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜CoinPrice.tsx
┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┃ ┃ ┃ ┣ 📂TradeValue
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜TradeValue.tsx
┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┃ ┃ ┃ ┣ 📜CoinList.styles.ts
┃ ┃ ┃ ┃ ┃ ┣ 📜CoinList.tsx
┃ ┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┃ ┃ ┣ 📜TableBox.styles.ts
┃ ┃ ┃ ┃ ┣ 📜TableBox.tsx
┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┃ ┣ 📂TableHeader
┃ ┃ ┃ ┃ ┣ 📂TableHeaderItem
┃ ┃ ┃ ┃ ┃ ┣ 📜TableHeaderItem.styles.ts
┃ ┃ ┃ ┃ ┃ ┣ 📜TableHeaderItem.tsx
┃ ┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┃ ┃ ┣ 📜TableHeader.styles.ts
┃ ┃ ┃ ┃ ┣ 📜TableHeader.tsx
┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┃ ┣ 📂TableNav
┃ ┃ ┃ ┃ ┣ 📜TableNav.styles.ts
┃ ┃ ┃ ┃ ┣ 📜TableNav.tsx
┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┃ ┣ 📜Table.constant.ts
┃ ┃ ┃ ┣ 📜Table.styles.ts
┃ ┃ ┃ ┣ 📜Table.tsx
┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┣ 📂Widget
┃ ┃ ┃ ┣ 📂Carousel
┃ ┃ ┃ ┃ ┣ 📜Carousel.tsx
┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┃ ┣ 📂ChartWidget
┃ ┃ ┃ ┃ ┣ 📜ChartWidget.tsx
┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┃ ┣ 📂TickerWidget
┃ ┃ ┃ ┃ ┣ 📜TickerWidget.tsx
┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┃ ┣ 📜Card.tsx
┃ ┃ ┃ ┣ 📜Widget.constants.ts
┃ ┃ ┃ ┣ 📜Widget.styles.ts
┃ ┃ ┃ ┣ 📜Widget.tsx
┃ ┃ ┃ ┣ 📜Widget.types.ts
┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┗ 📂common
┃ ┃ ┃ ┣ 📂Footer
┃ ┃ ┃ ┃ ┣ 📜Footer.styles.ts
┃ ┃ ┃ ┃ ┣ 📜Footer.tsx
┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┃ ┗ 📂Header
┃ ┃ ┃ ┃ ┣ 📂ExchangeRateDisplay
┃ ┃ ┃ ┃ ┃ ┣ 📜ExchangeRateDisplay.styles.ts
┃ ┃ ┃ ┃ ┃ ┣ 📜ExchangeRateDisplay.tsx
┃ ┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┃ ┃ ┣ 📂GlobalCoinLabel
┃ ┃ ┃ ┃ ┃ ┣ 📜GlobalCoinLabel.styles.ts
┃ ┃ ┃ ┃ ┃ ┣ 📜GlobalCoinLabel.tsx
┃ ┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┃ ┃ ┃ ┣ 📜Header.styles.ts
┃ ┃ ┃ ┃ ┣ 📜Header.tsx
┃ ┃ ┃ ┃ ┣ 📜Header.types.ts
┃ ┃ ┃ ┃ ┗ 📜index.ts
┃ ┣ 📂firebase
┃ ┃ ┣ 📜config.ts
┃ ┃ ┣ 📜createMessages.ts
┃ ┃ ┣ 📜fetchMessages.ts
┃ ┃ ┣ 📜messageQuery.ts
┃ ┃ ┗ 📜orderSnapshotMessages.ts
┃ ┣ 📂hooks
┃ ┃ ┣ 📂binance
┃ ┃ ┃ ┣ 📜index.ts
┃ ┃ ┃ ┣ 📜updateSocketDataWithBinance.ts
┃ ┃ ┃ ┣ 📜useBinanceTicker.ts
┃ ┃ ┃ ┗ 📜useFetchExchangeRate.ts
┃ ┃ ┣ 📂upbit
┃ ┃ ┃ ┗ 📜useUpbitTicker.ts
┃ ┃ ┣ 📜index.ts
┃ ┃ ┣ 📜useChartTickers.ts
┃ ┃ ┣ ...
┃ ┃ ┗ 📜useWidgetTickers.ts
┃ ┣ 📂pages
┃ ┃ ┗ 📂home
┃ ┃ ┃ ┣ 📜Home.page.tsx
┃ ┃ ┃ ┣ 📜Home.styles.ts
┃ ┃ ┃ ┗ 📜index.ts
┃ ┣ 📂recoil
┃ ┃ ┗ 📂atoms
┃ ┃ ┃ ┣ 📜commonAtoms.ts
┃ ┃ ┃ ┣ ...
┃ ┃ ┃ ┗ 📜themeAtoms.ts
┃ ┣ 📂styles
┃ ┃ ┣ 📜globalStyle.ts
┃ ┃ ┗ 📜theme.ts
┃ ┣ 📂utils
┃ ┃ ┣ 📜convertDate.ts
┃ ┃ ┣ ...
┃ ┃ ┗ 📜removeUSDT.ts
┃ ┣ 📜App.tsx
┃ ┣ 📜index.tsx
┃ ┣ 📜react-app-env.d.ts
┃ ┗ 📜reportWebVitals.ts
┣ 📜.eslintrc
┣ 📜.gitignore
┣ 📜.prettierrc
┣ 📜README.md
┣ 📜config-overrides.js
┣ 📜package-lock.json
┣ 📜package.json
┗ 📜tsconfig.json