Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/git-marvel/commit-guardians-client
๐
์ปค๋ฐ ํ๋ฆฌํฐ๋ฅผ ์ ์๋ก, ๋ฑ์ง๋ก ์๋ํ์ธ์! Show off your commit quality with scores and a badge!
https://github.com/git-marvel/commit-guardians-client
firebase-storage github-api javascript react repository-badge zustand
Last synced: 15 days ago
JSON representation
๐ ์ปค๋ฐ ํ๋ฆฌํฐ๋ฅผ ์ ์๋ก, ๋ฑ์ง๋ก ์๋ํ์ธ์! Show off your commit quality with scores and a badge!
- Host: GitHub
- URL: https://github.com/git-marvel/commit-guardians-client
- Owner: git-marvel
- Created: 2024-11-01T12:55:18.000Z (3 months ago)
- Default Branch: dev
- Last Pushed: 2025-01-05T11:48:13.000Z (20 days ago)
- Last Synced: 2025-01-05T12:28:41.447Z (20 days ago)
- Topics: firebase-storage, github-api, javascript, react, repository-badge, zustand
- Language: JavaScript
- Homepage: https://commitguardians.netlify.app
- Size: 24 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Commit Guardians
## ํ๋ก์ ํธ ์๊ฐ
![project_intro.png](assets/readme/project_intro.png)
## ๋ชฉ์ฐจ
## ํ๋ก์ ํธ ๋ฑ์ฅ ๋ฐฐ๊ฒฝ
๊ฐ๋ฐ์์ ์ผ์์ ์ฝ๋๋ง ์์ฑํ๋ ๊ฒ์ด ์๋ **โ๊ธฐ๋กโ์ ๋จ๊ธฐ๊ณ ๊ณต์ ํ๋ ๊ณผ์ ๊น์ง๋ ํฌํจ**๋๋ค๊ณ ์๊ฐํฉ๋๋ค. ํนํ ํ ํ๋ก์ ํธ๋ ๊ฐ์ธ ํ๋ก์ ํธ ๋ฟ๋ง ์๋๋ผ ์คํ์์ค์์๋ **์ปค๋ฐ ๋ฉ์์ง**๋ ์์ ํ๋ฆ์ ์ดํดํ๊ณ ์ง๋ ์์ ์ ๋๋์๋ณด๋ฉฐ ํ๋ก์ ํธ์ ๋งฅ๋ฝ์ ํ์ ํ๋ ๋ฐ์ ์ค์ํ ์ญํ ์ ํ๊ณ ์์ต๋๋ค.
์ปค๋ฐ๋ฉ์์ง๋ ์ฝ๋๊ฐ ์ด๋ป๊ฒ ๋ณ๊ฒฝ๋์๋์ง ์์ฝํด์ค ๋ฟ๋ง ์๋๋ผ, โ์โ ๋ณ๊ฒฝ๋์๋์ง๋ฅผ ์ค๋ช ํฉ๋๋ค. ๊ทธ๋์ ์ฝ๋๋ฆฌ๋ทฐ๋ ๋๋ฒ๊น ์ ํ ๋ ์ฝ๋์ ๋ณ๊ฒฝ์ฌํญ์ ๋น ๋ฅด๊ฒ ํ์ ํ ์ ์๋ ์ค์ํ ์ญํ ์ ํ๊ณ ์์ต๋๋ค. ๊ฐ ์ปค๋ฐ ํ์ ์ ๋ฐ๋ผ ๋ฆด๋ฆฌ์ฆ ๋ ธํธ๋ฅผ ์๋์ผ๋ก ์์ฑํ ์๋ ์์ด์ ์์ ๋จ์๋ฅผ ์๊ฒ ์ชผ๊ฐ์ด ์ปค๋ฐ์ ํ๋ ๊ฒ์ ํ์ ์ ์์ด์ ์ข์ ์ต๊ด์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๋ ๊ธฐ์ **์ปค๋ฐ ๋ฉ์ธ์ง์ ๋ฐ๋ฅธ ์ฝ๋ ์์ ์ด ์๋ก ์ผ์นํด์ผ** ํฉ๋๋ค.
์ผ๋ฐ์ ์ผ๋ก ์ข์ ์ปค๋ฐ ๋ฉ์์ง์ ๋ด์ฉ์ **์๋ฏธ์๋ ์ปค๋ฐ ๋ฉ์์ง๋ฅผ ์ฐ๋ ๊ฒ**์ด๋ฉฐ, ์ต๋ํ ๋ ผ๋ฆฌ์ ์ธ ๋จ์๋ก diff (๋ณ๊ฒฝ์ฌํญ)๋ฅผ ๋๋๋ ๊ฒ์ ๋๋ค. ๋ ผ๋ฆฌ ๋จ์๋ณ๋ก ๋๋์ด ์ปค๋ฐ์ ํ๋ ๊ฒ์ด ๊ฐ๋ณ ๋ณ๊ฒฝ ์ฌํญ์ผ๋ก ๋๋๋ฆฌ๊ธฐ ํธํ๊ณ ์ด๋ ๋ถ๋ถ์์ ์ค๋ฅ๊ฐ ๋ฌ๋์ง ํ์ธํ๊ธฐ ์์ํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ด๋ฌํ ๊ผผ๊ผผํ ์ปค๋ฐ๋ค์ด ๋ชจ์ฌ์ ์ ์ง๋ณด์๊ฐ ์ฉ์ดํ๊ณ ํ์ ํ๊ธฐ ์ข์ ํ๋ก์ ํธ๋ฅผ ๋ง๋๋ ๊ธฐ์ด๊ฐ ๋ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
๊ทธ๋ ๋ค๋ฉด, **ํ์ฌ ๊นํ ๋ ํฌ์งํ ๋ฆฌ์ ์ปค๋ฐ๋ค์ ๊ณผ์ฐ ๊ฑด๊ฐํ ์ํ์ผ๊น์?**
์ด ์ง๋ฌธ์์ ์์๋ Commit Guardians ํ ํ๋ก์ ํธ๋, **์ปค๋ฐ ๋ฉ์์ง์ ์ฝ๋ ๋ณ๊ฒฝ ๊ฐ์ ์ผ์น์ฑ์ ์ ๊ฒํ๊ณ , ๋ณด๋ค ๋์ ์ปค๋ฐ ๋ฌธํ๋ฅผ ํ์ฑํ๊ธฐ ์ํด ๋ฑ์ฅ**ํ๊ฒ ๋์์ต๋๋ค.
## ๊ธฐ๋ฅ
### 1. ๋ฉ์ธ ํ์ด์ง
![home_mock.gif](assets/readme/home_mock.gif)
![home_login.gif](assets/readme/home_login.gif)
**1-1. github ๋ก๊ทธ์ธ**
- github ๋ก๊ทธ์ธ ์ ์ฌ์ฉ์์ ๋ ํฌ์งํ ๋ฆฌ url์ ๋ ฅ์ด ๊ฐ๋ฅํฉ๋๋ค.
- ๋ก๊ทธ์ธ ์ ์๋ ์์ ๋ ํฌ์งํ ๋ฆฌ๋ก ์๋น์ค๋ฅผ ๋ฏธ๋ฆฌ ์ด์ฉํด๋ณผ ์ ์์ต๋๋ค.**1-2. ์๋น์ค ์ด์ฉ ๊ฐ๋ฅ ์ฌ๋ถ ํ์ธํ๊ธฐ**
- ํค๋์ ์ข์ธก ์๋จ ๋ถ๋ถ์๋ Github API์ ์ํ๋ฅผ ๋ณด์ฌ์ค๋๋ค.
Github์ Commit์ ํ์ธํด์ผํ๋ ์๋น์ค ํน์ฑ ์ Github API status์ ๋ฐ๋ผ ์๋น์ค ์ด์ฉ์ ํ ์ ์๋ ๊ฒฝ์ฐ๊ฐ ์์ด์ Github API status๊ฐ ์ ์์ธ ๊ฒฝ์ฐ์๋ง URL ์ ๋ ฅ(์ปค๋ฐ ๋ถ์)์ด ๊ฐ๋ฅํฉ๋๋ค.
- Github API status ๋ฒํผ ์ ํ ์ [https://www.githubstatus.com/](https://www.githubstatus.com/) ๋ก ์ด๋ํ์ฌ ์์ธ ๋ด์ญ์ ๋ณผ ์ ์์ต๋๋ค.**1-3. ํ์ฌ ๋์ ๊ฐ๋ฅํ Commit Type ํ์ธํ๊ธฐ**
- `remove` `docs` `style` `test`
- ๋ก๊ณ ์๋จ์๋ ํ์ฌ Commit Guardians์์ ๋ถ์ํ๊ณ ์๋ 4๊ฐ์ Commit Type์ ์ ์ ์์ต๋๋ค.**1-4. ์ปค๋ฐ ๋ถ์ ์์ํ๊ธฐ**
- ๋งจ ์ฒ์ ๋ณด์ด๋ ํ๋ฉด์ผ๋ก ์ฌ์ฉ์๊ฐ commit์ ๋ถ์๋ฐ๊ณ ์ถ์ Github Repository์ URL์ ์ ๋ ฅํ ์ ์์ต๋๋ค.
- URL ์ ๋ ฅ ํ Enterํค or Check the Quality ๋ฒํผ์ ๋๋ฌ ์ปค๋ฐ ๋ถ์์ ์์ํ ์ ์์ต๋๋ค.
- ์บ๋ฆญํฐ์ ์ค๋ช ์ ํตํด default branch์ Commit์ ๋ถ์ํ ์ ์๋ค๋ ๋ด์ฉ์ ์๋ ค์ค๋๋ค.
## 2. ์ปค๋ฐ ๋ฑ์ง ํ์ด์ง
![badge_readme.png](assets/readme/badge_readme.gif)
![b_review_faq.png](assets/readme/b_review_faq.gif)๋ฉ์ธ ํ์ด์ง์์ ์ปค๋ฐ ํ๋ฆฌํฐ ๋ถ์์ด ๋๋ ํ ๋ณด์ฌ์ง๋ ํ์ด์ง์ ๋๋ค.
**2-1. ์ ์์ ๋ฐ๋ฅธ ๋ฑ์ง ์ฐจ๋ณํ**
- ์ฌ์ฉ์์ ์ ์์ ๋ฐ๋ผ ๊ฐ๊ฐ ๋ค๋ฅธ ๋ฑ์ง๊ฐ ์ฃผ์ด์ง๋ฉฐ 4๊ฐ์ ๋ฑ์ง๋ก ๊ตฌ์ฑ๋์ด ์์ต๋๋ค.
์ ์ ๊ตฌ๊ฐ์ 80์ ์ด์, 50์ ์ด์, 30์ ์ด์, 30์ ๋ฏธ๋ง ์ผ๋ก ์ฑ์ ๋ฉ๋๋ค.
- `Copy your Badge` ๋ฒํผ์ ํตํด ์ฌ์ฉ์์ GitHub repository README ์ ๋ฑ์ง๋ฅผ ๋ถ์ฌ๋ฃ๊ธฐํ ์ ์๋ html ํ๊ทธ๋ฅผ ๋ณต์ฌํ ์ ์์ต๋๋ค.**2-2. Commit ํต๊ณ ๊ทธ๋ํ**
- Pie chart
- ์ค์์ ๊ฒ์ฌํ ์ปค๋ฐ์ ์ด ๊ฐ์๋ฅผ ๋ณผ ์ ์์ต๋๋ค.
- ๊ฒ์ฌํ ์ปค๋ฐ๋ค์ ์ปค๋ฐ ํ์ ๋ณ๋ก ๋ถ๋ฅํ์ฌ ๋น์จ์ ๋ํ๋์ต๋๋ค.
- Bar Chart
- ๊ฐ์ฅ ๋ง์ด ๊ธฐ์ฌํ ์์ 3๋ช ์ ์ ์ ํ์ฌ ๊ฐ์์ ์ปค๋ฐ์ ์ปค๋ฐ ํ์ ๋ณ๋ก ๋ถ๋ฅํด ๋ํ๋์ต๋๋ค.**2-3. ์ปค๋ฐ ํ๋ฆฌํฐ ์ต์ข ์ ์**
- 100์ ๋ง์ ์ ๊ธฐ์ค์ผ๋ก ์ฌ์ฉ์์ ์ ์๋ฅผ ๋ณผ ์ ์์ต๋๋ค.
- `View All Results` ๋ฒํผ์ ํตํด ์ปค๋ฐ ๋ถ์ ๊ฒฐ๊ณผ ํ์ด์ง๋ก ์ด๋ํ ์ ์์ผ๋ฉฐ ๊ฐ๊ฐ์ ์ปค๋ฐ ๋ง๋ค์ ์ ์๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.**2-4. FAQ**
- ๋ฉ์ธ ํ์ด์ง์์ ์ ๋ ฅ ๊ฐ๋ฅํ ๋ ํฌ์งํ ๋ฆฌ ์ปค๋ฐ ๋ฉ์์ง ํ์์ ์ ์ ์์ต๋๋ค.
- Commit Guardians ์์ ํ์ธํ๋ ์ปค๋ฐ ํ์ ๊ณผ ์ฑ์ ๋ฐฉ์์ ํ์ธํ ์ ์์ต๋๋ค.**2-5. ์ฌ์ฉ์์์ ์ํต์ ์ํ ์ด๋ฉ์ผ์ฃผ์์ GitHub ๋งํฌ**
- ํธํฐ์๋ ์ฌ์ฉ์๊ฐ Commit Guardians ์ ๋ํ ์์ด๋์ด๋ฅผ ์ ์ํ ์ ์๋ ์ด๋ฉ์ผ ์ฃผ์์ ํด๋น ํ๋ก์ ํธ์ GitHub ๋งํฌ๊ฐ ์์ต๋๋ค.
## 3. ์ปค๋ฐ ๋ถ์ ๊ฒฐ๊ณผ ํ์ด์ง
![scoreboard.png](assets/readme/scoreboard.gif)
์ปค๋ฐ ํ๋ฆฌํฐ๋ฅผ ๋ถ์ํ ๊ฐ ์ปค๋ฐ์ ๋ํ ์์ธ ์ ๋ณด๋ฅผ ์ ์ ์์ต๋๋ค.
- GitHub Owner์ Repository ์ด๋ฆ
- ์ปค๋ฐ ๋ฉ์์ง ํ์๋ณ๋ก ๋ถ๋ฅ๋ ๋น์จ
1. Prefix Style
2. Simple Text
3. Template Based Style- ๊ฐ ์ปค๋ฐ์ ์ ๋ณด
- COMMIT MESSAGE : ์ ํ ์ ํด๋น ์ปค๋ฐ์ GitHub ํ์ด์ง๊ฐ ์ด๋ฆฝ๋๋ค.
- CHANGES : ๋ณ๊ฒฝ๋ ํ์ผ ๊ฐฏ์ ๋ฟ๋ง ์๋๋ผ, -/+ ์ ๋ฌถ์์ Change ๋ก ์ ์ํ์ฌ ๋ง๋๊ทธ๋ํ๋ฅผ ํตํด ์ผ์น์จ์ ํ์ธํ ์ ์์ต๋๋ค.
- DATE : ๋ก์ปฌ๋ ์ง์ ์๊ฐ์ ๊ธฐ์ค์ผ๋ก ํ์ธํ ์ ์์ต๋๋ค.
- SHA : ์ ์ฒด SHA ๊ฐ์ ๋ณต์ฌํ๊ฑฐ๋ 7์๋ฆฌ๋ง ๋ณต์ฌํ ์ ์์ต๋๋ค.
## ๊ธฐ์ ์คํ
| ์ญํ | ์ข ๋ฅ |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Library | ![React](https://img.shields.io/badge/React-61DAFB?style=for-the-badge&logo=React&logoColor=white) |
| Bundler | ![VITE](https://img.shields.io/badge/VITE-f88afc?style=for-the-badge&logo=Vite&logoColor=white) |
| Programming Language | ![JavaScript](https://img.shields.io/badge/JavaScript-FFD93E.svg?style=for-the-badge&logo=JavaScript&logoColor=white) |
| Styling | ![tailwindcss](https://img.shields.io/badge/tailwindcss-61DAFB?style=for-the-badge&logo=tailwindcss&logoColor=white) |
| Data Fetching | ![Axios](https://img.shields.io/badge/Axios-5A29E4?style=for-the-badge&logo=Axios&logoColor=white) |
| State Management | ![zustand](https://img.shields.io/badge/zustand-FF4154?style=for-the-badge&logo=zustand&logoColor=white) |
| Formatting | ![ESLint](https://img.shields.io/badge/ESLint-4B3263?style=for-the-badge&logo=eslint&logoColor=white) ![Prettier](https://img.shields.io/badge/Prettier-F7B93E?style=for-the-badge&logo=prettier&logoColor=white) |
| Package Manager | ![npm](https://img.shields.io/badge/npm-2C8EBB?style=for-the-badge&logo=npm&logoColor=white) |
| Version Control | ![Git](https://img.shields.io/badge/git-%23F05033.svg?style=for-the-badge&logo=git&logoColor=white) ![GitHub](https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge&logo=github&logoColor=white) |GitHub ์ด์ฉ์์ ๋๋ถ๋ถ์ด PC๋ฅผ ํตํ ์น ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์, REACT๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์น ํ์ด์ง๋ฅผ ๊ฐ๋ฐํ์์ต๋๋ค. ๋ํ, Axios๋ฅผ ํ์ฉํ์ฌ GitHub API์์ ๋ง์ ํต์ ์ ์ํํ๊ฒ ์ฒ๋ฆฌํจ์ผ๋ก์จ ๋ฐ์ดํฐ ํ์นญ ๋ฐ ๊ด๋ฆฌ๋ฅผ ํจ์จ์ ์ผ๋ก ์ํํ ์ ์์์ต๋๋ค.
### ์ฃผ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฆฌ
- `diff-match-patch` : ๊ตฌ๊ธ์ Neil Fraser๊ฐ ๊ฐ๋ฐํ ์คํ์์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก, ํ ์คํธ์ ์ฐจ์ด์ (diffs)์ ๊ณ์ฐํ๊ณ ํจ์น๋ฅผ ์์ฑ ๋ฐ ์ ์ฉํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ๋๋์ ์ปค๋ฐ์ ์ ํํ๊ณ ๋น ๋ฅด๊ฒ ๋ถ์ํ์ฌ ์ฝ๋ ๋ณ๊ฒฝ ์ฌํญ์ ํ์ธํ๋ ๋ฐ ์ฌ์ฉํ์์ต๋๋ค.
- `idb-keyval` : IndexedDB๋ฅผ ๊ฐํธํ๊ฒ ์ฌ์ฉํ ์ ์๊ฒ ํด์ฃผ๋ ๊ฒฝ๋ ์คํ์์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก, key-value ํ์์ ๋ฐ์ดํฐ ์ ์ฅ ๋ฐ ์กฐํ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. zustand ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํจ๊ป ์ฌ์ฉํ์ฌ ์ํ๋ฅผ ๋ธ๋ผ์ฐ์ ์ IndexedDB์ ์ ์ฅํ ์ ์์ด ๋๋์ ์ํ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ณ , ์ฌ์ฉ์ ๊ฒฝํ์ ํฅ์์ํฌ ์ ์์์ต๋๋ค.
## Git Commit ์ปจ๋ฒค์
**- Commit Type**
```
type: titlebody
```
**- Commit ๋ฉ์์ง ์ข ๋ฅ ์ค๋ช **
| ์ ๋ชฉ | ๋ด์ฉ |
| -------- | ---------------------------------------- |
| feat | ์๋ก์ด ๊ธฐ๋ฅ์ ๋ํ ์ปค๋ฐ |
| fix | ๋ฒ๊ทธ ์์ ์ ๋ํ ์ปค๋ฐ |
| chore | ๋น๋ ์์ ์ ๋ํ ์ปค๋ฐ |
| docs | ๋ฌธ์ ์์ ์ ๋ํ ์ปค๋ฐ |
| style | ์ฝ๋ ์คํ์ผ ํน์ ํฌ๋งท ๋ฑ์ ๊ดํ ์ปค๋ฐ |
| refactor | ์ฝ๋ ๋ฆฌํฉํ ๋ง์ ๋ํ ์ปค๋ฐ |
| design | css ๋์์ธ ๊ด๋ จ์ ๋ํ ์ปค๋ฐ |
| test | ํ ์คํธ ์ฝ๋ ์ถ๊ฐ, ์ญ์ , ๋ณ๊ฒฝ์ ๋ํ ์ปค๋ฐ |
| remove | ๋ถํ์ํ ํ์ผ์ด๋ ๋ก์ง ์ญ์ ์ ๊ดํ ์ปค๋ฐ |
# ๐ค ๊ณ ๋ฏผํ ๋ถ๋ถ
## 1. ์ปค๋ฐ ํ์ ํํฐ๋ง
์ข์ ์ปค๋ฐ์ธ์ง๋ฅผ ํ๋จํ๊ธฐ ์ํด ์ปค๋ฐ์ ๋ฉ์์ง์ ์ค์ ๋ณ๊ฒฝ ๋ด์ฉ์ ๋งฅ๋ฝ์ด ์ผ์นํ์ง ๊ฒ์ฌ๊ฐ ํ์ํ์ต๋๋ค. ์๋ฅผ ๋ค์ด ์ปค๋ฐ ๋ฉ์์ง์ โtest: ํ ์คํธ ์ฝ๋ ์์ โ ์ด๋ผ๊ณ ์ ํ์์ผ๋ ๋ณ๊ฒฝ ๋ด์ฉ์ ํด๋น ๋ด์ฉ๊ณผ ๊ด๋ จ ์๋ ๋ถ๋ถ์ด ํฌํจ๋๋ ๊ฒฝ์ฐ์๋ ์ปค๋ฐ์ ์ง์ ๋ฎ์ถ๋ค๊ณ ํ๋จ๋์ด์ผ ํฉ๋๋ค.
Problem
**์ปค๋ฐ ๋ถ์์ ์ํ ๊ธฐ์ค ์ค์ ์ ๋ํ ์ด๋ ค์**
1. ์ปค๋ฐ ๋ฉ์์ง ํ์์ ๋น์ผ๊ด์ฑ
์ปค๋ฐ ๋ฉ์์ง์ ๋ํ ์ปจ๋ฒค์ ์ด ์กด์ฌํ์ง๋ง ํ๋ก์ ํธ๋ง๋ค ๋ค๋ฅธ ๊ท์น์ ์ ์ฉํ๊ฑฐ๋ ์ปจ๋ฒค์ ์ ๊ฐ์ ํ์ง ์์ ๊ฒฝ์ฐ๊ฐ ๋ง์๊ณ ๋์ผํ ์ปค๋ฐ ํ์ ์ด์ด๋ ์์ฑ์์ ์คํ์ผ์ ๋ฐ๋ผ ๋ฉ์์ง ํ์์ด ๋ฌ๋์ต๋๋ค.
2. ์ปค๋ฐ ๋ฉ์์ง์ ์ฝ๋ ๋ณ๊ฒฝ ๋ด์ฉ ๊ฐ์ ๋ชจํธํ ๊ธฐ์ค
์๋ฅผ ๋ค์ด, ์ปค๋ฐ ๋ฉ์์ง ํ์ ์ด โfixโ ์ด๊ณ CSS ๊ด๋ จ UI ๋ณ๊ฒฝ์ด ๋ ๊ฒฝ์ฐ์๋ โfixโ ์ธ์ง โdesignโ์ธ์ง ํ๋จํ๋ ๊ธฐ์ค์ด ๋ชจํธํ์ต๋๋ค. โrefactorโ, โfeatโ ๋ฑ์ ๊ฒฝ์ฐ์๋ ํด๋น ์ปค๋ฐ์ ์ฝ๋ ๋ณ๊ฒฝ ๋ด์ฉ๋ง์ ๋ณด๊ณ ์ ํํ๋ ๊ท์น๋ง์ผ๋ก ์ผ์น์ฑ์ ํ๋จํ๊ธฐ์๋ ์ด๋ ค์ ์ต๋๋ค.
3. ๋์ผํ ํ์ ์ด์ง๋ง ๋ค์ํ ํด์
๊ฐ์ ๋จ์ด์ด์ง๋ง ๋ค์ํ ์๋ฏธ๋ก ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ๋น๋ฒํ์ต๋๋ค. ์ปค๋ฐ ๋ฉ์์ง ํ์ ์ด โstyleโ์ผ ๋ ์ฝ๋ ํฌ๋งท ๋ณ๊ฒฝ์ ๋ํ๋ด๋ ๊ฒฝ์ฐ๋ ์์ง๋ง ๋์์ธ์ ์ธ ์คํ์ผ ๋ณ๊ฒฝ์ ์ฌ์ฉ๋๊ธฐ๋ ํ์ผ๋ฉฐ โchoreโ์ธ ๊ฒฝ์ฐ์๋ ๋น๋์ ๊ด๋ จ ์์ ๋ง์ ๋ํ๋ด๋ ์๋ฏธ๋ก ์ฐ์ด๊ฑฐ๋ ์์ํ ์์ ์ ์๋ฏธ๊น์ง ํฌํจํ์ฌ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๋ ์์์ต๋๋ค.
Analysis
**1. ์์ฑ์์ ์คํ์ผ์ ๋ฐ๋ฅธ ์ปค๋ฐ ๋ฉ์์ง ํ์ ๋ถ์**
์ปค๋ฐ ๋ฉ์์ง๋ฅผ ์ธ ๊ฐ์ง ์ฃผ์ ํ์์ผ๋ก ๋ถ๋ฅํ์ต๋๋ค. ๋ค์ํ ํ์์ ์ปค๋ฐ ๋ฉ์์ง๊ฐ ์ ๋ ฅ๋๋๋ผ๋ ์ง์ ๋ ํ์์ ๋ฐ๋ฅผ ๊ฒฝ์ฐ ์ปค๋ฐ ํ๋ฆฌํฐ๋ฅผ ๋ถ์ํ ์ ์๋๋ก ํ์ต๋๋ค.
- ์ ๋ ฅ ๊ฐ๋ฅํ ์ปค๋ฐ ๋ฉ์์ง ํ์ ์ง์ \*๋์๋ฌธ์ ๊ตฌ๋ถ์ด ์์ต๋๋ค. (Case-insensitive)
1. ํ๋ฆฌ ํฝ์ค ์คํ์ผ (Prefix Style)
`type(scope): subject`
์์: feat(auth): ๋ก๊ทธ์ธ API ์ฐ๋
2. ์ผ๋ฐ ํ ์คํธ ์คํ์ผ (Simple Text Style)
`type subject`
์์: Add ๋ก๊ทธ์ธ API ์ฐ๋
3. ํ ํ๋ฆฟ ๊ธฐ๋ฐ ์คํ์ผ (Template Based Style)
`[type] subject`
์์: [ADD] ๋ก๊ทธ์ธ API ์ฐ๋
**2. ๋ชจํธํ ์ปค๋ฐ ํ์ ์ ๋ฌธ์ ํด๊ฒฐ์ ์ํ commit type ํํฐ๋ง**
| ์ปค๋ฐ ๋ด์ฉ[์นดํ ๊ณ ๋ฆฌ] | Type | ์ถ์ /๋ถ์ ์์ธ |
| ------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------- |
| 1. ๊ธฐ๋ฅ์ ์ถ๊ฐ | feat, make, implement | |
| 2. ํ์ผ์ ์ญ์ | remove, removed, removes, delete, deletes, deleted, erase, erases, erased, discard, | |
| 3. ๋ฌธ์์์ ๋ง | docs, doc, documentation, readme | ํ์ผํ์ฅ์๋ช (.md, .mdx, .docs, ...) |
| 4. ๋ฒ๊ทธ ์์ | fix, fixed | |
| 5. ๋ฆฌํฉํ ๋ง | refactor | |
| 6. ์ฝ๋ ํฌ๋ฉงํ | style, format, beautify, "reformatโ | |
| 7. ๋์์ธ ์คํ์ผ๋ง๋ง | design, css | ํ์ผํ์ฅ์๋ช (.css, .scss) / tailwind (โฆ) |
| 8. ํ ์คํธ๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ๋ณ๊ฒฝํ๋ ์ฝ๋ | test, tests, verify, unittest | ํ์ผํ์ฅ์ ๋ฐ ์๋๊ฒฝ๋ก (.jest, ...) |
| 9. ๋น๋ ๋ฐ ์ค์ ํ์ผ ์์ (ํ๋ก์ ํธ์ ๊ธฐ๋ฅ๊ณผ ์ง์ ์ ์ผ๋ก ์ฐ๊ด x) | chore | |"fix", "feat", "refactorโ ์ ๊ฐ์ ์ปค๋ฐ ํ์ ์ ์ฝ๋ ๋ณ๊ฒฝ ๋ด์ฉ์ ๊ธฐ๋ฐ์ผ๋ก ๋ถ์ํ ์ ์๋ ๊ฒฝ์ฐ๋ ์์์ง๋ง ๋๋ถ๋ถ์ ๋ช ํํ ๊ธฐ์ค์ ๊ฐ์ง๊ณ ํ๋จํ๊ธฐ ์ด๋ ค์ด ๊ฒฝ์ฐ๊ฐ ๋ง์์ต๋๋ค. ์ปค๋ฐ ๋ฉ์์ง์ ๋ด์ฉ ๋ฟ๋ง ์๋๋ผ ์ ์ฒด ์ฝ๋์ ๋ด์ฉ๋ ํ์ ์ด ๋์ด์ผ ์ปค๋ฐ ๋ฉ์์ง์ ์ฝ๋ ๋ณ๊ฒฝ ๋ด์ฉ์ ์ผ์น์ฑ์ ์ ์ ์์๊ธฐ ๋๋ฌธ์ ํ๋์ ์ปค๋ฐ์ ๋ณ๊ฒฝ ๋ด์ฉ(diff)์ผ๋ก๋ ์ข์ ์ปค๋ฐ์ธ์ง ์๊ธฐ ์ด๋ ค์ ์ต๋๋ค.
๋ฐ๋ผ์ ๋ถ์ ๊ฐ๋ฅ์ฑ์ด ๋์ ์ปค๋ฐ ํ์ ์ ํํฐ๋งํ์ฌ ๋ชจํธ์ฑ์ ์ต์ํํ๊ณ ์ผ๊ด๋ ํ๊ฐ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํ์ต๋๋ค.
๋๋ถ๋ถ์ ์คํ์์ค ํ๋ก์ ํธ์์ ์๋ฏธ๊ฐ ๋ช ํํ ๊ตฌ๋ถ๋๊ณ ์ค์ ์ฝ๋์ ๋ณ๊ฒฝ ๋ด์ฉ๊ณผ ์ปค๋ฐ ๋ฉ์์ง ๊ฐ์ ์ผ์น์ฑ์ ํ๋จํ๋ ๊ธฐ์ค์ ์ธ์ธ ์ ์๋ค๋ ์ ์์ `style`, `remove`, `docs`, `test` 4๊ฐ์ง ํ์ ์ผ๋ก ๋ถ์ ๋์์ ์ ํํ์ต๋๋ค.
**3. ์ปค๋ฐ ๋ฉ์์ง ํ์ ๊ณผ ์๋ฏธ์ ๋ํ ๋ช ํํ ๊ธฐ์ค ์ค์ **
๋์ผํ ํ์ ์ด์ง๋ง ๋ค์ํ ํด์์ด ๋ ์ ์๋ ๋ฌธ์ ๋ฅผ ๊ฐ์ ํ๊ธฐ ์ํด 4๊ฐ์ง ํ์ ์ด ์ค์ ๋ก ์ด๋ค ์๋ฏธ๋ก ์ฐ์ด๊ณ ๊ทธ์ ๋ฐ๋ฅธ ์ฝ๋ ๋ณ๊ฒฝ ์ฌํญ์ ์ด๋ป๊ฒ ๋๋์ง ๋ถ์ํ์ต๋๋ค.
๊ฐ ํ์ ๋ง๋ค ๊ณตํต๋ ์ฝ๋ ๋ณ๊ฒฝ ์ฌํญ์ ์ฐพ๊ณ ์ผ๋ฐ์ ์ผ๋ก ์์ฃผ ์ฐ์ด๋ ์๋ฏธ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ช ํํ ๊ธฐ์ค์ ์ค์ ํ์ต๋๋ค. ์๋ฅผ ๋ค์ด, style ํ์ ์ HTMLํ๊ทธ์ ์ธ์ด ์์ฑ ์ถ๊ฐ, configํ์ผ ์์ , ์ฐ์ด์ง ์์ ์ฝ๋๋ฅผ ์ญ์ ํ ๊ฒฝ์ฐ ๋ฑ ํ๋จ ๊ธฐ์ค์ ์ธ์ฐ๊ธฐ ์ด๋ ค์ด ์ผ์ด์ค๋ณด๋ค๋ ์ผ๋ฐ์ ์ผ๋ก ์ฐ์ด๋ ์ฝ๋ ํฌ๋งท์ ๊ด๋ จํ ์์ ์ ๋ํด ๋ถ์ํ์ฌ ๊ธฐ์ค์ ์ค์ ํ์ต๋๋ค.
**- Commit Guardians๊ฐ ํ์ธํ๋ ์ปค๋ฐ ํ์ ๊ณผ ๊ธฐ์ค**
- remove
- ํ์ผ ๋ฐ ํด๋, ์ฝ๋๋ฅผ ์ญ์ ํ ์ปค๋ฐ
- ๋ณ๊ฒฝ์ฌํญ์ ์ญ์ ํ ๋ถ๋ถ๋ง ํฌํจ๋๋์ง ํ์ธํฉ๋๋ค.
- ํด๋นํ์ง ์๋ ๊ฒฝ์ฐ ์์
- ํ์ผ ์ญ์ ์ ์ฝ๋ ์์ ์ ๊ฐ์ด ์ปค๋ฐํ์ ๊ฒฝ์ฐ์ ํด๋นํฉ๋๋ค.
- ๋ณ๊ฒฝ์ฌํญ์ ์ฝ๋์ ์ถ๊ฐ๋ ๋ถ๋ถ์ด ํฌํจ๋ ๊ฒฝ์ฐ์ ํด๋นํฉ๋๋ค.
- docs
- ๋ฌธ์ ์์ ๋ง์ ํ ์ปค๋ฐ
- ๋ฌธ์์ ์ฌ์ฉ๋๋ ํ์ผ๋ง ํฌํจ๋๋์ง ํ์ธํฉ๋๋ค.
- ์ด๋ฏธ์ง ํ์ผ -ย `.img`,ย `.png`,ย `.jpeg`,ย `.svg`,ย `.ai`
- ๊ธฐํ ๋ฌธ์ ํ์ผ - `.pdf` ,`.docs`,ย `.md`,ย `.mdx`,ย `.rst`
- ํด๋นํ์ง ์๋ ๊ฒฝ์ฐ ์์
- ๋ฌธ์ ํ์ผ๊ณผ ์์ค ์ฝ๋ ํ์ผ์ ์์ ์ฌํญ์ ๊ฐ์ด ์ปค๋ฐํ์ ๊ฒฝ์ฐ์ ํด๋นํฉ๋๋ค.
- style
- ์ฃผ๋ก ์ฝ๋ ํฌ๋งคํ , ๋ค์ฌ ์ฐ๊ธฐ, ์ฝ๋ ์ ๋ ฌ ๋ฑ ์ฝ๋์ ๋์์ ์ํฅ์ ์ฃผ์ง ์๋ ์์ ์ ํ ์ปค๋ฐ
- ํ์ผ๋ช ์ style์ ๋ํ๋ด๋ ๋จ์ด ํ์ธ ("prettier", "eslint", "configโ)
- ๋ณ๊ฒฝ์ฌํญ์ ํน์๋ฌธ์(`,` , `'` , `"` , `\n` , `;` ๋ฑ)๋ง ์์ ๋๋์ง ํ์ธํฉ๋๋ค.
- ๋ณ๊ฒฝ์ฌํญ์ด `console.log` ์ ๊ด๋ จ๋๋์ง ํ์ธํฉ๋๋ค.
- ์์๋ค์ ์์น ๋ณ๊ฒฝ ํ์ธํฉ๋๋ค.
- tailwind className์ ์์ฑ ์์๋ฅผ ํ์ธํฉ๋๋ค.
- ๊ฐ์ฒด ์์ฑ๋ค์ ์์๋ฅผ ํ์ธํฉ๋๋ค.
- ํด๋นํ์ง ์๋ ๊ฒฝ์ฐ ์์
- ๋ณ์๋ช ๋ณ๊ฒฝ ๋ฑ style ์ฒดํฌ ์ฌํญ์ ๋ฒ์ด๋ ๊ฒฝ์ฐ์ ํด๋นํฉ๋๋ค.
- test
- ํ ์คํธ๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ๋ณ๊ฒฝํ ์ปค๋ฐ
- ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ ํ์ผ๋ง ํฌํจ๋๋์ง ํ์ธํฉ๋๋ค.
- `test`, `tests`, `spec`, `mock`
- ํด๋นํ์ง ์๋ ๊ฒฝ์ฐ ์์
- test ๊ฒ์ฆ ํค์๋๊ฐ ํ์ผ๋ช ์ ์๊ฑฐ๋ ๋์ ์์นํ์ง ์์ ๊ฒฝ์ฐ์ ํด๋นํฉ๋๋ค.
- `a/src/compiler-worker.ts`
- `a/mock_feed_repository_impl.dart`
- ํ ์คํธ ์ฝ๋ ๊ด๋ จ ํ์ผ์ด ์๋ ์ค์ ํ์ผ ๋ฑ์ ์์ ์ฌํญ์ ๊ฐ์ด ์ปค๋ฐํ์ ๊ฒฝ์ฐ์ ํด๋นํฉ๋๋ค.ํ์ฌ๋ ๋ณ๊ฒฝ ๋ด์ฉ๊ณผ ์ปค๋ฐ ๋ฉ์์ง๋ฅผ ํ๋จํ ๋ ๋ช ํํ ๋์์ด ๊ฐ๋ฅํ ํ์ ๋ง์ ์ฐ์ ์ ์ผ๋ก ์ ํํ์ผ๋ฉฐ ์ถํ ํํฐ๋ง ๊ธฐ์ค์ ํ์ฅํ์ฌ feat, fix ๋ฑ์ ํฌํจํ๊ธฐ ์ํ ์ถ๊ฐ ๊ฐ์ ์ ์งํํ ์์ ์ ๋๋ค.
## 2. API ๊ด๋ จ ๋ฆฌ์์ค ์ต์ ํ
Problem |
REST API๋ฅผ ์ด์ฉํ์ฌ ์์ฒญ์ ํ ๊ฒฝ์ฐ, ์๋ํฌ์ธํธ๋ง๋ค ์ ๋ฌ๋ฐ๋ ๋ฐ์ดํฐ ํ์์ด ๊ณ ์ ๋์ด ์์ด ๋ถํ์ํ ์ ๋ณด๋ ํจ๊ป ์ ๋ฌ๋ฉ๋๋ค. ์ด๋ก ์ธํด ๋คํธ์ํฌ, ๋ฉ๋ชจ๋ฆฌ, ํ๋ก์ธ์ ๋ฑ์ ๋ฆฌ์์ค๊ฐ ๋ญ๋น๋ฉ๋๋ค. ์ค์ ๋ก, ๋ง์ ์์ ์ปค๋ฐ์ ์์ฒญํ ์๋ก ๋ฒ๋ฒ ์๊ณผ ๋๊ธฐ ์๊ฐ์ด ์ ์ ์ฆ๊ฐํ๋ ๊ฒ์ ์ฒด๊ฐํ์ต๋๋ค.
Analysis |
GitHub๋ ์ฌ์ฉ์์ ์์ฒญ์ ๋ณด๋ค ์ ์ฐํ๊ฒ ์ฒ๋ฆฌํ ์ ์๋๋ก GraphQL์ด๋ผ๋ ๋ฐ์ดํฐ ์ฟผ๋ฆฌ ์ธ์ด๋ฅผ ์ฌ์ฉํ API๋ฅผ ์ ๊ณตํ๊ณ ์์ต๋๋ค. ํ์ํ ์ ๋ณด๋ง ์คํค๋ง์ ๋ช ์ํ์ฌ ์์ฒญํ ์ ์๊ธฐ ๋๋ฌธ์, ์ฌ์ฉ์๋ ๋์ญํญ๊ณผ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ฝํ ์ ์์ต๋๋ค.
ํ์ง๋ง GraphQL์ ์ฌ์ฉํ ์ ์๋ ๋ ๊ฐ์ง ์ด์๊ฐ ์์์ต๋๋ค.
1. ํ ํฐ ๊ธฐ๋ฐ ํ์ด์ง๋ค์ด์ (Token-Based Pagination)
GraphQL์ ํ์ด์ง๋ค์ด์ ์ ์ง์ํ์ง๋ง, ํ์ด์ง ๋ฒํธ ๊ธฐ๋ฐ์ด ์๋ ํ ํฐ ๊ธฐ๋ฐ์ ์ฌ์ฉํฉ๋๋ค. ์ด๋ก ์ธํด ์์ฐจ์ ์ผ๋ก ๋ค์ ํ์ด์ง์ ๋ด์ฉ์ ์์ฒญํด์ผ ํ๊ณ , REST API์ฒ๋ผ ๋น๋๊ธฐ์ ์ผ๋ก ์ปค๋ฐ ๋ชฉ๋ก์ ๋ณ๋ ฌ๋ก ์์ฒญํ ์ ์์ด ํ์ด์ง ๋ก๋ฉ ์๊ฐ์ด ํฌ๊ฒ ์ฆ๊ฐํ์ต๋๋ค.
2. ์ปค๋ฐ ๋ณ๊ฒฝ์ฌํญ ๋ฏธ์ ๊ณต
GraphQL์ ์ปค๋ฐ์ ๋ณ๊ฒฝ ์ฌํญ ์ ๊ณตํ์ง ์์์ต๋๋ค.Result |
๊ธฐ์กด REST API๋ก ์์ฒญํ๋ ๋ฐ์ดํฐ๋ฅผ GraphQL๋ก ์ ํํ์ฌ ๋ฆฌ์์ค์ ์ฌ์ฉ์ ์ต์ ํ ํ๋ ค ํ์์ง๋ง, ๊ธฐ๋ฅ์ด ์ ํฌ ํ๋ก์ ํธ์ ์ ์ฉํ ์ ์์ด ์ฌ์ฉํ ์ ์์์ต๋๋ค.
## 3. GitHub API Rate Limit ํํผ๋ฅผ ์ํ ํ ํฐ ๋กํ ์ด์ ๊ตฌํ
[Github API Rate Limit ์ฐธ๊ณ ๋งํฌ](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28#primary-rate-limit-for-authenticated-users)
Problem |
### **Github API ํธ์ถ ์ธ์ฆ๋ ํ ํฐ ์๊ฐ๋น 5,000ํ ์ ํ**
Github API ์ ์์กด๋๊ฐ ๋์ ํ๋ก์ ํธ์๊ธฐ์ **Github API ์์ฒญ ์ ํ ์๋ ์ ํฌ ํ๋ก์ ํธ์์ ์น๋ช ์ **์ด์์ต๋๋ค. ์ปค๋ฐ ๋ถ์ ๋ก์ง์ API ํธ์ถ์ ํตํด ํ์ํ ๊ฐ๋ค์ ๋ถ๋ฌ์ค๊ณ , ์ปค๋ฐ ๋ฉ์์ง์ ์ปค๋ฐ ํ์ ์ ๋ถ์ํ ์ดํ, ๊ฒ์ฌ๊ฐ๋ฅํ ์ปค๋ฐ ํ์ ๋ค๋ง์ ํํฐ๋งํฉ๋๋ค. ํํฐ๋ง ํ ์ปค๋ฐ์ `owner`, `repo`, `sha` ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก API ํธ์ถ์ ํตํด ์ฝ๋์ ์์ ์ ๋ณด์ธ diff ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
ํนํ๋ ํ ์ธ์ฆ๋ ํ ํฐ ์๊ฐ๋น 5,000ํ๊ฐ ์ต๋์๊ธฐ ๋๋ฌธ์ ์๋ฅผ ๋ค์ด, [facebook/react](https://github.com/facebook/react) ์ ๊ฐ์ด ์ปค๋ฐ ๊ฐฏ์๊ฐ 19,000๊ฐ ์ด์์ ๊ฒฝ์ฐ 19,000/100 = **190**ํ API ํธ์ถ์ ํตํด ์ ์ฒด ์ปค๋ฐ์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๊ณ , ๊ฒ์ฌ๊ฐ๋ฅํ ์ปค๋ฐ์ ์ถ์ถํ๋ฉด (2024.12.25 ์ผ ๊ธฐ์ค์ผ๋ก) 1450 ๊ฐ ์ด๋ฏ๋ก, **1450**ํ์ diff API ํธ์ถ์ ๋ ํ๊ฒ ๋ฉ๋๋ค.
์ฆ, facebook/react ๋ 190 + 1450 = **1640**ํ์ API ํธ์ถ์ ํ๊ฒ ๋ฉ๋๋ค. ๊ทธ๋ผ ์ฌ์ค 2, 3๋ฒ์ facebook/react ์ ๋์ ๋ ํฌ์งํ ๋ฆฌ๋ง ์กฐํ๋ฅผ ํ๋๋ผ๋ GitHub API Rate Limit ๋ฅผ ๋ชจ๋ ์์งํ๊ฒ ๋๋ ๋ฌธ์ ๊ฐ ์์์ต๋๋ค.
๋ํ, ๊ฒ์ฌ๊ฐ๋ฅํ ์ปค๋ฐ ํ์ ์ด ์ถ๊ฐ๊ฐ ๋๋ค๋ฉด ๋ ๋ง์ API ํธ์ถ์ ์์ํ ์ ์์ต๋๋ค. ๋ง์ฝ ๋ชจ๋ ์ปค๋ฐ์ด ๊ฒ์ฌ ๋์์ด๋ผ๋ฉด ์ปค๋ฐ ๊ฐ์์ 101% ๋งํผ API ํธ์ถ์ ํ๊ฒ ๋ฉ๋๋ค.
Analysis |
**์ธ์ฆ๋ ํ ํฐ ๋กํ ์ด์ ๋ฐฉ์ ๊ฒํ **
GitHub API ์์ฒญ ์ ํ์ ๊ฐ ํ ํฐ๋ง๋ค ๋ ๋ฆฝ์ ์ผ๋ก ์ ์ฉ๋๊ณ ์์ต๋๋ค. API ํธ์ถ์ด ๋ง์ ์์ ์์ Rate Limit ๋ฅผ ์ด๊ณผํ๋ ๋ฌธ์ ๊ฐ ๋น๋ฒํ๊ฒ ๋ฐ์ํ๊ณ , ํ๋์ ํ ํฐ๋ง์ผ๋ก๋ ํ๋ก์ ํธ ์๊ตฌ ์ฌํญ์ ์ถฉ์กฑํ ์ ์์์ต๋๋ค. ์ฌ๋ฌ GitHub Personal Access Token(PAT)์ ํ๊ฒฝ ๋ณ์๋ก ๋ฐ์ ์ด๋ฅผ ํจ์จ์ ์ผ๋ก ๋กํ ์ด์ ํ๋ ๋ฐฉ์์ ์ฐจ์ฐ์ ์ผ๋ก ๊ฒํ ํ์ต๋๋ค.
Action |
**ํ ํฐ ๋กํ ์ด์ ๋ก์ง ๊ตฌํํ์ฌ ์ผ์์ ์ผ๋ก ํด๊ฒฐํ์ต๋๋ค**. ์ฌ๋ฌ ํ ํฐ์ tokenStates ๋ฐฐ์ด๋ก ๊ด๋ฆฌํ๋ฉฐ, ๊ฐ ํ ํฐ์ ๋จ์ ํธ์ถ ๊ฐ๋ฅ ํ์(remaining)๋ฅผ ์ถ์ ํ๋๋ก ์ค๊ณํ์ต๋๋ค. API ํธ์ถ ์, ๋จ์ ์์ฒญ๋์ด ๊ฐ์ฅ ๋ง์ ํ ํฐ์ ์ ํํด Rate Limit ์ด๊ณผ๋ฅผ ๋ฐฉ์งํ์ต๋๋ค. ํธ์ถ ํ, GitHub API์ ์๋ต ํค๋์์ ๋ฐํ๋๋ X-RateLimit-Remaining ๊ฐ์ ์ฌ์ฉํด ํ ํฐ ์ํ๋ฅผ ์ ๋ฐ์ดํธํ์ต๋๋ค. `getBestGithubToken()` ํ์ฌ ์ฌ์ฉ ๊ฐ๋ฅํ ํ ํฐ ์ค ๊ฐ์ฅ ๋ง์ ๋จ์ ์์ฒญ ํ์๋ฅผ ๊ฐ์ง ํ ํฐ์ ๋ฐํํ๋๋ก ํ์ต๋๋ค. `updateTokenState()` ํธ์ถ ํ, ์ฌ์ฉํ ํ ํฐ์ ์ํ๋ฅผ ์ต์ ์ํ๋ก ์ ๋ฐ์ดํธํ์ฌ ํ ํฐ์ ๋ค๊ณ ์ฌ ๋ ์ต์ limit ์ ๊ฐ์ ธ์ฌ ์ ์๋๋ก ํฉ๋๋ค.
```jsx
const GITHUB_REQUEST_LIMIT = 5000;const tokenStates = [
{
token: import.meta.env.VITE_GITHUB_TOKEN,
remaining: GITHUB_REQUEST_LIMIT,
},
...
];const getBestGithubToken = () => {
tokenStates.sort((a, b) => b.remaining - a.remaining);return tokenStates[0].token;
};const updateTokenState = (token, remaining) => {
const tokenState = tokenStates.find((t) => t.token === token);if (tokenState) {
tokenState.remaining = remaining;
}
};export { getBestGithubToken, updateTokenState };
```Result |
์ฌ๋ฌ ํ ํฐ์ ํ์ฉํ ๋กํ ์ด์ ๋ฐฉ์์ผ๋ก, GitHub API ์์ฒญ ์ ํ์ ๋๋ฌํ์ง ์๊ณ ๋๊ท๋ชจ ๋ฐ์ดํฐ๋ฅผ ์์ ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์์์ต๋๋ค. ๊ทธ๋์ facebook/react ์ฒ๋ผ ์ปค๋ฐ์ด ๋ง์ ๋ ํฌ์งํ ๋ฆฌ์์๋ ๋ถ์์ด ์ค๋จ๋์ง ์๊ณ ์๋ฃ๋ ์ ์์์ต๋๋ค. ํ ํฐ์ด ์ถ๊ฐ๋ ๊ฒฝ์ฐ tokenStates ๋ฐฐ์ด์๋ง ์ถ๊ฐํ๋ฉด ์๋์ผ๋ก ์ ์ฉ๋๋๋ก ์ค๊ณํ์ต๋๋ค.
## 4. GitHub ๋ก๊ทธ์ธ ๊ตฌํ
Problem |
๊ฒ์ฌํ ์ปค๋ฐ์ด ๋จ์ผ ํ ํฐ์ ์์ฒญ๋์ธ 5000๊ฐ ์ด์์ ๋ ํฌ์งํ ๋ฆฌ๋ ์ ์์ ์ผ๋ก ๋ชจ๋ ๊ฒ์ฌํ ์ ์๋๋ก ํ ํฐ ๋กํ ์ด์ ๋ฐฉ์์ ๊ตฌํํ์์ต๋๋ค. ๋ฐฐํฌ๋ฅผ ํ์ง ์๊ณ ๋ก์ปฌ์์๋ง ์ด์์ ํ๋ค๋ฉด ํ ํฐ ๋กํ ์ด์ ๋ฐฉ์์ผ๋ก๋ ๋ฌธ์ ๊ฐ ์๊ฒ ์ง๋ง, ๋ฐฐํฌํ์ฌ ์๋น์ค๋ฅผ ํ๋ค๋ฉด ๋ง์ ์ฌ๋๋ค์ด ์ด์ฉํ๋ API ์ฌ์ฉ๋์ด ์ ํฌ๊ฐ ์๋์ผ๋ก ์ถ๊ฐํ ํ ํฐ์ ์์ฒญ๋์ ๊ฐ๋นํ ์ ์์ ๊ฒ์ ๋๋ค.
Analysis |
์ ์ ์ ์ ๊ทผ์ฑ์ ์ํด ๋ก๊ทธ์ธ ๊ธฐ๋ฅ์ ์ถ๊ฐํ์ง ์์ผ๋ ค ํ์ง๋ง ๋ฐฐํฌ๋ ์๋น์ค๊ฐ ์ ์์ ์ผ๋ก ๋์๊ฐ๋ ค๋ฉด ๊ฐ ์ ์ ์ ํ ํฐ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ต์ ์ด๊ณ ๊ฒฐ๊ตญ ๋ก๊ทธ์ธ์ ํ์๋ถ๊ฐ๊ฒฐ์ด ๋์์ต๋๋ค. ํ์ง๋ง ๋ก๊ทธ์ธ์ ํ์ง์๊ณ ์๋น์ค๋ฅผ ๊ฒฝํํ๋ ๊ฒ๋ ์ค์ํ๋ค ์๊ฐํ์ฌ ๋ฐฉ๋ฒ์ ์ฐพ๊ฒ ๋์์ต๋๋ค.
Action |
**- ๋ฐ๋ชจ ๋ฒ์ ์ ๊ณต ๊ณ ๋ ค**
์ฒ์์๋ ๋ก๊ทธ์ธ์ ํ์ง ์์ ์ฌ์ฉ์๊ฐ ๋งํฌ๋ฅผ ์ ์ถํ๋ฉด ๊ธฐ๋ณธ ํ ํฐ์ ์์ฒญ๋(์๊ฐ ๋น 60๊ฐ)์ ์ด์ฉํ์ฌ ์ผ๋ถ๋ง ๋ณด์ฌ์ฃผ๋๋ก ํ๊ณ ๋ก๊ทธ์ธ์ ์ ๋ ํ๋ คํ์ต๋๋ค. ํ์ง๋ง ์ ๋ง ์ผ๋ถ์ ์ปค๋ฐ ๋ถ์๋ง ๋ณด์ฌ์ค ์ ์๊ณ ํต๊ณ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, ํ ํฐ์ ์์ฒญ๋์ ๋น ๋ฅด๊ฒ ์์งํ๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ ๋ ํฌ์งํ ๋ฆฌ๋ฅผ ๋ถ์ํ ์ ์๋ค๋ ๋ฌธ์ ๊ฐ ์์์ต๋๋ค. ๋ํ, ์ผ๋ถ ๊ฒฝ์ฐ์๋ API์ ์ ๊ทผ ์์ฒด๊ฐ ๋์ง ์๋ ๋ฌธ์ ๋ ๋ฐ์ํ์ต๋๋ค.
**- ๋ชฉ์ ๋ฐ์ดํฐ๋ฅผ ์ด์ฉํ ๋์ผํ ๊ฒฝํ ์ ๊ณต**
๋ฐ๋ผ์ ์ผ๋ถ ์ ๋ช ํ ๋ ํฌ์งํ ๋ฆฌ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ ๋ชฉ์ ๋ฐ์ดํฐ๋ก ์ ๊ณตํ๊ธฐ๋ก ํ์ต๋๋ค. ๋ํ ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํ ์ ์ ์ ์ต๋ํ ๋น์ทํ ์ฒดํ์ ํ๊ธฐ ์ํด ๊ธฐ๋ฅ๊ณผ ์ธํฐํ์ด์ค์ ์์๋ฅผ ๋๊ฐ์ด ์ด์ฉํ๊ฒ ํ๋ ๊ฒ์ด ์ค์ํ๋ค ์๊ฐํ์ต๋๋ค.
Result |
๋น๋ก๊ทธ์ธ ์ํ์์๋ ํ ์คํธ ์ ๋ ฅ ๋ฐ์ค๋ฅผ ์ ํ ๋ฐ์ค๋ก ๋ณ๊ฒฝํ๊ณ , ์ ๊ณต๋๋ ์ ํ์ง๋ฅผ ์ด์ฉํด ์ ์ถํ๊ฒ ๋๋ฉด ๋ชฉ์ ๋ฐ์ดํฐ๋ฅผ ์ด์ฉํด ์ค์ ๊ธฐ๋ฅ๊ณผ ๋์ผํ ๊ฒฝํ์ ํ ์ ์๊ฒ ํ์์ต๋๋ค. ๋ํ, ๋ฌธ๊ตฌ๋ฅผ ๋ฐ์ค ์์ ๋์ด ๋ก๊ทธ์ธ ์ ์ง์ ์ ๋ ฅ ๊ฐ๋ฅํ ์ ์ ์๊ฒ ํ์์ต๋๋ค.
![without_login_selection_box](assets/readme/without_login_selection_box.gif)
![login_input](assets/readme/login_input.gif)
ํ๋ก์ธ์ค๊ฐ ๊ฑฐ์ ๋๊ฐ๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ ํ์ง์๊ณ ์ฒดํํ๋ฉด์ ํํ ๋ฆฌ์ผ์ ๊ธฐ๋ฅ๋ ๊ฐ์ง ์ ์๊ฒ ๋์์ต๋๋ค.
## 5. ๋์ฉ๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ์ฒ๋ฆฌํ๊ธฐ
Problem |
**- ๋์ฉ๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์ ์๋ฌ ๋ฐ์**
์ปค๋ฐ์ ๋ํ ๋ฐ์ดํฐ ๊ด๋ฆฌ๋ก ํ์ด์ง ๋ฆฌ๋ก๋ ์ ์ํ๊ฐ ์ด๊ธฐํ๋๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํด sessionStorage์ ์ ์ฅํ์ต๋๋ค.
GitHub API๋ฅผ ํตํด ์ปค๋ฐ๋ค์ ๋ณ๊ฒฝ ๋ด์ฉ(diff)์ ๊ฐ์ ธ์ค๋ ๊ณผ์ ์์ ์ฝ๋์ ๋ณ๊ฒฝ ์ฌํญ์ด ๋ง์ ๊ฒฝ์ฐ ์ ์ฅ๋๋ ๋ฐ์ดํฐ์ ํฌ๊ธฐ๊ฐ ๋งค์ฐ ์ปค์ก๊ณ ์ด์ ๋ฐ๋ผ ๋ฐ์ดํฐ ์ ์ฅ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๊ฒ ๋์์ต๋๋ค.
sessionStorage ๋ ๋์ฉ๋์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ ๊ฒฝ์ฐ ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋์ง ์๊ณ ์ฉ๋์ด ์ด๊ณผ๋์๋ค๋ ์๋ฌ๊ฐ ๋ฐ์ํ๋ ๋ฌธ์ ๊ฐ ์์์ต๋๋ค.
Analysis |
sessionStorage ๋ ๋ธ๋ผ์ฐ์ ๋ง๋ค ์ฝ 5 MiB์ ์ฉ๋ ์ ํ์ด ์์๊ณ ์ด ์ฉ๋ ์ด์์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ธฐ์๋ ์ ํฉํ์ง ์์์ต๋๋ค. GitHub API๋ก ์๋ต ๋ฐ๋ ์ปค๋ฐ diff ๋ฐ์ดํฐ๋ ๋ณ๊ฒฝ๋ ์ฝ๋ ์์ ๋ฐ๋ผ ๋งค์ฐ ํฐ ํฌ๊ธฐ์ ๋ฐ์ดํฐ๊ฐ ๋ ์ ์๊ธฐ ๋๋ฌธ์ ๊ธฐ์กด์ sessionStorage๋ก๋ ๋ฐ์ดํฐ ์ ์ฅ ์คํจ๋ก ์ธํ ์๋ฌ ๋ฐ์ ๊ฐ๋ฅ์ฑ์ด ์ปค์ก์ต๋๋ค.
Action |
์ด ๋ฌธ์ ์ ํด๊ฒฐ์ ์ํด sessionStorage๋์ IndexedDB๋ฅผ ์ฌ์ฉํ์ต๋๋ค.
- IndexedDB
๋ธ๋ผ์ฐ์ ๋ด์์ ๋๊ท๋ชจ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ ์ฅํ๊ณ ๊ณ ์ฑ๋ฅ ๊ฒ์์ ์ํด ์ธ๋ฑ์ฑํ๋ ์น API ์ ๋๋ค.idb-keyval ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ๊ฐ๋จํ API (get(), set(), del() ๋ฑ)๋ฅผ ์จ์ IndexedDB ๋ฅผ ๋ค๋ฃฐ ์ ์๋๋ก ๊ตฌํํ์ต๋๋ค. ๋ํ zustand ๋ฅผ ํตํด ์ํ๋ฅผ ๊ด๋ฆฌํ๋ฉด์ ๋ฐ์ดํฐ๋ฅผ IndexedDB ์ ์ ์ฅํ๋ ๋ฐฉ์์ผ๋ก ์ ํํ์ต๋๋ค.
- zustand ์ persist ๋ฏธ๋ค์จ์ด(`storage: createJSONStorage(() => indexedDB)`)๋ฅผ ํ์ฉํ์ฌ zustand ์ํ๋ฅผ IndexedDB ์ ์ ์ฅํ๋๋ก ์ค์ ํ์ต๋๋ค.
- IndexedDB ์์ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๊ฑฐ๋ ์ญ์ ํ ๋ ๋ฐ์ํ ์ ์๋ ์๋ฌ๋ฅผ ์ฒ๋ฆฌํด์ฃผ๋ ๋ถ๋ถ์ ์ถ๊ฐํ์ต๋๋ค.```jsx
import { create } from "zustand";
import { createJSONStorage, persist } from "zustand/middleware";
import { get, set, del } from "idb-keyval";
import { throwIndexedDBErrorMessage } from "../../../shared/error/throwCustomErrorMessage";const indexedDB = {
getItem: async (name) => {
try {
const value = await get(name);
return value || null;
} catch (error) {
throwIndexedDBErrorMessage(error);
}
},
setItem: async (name, value) => {
try {
await set(name, value);
} catch (error) {
throwIndexedDBErrorMessage(error);
}
},
removeItem: async (name) => {
try {
await del(name);
} catch (error) {
throwIndexedDBErrorMessage(error);
}
},
};const initialState = {};
const useCommitStore = create(
persist(
(set) => ({
...initialState,
}),
{
name: "commit-storage",
storage: createJSONStorage(() => indexedDB),
}
)
);export default useCommitStore;
```Result |
**- sessionStorage ์์ ๋ฐ์ํ๋ ์ ์ฅ ์ฉ๋ ์ด๊ณผ ๋ฌธ์ ๋ฅผ ํด๊ฒฐ**
IndexedDB๋ 5MiB ๋ณด๋ค ํจ์ฌ ํฐ ์ฉ๋(GB ๋จ์)์ ์ง์ํ์ฌ ์ปค๋ฐ diff ๋ฐ์ดํฐ์ ๊ฐ์ ๋๋์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ ๋ ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์๊ณ ์ํํ๊ฒ ์ ์ฅํ ์ ์๊ฒ ๋์์ต๋๋ค.
zustand์ ๊ฒฐํฉํ์ฌ ์ปค๋ฐ ๊ด๋ จ ์ํ๋ฅผ ์ง์์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์๊ฒ ๋์๊ณ idb-keyval ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ์ฝ๋ ๋ณต์ก๋๋ฅผ ์ค์ด๊ณ ๋์ฉ๋ ๋ฐ์ดํฐ๋ฅผ ์์ ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๊ฒ ๋์์ต๋๋ค.
## 6. ๋ง์ ์ปดํฌ๋ํธ๋ค์ ํ๋ฉด์ ๋ ๋๋ง ํ๊ธฐ ์ํ virtual scroll ๋์
[virtual scroll ๋์ ํ PR ๋งํฌ](https://github.com/git-marvel/commit-guardians-client/pull/93)
![](assets/readme/before_virtualscroll.gif)
Problem |
**- INP ์ง์ ์์น ๋ฐ ํ๋ฉด ๋ฒ๋ฒ ์**
์ด๋ฏธ ๊ฒ์ฌ๊ฐ ๋๋ ๋ชจ๋ ์ปค๋ฐ๋ค์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํ๋ ๋ํ ์ผ ๋ทฐ์๋ **ํ๋ฉด ์ฑ๋ฅ์ ๊ดํ ๋ฌธ์ **๊ฐ ์์์ต๋๋ค. ์ ์ ์์ ์ปดํฌ๋ํธ๋ค์ ์คํฌ๋กค ํ ๋๋ ํฐ ๋ฌธ์ ๊ฐ ์์์ง๋ง, ๋ง์ ์์ ์ปดํฌ๋ํธ๋ค์ (๋๋ต 1์ฒ๊ฐ ์ด์์ ์ปค๋ฐ ์ปดํฌ๋ํธ) ๊ฐ์ง ๋ํ ์ผ ํ๋ฉด์ ์ฒซ ์ง์ ์ ํ๋ฉด ๋ ๋๋ง์ ์๊ฐ์ด ์ง์ฐ๋์์ต๋๋ค. ๋ธ๋ผ์ฐ์ ํผํฌ๋จผ์ค ํญ์ ํ์ธํด๋ณด๋ [**INP**](https://web.dev/articles/inp?hl=ko)(**Interaction to Nextย Paint**) ์ง์๊ฐ ๊ธ๊ฒฉํ ์์นํ๊ณ , ํ๋ฉด์ด ๋์ ์ผ๋ก ๋ณํ ๋, ํนํ๋ ๋ฒ๋ฒ ์ด๋ ๋ฌธ์ ๊ฐ ์์์ต๋๋ค. ์ด ๋ฌธ์ ๋ ์ฌ์ฉ์๋ ํ๋ฉด ์ ํ ์์ ๋๋ฆฐ ๋ฐ์ ์๋์ ์ง์ฐ์ผ๋ก ์ธํด ๋ต๋ตํจ์ ๋๋ผ๊ฒ ํ๊ณ , ์ ์ฒด์ ์ธ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ํ์ํค๊ณ , ์ฑ ์ฑ๋ฅ์ ๋ํ ๋ถ์ ์ ์ธ ์ํฅ์ ๋ผ์น ๊ฒ์ผ๋ก ์์ํ์ต๋๋ค.
Analysis |
๋ธ๋ผ์ฐ์ ๊ฐ ๋ชจ๋ ์ปดํฌ๋ํธ๋ฅผ ํ ๋ฒ์ ๋ ๋๋งํ๋ ค๋ ๊ณผ์ ์์ ๋ธ๋ผ์ฐ์ ๊ฐ ํ์ํ์ง ์์ ๋ฐ์ดํฐ๊น์ง ๋ชจ๋ DOM ์ ๋ ๋๋งํ๋ ๋ฐฉ์์ด ๋ณ๋ชฉํ์์ ์ฃผ์ ์์ธ์์ ํ์ธํ ์ ์์์ต๋๋ค. ์คํฌ๋กค์ด ๋ฐ๋์ ํ์ํ ๋ํ ์ผํ๋ฉด์์ ์คํฌ๋กค ์ฌ์ฉ ์ ์ฑ๋ฅ ์ ํ๊ฐ ๋์ฑ ์ฌ๊ฐํ๊ฒ ๋ํ๋๋ ๊ฒ์ ํ์ธํ์ต๋๋ค. ๋ฐ๋ผ์ INP ์ง์๋ฅผ ๊ฐ์ ํ๊ณ , ์คํฌ๋กค ์ ๋ถ๋๋ฌ์ด ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ ๋ฐฉ๋ฒ์ ์ฐพ์์ผ ํ์ต๋๋ค.
Action |
**- Virtual Scroll ๋์ **
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ ํฌ๋ **Virtual Scroll** ๊ธฐ์ ์ ๋์ ํ์์ต๋๋ค. Virtual Scroll ์ ์ฌ์ฉ์๊ฐ **ํ์ฌ ํ๋ฉด์์ ๋ณด๊ณ ์๋ ๋ถ๋ถ์ ํด๋นํ๋ ๋ฐ์ดํฐ๋ง DOM ์ ๋ ๋๋งํ๊ณ , ๋ณด์ด์ง ์๋ ๋ถ๋ถ์ ๋ ๋๋งํ์ง ์์**์ผ๋ก์จ ๋ธ๋ผ์ฐ์ ์ ๋ถํ์ํ ์์ ์ ์ค์ฌ์ฃผ๋ ๊ธฐ์ ์ ๋๋ค. ์ด๋ฐ ๋ฐฉ์์ ํตํด ์ด๊ธฐ ๋ ๋๋ง ์ ํ์ํ์ง ์์ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ฅผ ์ต์ํํ๊ณ , ๋ ๋๋ง ์๋๋ฅผ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์์ต๋๋ค. ๋๋ถ์ด ๋ฌดํ์คํฌ๋กค์ฒ๋ผ ํ์ด์ง๋ค์ด์ ์ ํตํ ๋ฐ์ดํฐ ์์ฒญ์ ํตํด์๋ ๊ฐ์ ํ ์ ์์์ง๋ง, ์ด๋ฏธ ์ปค๋ฐ๋ค์ด ๋ถ์๋ ๋ค์ ๋ํ ์ผ ํ๋ฉด ํ์ด์ง๋ฅผ ๋ณด๋ ๊ฒ์ด๊ธฐ์ ๋ฌดํ ์คํฌ๋กค ๊ธฐ๋ฅ์ ํ์์๋ค ํ๋จํ์ต๋๋ค. Virtual Scroll ์ ๋์ ํ๊ณ ๋ ๋๋ง ์ต์ ํ๋ฅผ ์ํด ์ปดํฌ๋ํธ ๋ถ๋ฆฌ ๋ฐ ๋ฉ๋ชจ์ด์ ์ด์ ์ ์ฉํ์ฌ ์ฑ๋ฅ์ ๊ฐ์ ํ์ต๋๋ค.
Result |
![](assets/readme/after_virtualscroll.gif)
์ด๊ธฐ ๋ ๋๋ง ์ ๋ถํ์ํ DOM ์์ ์ ์ค์ด๊ณ , ์คํฌ๋ฆฐ์ ๋ณด์ฌ์ฃผ๋ ๋ถ๋ถ๋ง DOM ์ ๊ทธ๋ฆฌ๋๋ก ํ๋ฉด์ INP ์ง์๋ฅผ ๊ฐ์ ํ ์ ์์์ต๋๋ค. ์ด๋ก์จ, ๋๊ฐ์ง ์ด์ ์ ๋ ์ป์ ์ ์์์ต๋๋ค.
1. **์คํฌ๋กค ์ฑ๋ฅ ํฅ์**: ๋๊ท๋ชจ ์ปค๋ฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง ํ๋ฉด์์๋ ์คํฌ๋กค์ด ๋ถ๋๋ฝ๊ฒ ์๋ํ๊ณ ์ฆ๊ฐ์ ์ธ ๋ฐ์์ฑ ์ ๊ณตํ ์ ์๊ฒ ๋์์ต๋๋ค.
2. **์ฌ์ฉ์ ๊ฒฝํ ๊ฐ์ **: ํ๋ฉด ์ ํ ์๋๊ฐ ๋นจ๋ผ์ง๊ณ , ๋ฐ์ดํฐ๊ฐ ๋ง์ ํ๋ฉด์์๋ ๋์ ์ฑ๋ฅ ์ ์งํ ์ ์์ต๋๋ค.๊ฒฐ๊ณผ์ ์ผ๋ก, ๋๊ท๋ชจ ์ปค๋ฐ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๋ ๋ ํฌ์งํ ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ๋์๋ ์์ ์ ์ธ ์ฑ๋ฅ๊ณผ ์ํํ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ฌ์ฑํ๊ฒ ๋์์ต๋๋ค.
## ํ์ ์๊ฐ
**์ ์ฒ ํ**
์๋น์ค์ ๋ชฉ์ ์ ๊ฐ์ง ํ๋ก์ ํธ์ ํ์ ์ ์ด๋ฒ์ด ์ฒ์์ ๋๋ค. ๊ทธ ์ ์๋ ํ์๋ค๊ณผ ๊ฐ์ด ์ฝ๋ฉ์ ํ๋ฉด์ ํ์ ์ด๋ ๋ฌด์์ธ์ง์ ๋ํด ์ด๋ก ์ ์ผ๋ก ์ ๊ทผํ์ง ํฌ๊ฒ ์๋ฟ์ง๋ ์์์ต๋๋ค. ํ๋ก์ ํธ๋ฅผ ์งํํ๋ ๋ช ์ฃผ ๋์ ์ญํ ์ ๋๋๊ณ , ๋ง์ ์๊ฐ์ ํ๋์ ๋ชฉํ์ ๋ํด ์ง์คํ๊ฒ ๋๋ฉด์ ํ์ ์ ๋ํด ๋ง์ด ์๊ฐ์ ํ๊ฒ ๋์์ต๋๋ค.
์ ํฌ ํ๋ก์ ํธ ์ฃผ์ ๋ก ์ปค๋ฐ์ ์ฌ๋ฐ๋ฅด๊ฒ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์กฐ์ฌํ๋ฉด์ ๋จ์ํ ์ปค๋ฐ์ด ๊ธฐ๋ก์ ์๋จ์ด ์๋๋ผ ์ ํฌ๊ฐ ํ๋ ํ์ ์ โ์ธ์ดโ๋ผ๋ ๋๋์ ๋ง์ด ๋ฐ์์ต๋๋ค. ๊ฐ๋ ๋ง์ด ๊ณ ์์ผ ์ค๋ ๋ง์ด ๊ณฑ๋ค๋ ์๋ด์ฒ๋ผ ์ปค๋ฐ๋ ์ ์์ฑํ๊ณ ์ ๋ฌํด์ผ ์ํต์ด ์ ์งํ๋๋ ๊ฒ ๊ฐ์์ต๋๋ค.
๊ทธ๋์ ์ ์๊ฒ ํ์ ์ ์ํ๋๊ณ ๋ฌผ์ผ๋ฉด ์ ๋ ์ด๋ฒ์๋ ์ปค๋ฐ์ ์ ์ฐ์ง ๋ชปํด์ ์์ฝ๋ค๊ณ ๋๋ตํ ๊ฒ๋๋ค. ํ์ง๋ง ๋์ค์๋ ๋ฉ์ง ์ปค๋ฐ์ ์ฐ๊ณ ๋น๋นํ๊ฒ โ๋คโ๋ผ๊ณ ๋ตํ์ผ๋ฉด ์ข๊ฒ ์ต๋๋ค.
**ํ์ ์ง**
์ด๋ฒ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉด์ ์ปค๋ฐ์ด ๋จ์ํ ๊ธฐ๋ก์ด ์๋๋ผ, ํ๋ก๋ํธ์ ๊ธฐ๋ฐ์ ์ด๋ฃจ๋ ์ค์ํ ์์๋ผ๋ ์ฌ์ค์ ๋ค์ ํ๋ฒ ์ค๊ฐํ๊ฒ ๋์์ต๋๋ค. ์ฌ์ค, ์ปค๋ฐ์ ์ค์์ฑ์ ๋ํ ์ด์ผ๊ธฐ๋ ์์ฃผ ๋ค์์์ง๋ง, ์ด ํ๋ก์ ํธ๋ฅผ ๊ฒฝํํ๊ธฐ ์ ๊น์ง๋ ๊น์ด ๊ณต๊ฐํ์ง ๋ชปํ์ต๋๋ค. ์ด๋ฒ ํ๋ก์ ํธ ๊ฒฝํ์ ํตํด, ์ข์ ์ปค๋ฐ์ด ๋๋ฃ ๊ฐ๋ฐ์์ ์์ฐ์ฑ์ ์ผ๋ง๋ ํฌ๊ฒ ํฅ์์ํฌ ์ ์๋์ง๋ฅผ ์ฒด๊ฐํ๊ฒ ๋์๊ณ , ์ปค๋ฐ์ ๋ํ ์ ๊ฐ์น๊ด ๋ํ ํฌ๊ฒ ๋ณํํ์ต๋๋ค.
๋, ํ ํ๋ก์ ํธ๋ก ํจ๊ป ํ์ ์ ํ๋ฉด์ ์๋ก์ ์๊ฐ์ ๋ง์ถฐ๋๊ฐ๋ ๊ณผ์ ์ด ์ฆ๊ฑฐ์ ์ต๋๋ค. ์ง๊ธ์ ์ ํฌ ํ๋ก์ ํธ๊ฐ style, remove, test, docs ์ ์ปค๋ฐํ์ ๋ง ๊ฐ๋ฅํ์ง๋ง, ์ดํ ํ๋์ฉ ํ๋์ฉ ๋ ์ถ๊ฐํ์ฌ ์ ๋ฐ์ดํธ ํ ์ ์์์ผ๋ฉด ์ข๊ฒ ์ต๋๋ค!
**๊น์ํ**
ํ๋ก์ ํธ ์งํ ์ด๊ธฐ์๋ ์ปค๋ฐ๋ฉ์์ง์ ๊ดํ ๊ธฐ์ค์ ์ ํ๋ ๊ณผ์ ์ด ์์์ต๋๋ค. ์ฌ๋๋ค๋ง๋ค ๋ค๋ฅด๊ฒ ์์ฑ๋ ์ปค๋ฐ ๋ฉ์์ง์ ๋ณ๊ฒฝ ๋ด์ฉ์ ์ผ์น์ฑ์ ๊ท๊ฒฉํ๋ ๊ธฐ์ค์ ์ ํด ํ๋จํด์ผํ๊ธฐ ๋๋ฌธ์ ์๋ก์ด ์ผ์ด์ค๊ฐ ๋์ฌ ๋๋ง๋ค ์ด๋ค ์์ผ๋ก ๊ท๊ฒฉํ๋ฅผ ์์ผ์ผํ ์ง ๊ณ ๋ฏผ์ ๋ง์ด ํ๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋ํ API๋ก ์๋ต๋ฐ์ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๊ด๋ จํด์ ๋ค์ํ ๋ฌธ์ ๋ค์ ๋ง์ฃผํ๊ฒ ๋์์ต๋๋ค. ์ด๋ฅผ ํด๊ฒฐํ๋ ๊ณผ์ ์์ IndexedDB ํ์ฉ๊ณผ ๋ง์ ์์ ๋ฐ์ดํฐ๋ฅผ API์์ฒญ์ ๋ณด๋ผ ๋ ํจ์จ์ ์ผ๋ก ๋ณด๋ผ ์ ์๋ ๋ฐฉ์ ๋ฑ ์ฌ๋ฌ ๊ฐ์ง๋ฅผ ๋ฐฐ์ฐ๊ฒ ๋์์ต๋๋ค.
์์ํ์ง ๋ชปํ ๋ฌธ์ ๊ฐ ์๊ฒผ์ ๋ ํ์๋ค๊ณผ ๊ฐ์์ ์๊ฒฌ์ ๊ณต์ ํ๊ณ ํ์๋ฅผ ํ๋ค๋ณด๋ฉด ์๋ก์ด ๋ฐฉํฅ์ ํด๊ฒฐ์ฑ ๋ค์ด ๋์์ ๋ค์ํ ์๋๋ค์ ํด๋ณผ ์ ์๋ ๊ธฐํ๊ฐ ๋์์ต๋๋ค. ์งง์ ๊ธฐ๊ฐ์ด์์ง๋ง ์๋ก์ด ๊ฐ๋ ๋ค์ ๋ฐฐ์ฐ๊ฒ ๋์๊ณ ํจ์จ์ ์ธ ์ํต ๋ฐฉ์์ ๋ํด ์๊ฐํด๋ณด๊ณ ์ ์ฉํด๋ณผ ์ ์์๋ ์ข์ ๊ฒฝํ์ด์์ต๋๋ค.