TnT๋ ํธ๋ ์ด๋์ ํ์ยท์์ ๊ด๋ฆฌ์ ํธ๋ ์ด๋์ ์ด๋ยท์๋จ ๊ธฐ๋ก์ ์ฐ๊ฒฐํ๋ PT ๊ด๋ฆฌ ์ฑ์ ๋๋ค. ์ด ์ ์ฅ์๋ ๊ธฐ์กด TnT iOS๋ฅผ ํฌํฌํด, ๊ฐ์ ํ๋ฉด์ ๋ค์ ์ด ๋๋ง๋ค ๋ฐ๋ณต๋๋ APIยท์ด๋ฏธ์ง ์์ฒญ๊ณผ ๋๊ธฐ ์๊ฐ์ ์ค์ธ ๊ฐ์ ํ๋ก์ ํธ์ ๋๋ค.
๋ถ๊ธฐ ์์ ์๋ ํ ์คํธ ๋ฉ์๋๊ฐ ์์์ต๋๋ค. ์ ํ ๊ท์น๊ณผ ์คํจ ์ํ๋ฅผ 302๊ฐ์ ํ๊ท ํ ์คํธ๋ก ๋จผ์ ๊ณ ์ ํ๊ณ , ์ฌ์ฉ์๋ ๊ธฐ๋ก์ด ๋ฐ๋์์ ๋ ์๋ชป๋ ๊ฐ์ ์ฌ์ฌ์ฉํ์ง ์๋๋ก ๋๋ฉ์ธยท์ด๋ฏธ์ง ์บ์๋ฅผ ๊ฐ๊ฐ ์ค๊ณํ์ต๋๋ค. ๋ค์ฏ ์ฌ์ง์ ํ๋ก์ฐ์์ ๋์ ๋ฐ๋ณต ์์ฒญ์ ๋ชจ๋ ์ ๊ฑฐํ๊ณ , ๋์ผํ Profile ์คํ ํ์ผ๋ก ์งํํ 100ํ์ ์ ํจ ์ค๊ธฐ๊ธฐ A/B์์ ๋ด๋ถ ์๋ฃ ์์ p50์ด 74.9~97.5% ์ค์์ต๋๋ค.
์๋ณธ ํ๋ก์ ํธ์ ๊ธฐํ๊ณผ UI, TrainerยทTrainee ํ๋ก์ฐ๋ ์ ์งํ์ต๋๋ค. ์ดํ์ ๋ ์ด์ด ๋ฆฌํฉํ ๋ง๊ณผ ํ ์คํธ, ์บ์ ํ์ดํ๋ผ์ธ, ์ค๊ธฐ๊ธฐ ์ธก์ ์ ์ง์ ์งํํ์ต๋๋ค.
Diet Before/After ยท ์ค๊ธฐ๊ธฐ ์ธก์ ๊ฒฐ๊ณผ
Diet๋ ์บ๋ฆฐ๋, ๋ ์ง๋ณ ์๋จ, ์์ธ ๊ธฐ๋ก๊ณผ ์ด๋ฏธ์ง๋ฅผ ์ฐจ๋ก๋ก ๋ค์ ์ฌ์ฉํ๋ ํ๋ก์ฐ์ ๋๋ค. ์บ์ ์ ์ฉ ํ์๋ ์ธ ๋๋ฉ์ธ ๋ฐ์ดํฐ์ ์์ธ ์ด๋ฏธ์ง๋ฅผ ์๊ฒฉ ์์ฒญ ์์ด ๋ค์ ์ฌ์ฉํ์ต๋๋ค.
| ์ฌ์ฉ์ | ๋ค์ ๋ค์ด๊ฐ ํ๋ฉด | ๋์ ์๋ณธ ์์ฒญ | ์ ์ฉ ์ โ ์ ์ฉ ํ p50 |
|---|---|---|---|
| Trainer | Home ยท ์์ ๋ชฉ๋ก | API 1ํ โ 0ํ | 687.4 โ 172.5ms ยท 74.9% ๊ฐ์ |
| Trainer | Home ยท ํ์ ํ๋กํ | ์ด๋ฏธ์ง 6ํ โ 0ํ | 1,937.9 โ 183.4ms ยท 90.5% ๊ฐ์ |
| Trainee | Home ยท ์๋จ ์นด๋ | ์ด๋ฏธ์ง 3ํ โ 0ํ | 1,490.0 โ 171.2ms ยท 88.5% ๊ฐ์ |
| Trainee | Diet ยท ์บ๋ฆฐ๋์์ ์๋จ ์์ธ | API 3ํยท์ด๋ฏธ์ง 1ํ โ ๋ชจ๋ 0ํ | 1,092.6 โ 212.6ms ยท 80.5% ๊ฐ์ |
| ๊ณตํต | MyPage ยท ๋ด ์ ๋ณด | API 1ํยท์ด๋ฏธ์ง 1ํ โ ๋ชจ๋ 0ํ | 1,133.3 โ 28.2ms ยท 97.5% ๊ฐ์ |
์บ์ ์ ์ค๋ฅ ๋ณด๋ค โ์ง๊ธ ์ด ๊ฐ์ ๋ค์ ๋ณด์ฌ์ค๋ ๋๋์งโ๋ฅผ ๋จผ์ ์ ํ์ต๋๋ค. ๋น ๋ฅด๋๋ผ๋ ๋ค๋ฅธ ์ฌ์ฉ์์ ์ ๋ณด๋ ์์ ์ ๊ธฐ๋ก(์บ์)์ด ๋ณด์ด๋ฉด ์ ์ ๊ฒฝํ์ ๋ ๋๋น ์ง๊ธฐ ๋๋ฌธ์ ๋๋ค.
| ์ํฉ | ์ ์ฉํ ๊ธฐ์ค |
|---|---|
| ๋ก๊ทธ์์ยท๊ณ์ ์ ํ | ์ด์ ์ฌ์ฉ์์ ์บ์๋ฅผ ๋น์ฐ๊ณ ์ธ์ ๋ณ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฆฌ |
| ์๋จยทํ๋กํ ๋ณ๊ฒฝ | ๊ด๋ จ ๋๋ฉ์ธ ์ค๋ ์ท์ ๋ฌดํจํ |
| TTL ๋ง๋ฃ | ์๋ฒ ์์ฒญ์ด ์คํจํ์ ๋๋ง ์ค๋๋ ์ค๋ ์ท์ ์ ํ์ ์ผ๋ก ์ฌ์ฉ |
| ์ด๋ฏธ์ง URL ๋ณ๊ฒฝ | ๋ฆ๊ฒ ๋๋ ์ด์ ์์ฒญ์ด ํ์ฌ ํ๋ฉด์ ๋ฎ์ง ๋ชปํ๊ฒ ์ฐจ๋จ |
| ๋์ผ URL ๋์ ์์ฒญ | ์งํ ์ค์ธ ์์ฒญ ํ๋๋ฅผ ๊ณต์ |
| ์ ์ฅ ๊ณต๊ฐ | ๋ฉ๋ชจ๋ฆฌยท๋์คํฌ ์บ์์ ํฌ๊ธฐ์ ์๋ช ์ ์ ํํ๊ณ LRU๋ก ์ ๋ฆฌ |
๋๋ฉ์ธ ๋ฐ์ดํฐ์ ์ด๋ฏธ์ง๋ ํ๋์ ์ ์ฅ ๊ตฌ์กฐ๋ก ๋ฌถ์ง ์์์ต๋๋ค. ๋๋ฉ์ธ ์บ์๋ ์ธ์ ๊ณผ ๊ธฐ๋ก ๋ณ๊ฒฝ์ด ์๋ช ์ ๊ฒฐ์ ํ๊ณ , ์ด๋ฏธ์ง ์บ์๋ URL๊ณผ ๋์ฝ๋ฉ ๋น์ฉ, ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ์ค์ฌ์ผ๋ก ๊ด๋ฆฌํด์ผ ํ์ต๋๋ค.
์บ์ ์ ์ฅ ๋ฐฉ์
์บ์์ DTO๋ ํ๋ฉด ์ํ๋ฅผ ๊ทธ๋๋ก ์ ์ฅํ์ง ์์์ต๋๋ค. Data์ ๋๋ฉ์ธ ์นํ์ ์ธ ์ค๋ ์ท์ ์ ์ฅํ๊ฒ ํด ์๋ฒ ์๋ต ํ์๊ณผ ํ๋ฉด ์๋ช ์ฃผ๊ธฐ์์ ์บ์ ํ์์ ๋ถ๋ฆฌํ์ต๋๋ค.
๊ธฐ๋ก์ด ๋ฐ๋ ๋ค์๋ ๊ฐ๋ณ key๋ฅผ ์ฐพ์ ์ง์ฐ๋ ๋์ ๊ด๋ จ ์ธ์ namespace๋ฅผ ๋น์ ์ต๋๋ค. ๋ค์ ์์ฒญ ๋น์ฉ์ ๊ฐ์ํ๋๋ผ๋ ํ์ ์กฐํ ๊ด๊ณ๋ฅผ ๋น ๋จ๋ ค ์์ ์ ๋ฐ์ดํฐ๋ฅผ ๋ณด์ฌ์ฃผ๋ ์ชฝ์ด ๋ ์ํํ๋ค๊ณ ํ๋จํ์ต๋๋ค.
๋์ผํ ์์ ์ค๋ ์ท 60๊ฐ๋ฅผ ์์ฐจ ์ ์ฅยท์กฐํํ๋ ๋์คํฌ ๊ธฐ๋ฐ ๋ฒค์น๋งํฌ ํ ์คํธ์์ JSON์ ์ด๊ธฐํยท์ ์ฅยท์กฐํ๊ฐ, CoreData๋ ์ผ๊ด ์ ๋ฆฌ์ ์ ์ฅ ๊ณต๊ฐ์ด ์ ๋ฆฌํ์ต๋๋ค. ์ด๋ ํ์ชฝ์ ์ ๋ฉด์ ์ธ ์ฑ๋ฅ ์ฐ์๋ ํ์ธ๋์ง ์์๊ณ , ํ์ฌ ์ ๊ทผ ํจํด์์๋ CoreData์ ์ถ๊ฐ ๋ณต์ก๋๋ฅผ ๊ฐ์ํ ๊ทผ๊ฑฐ๋ ๋ถ์กฑํ์ต๋๋ค. ๋ณธ ํ๋ก์ ํธ ๋ฒ์์์๋ CoreData ์ ์ง๋ณด์ ๋น์ฉ์ ๋นํด ํ์ฐํ CoreData ์ฌ์ฉ์ ์ด๋์ด ์์ด JSON์ ๊ธฐ๋ณธ ์ ์ฅ ๋ฐฉ์์ผ๋ก ์ ์งํ์ต๋๋ค.
๊ธฐ์กด ํ๋ก์ ํธ๋ ๋ ์ด์ด๋ณ ๋ชจ๋๋ก ๋๋์ด ์์์ง๋ง, ์ ๋ ฅ ๊ฒ์ฆ๊ณผ ์ธ์ ํ๋จ์ด TCA Reducer์ ๋จ์ ์์๊ณ Domain์ด ๋คํธ์ํฌ DTO์ Mapper๋ฅผ ์๊ณ ์์์ต๋๋ค. ๋คํธ์ํฌ์ Keychain ๊ฐ์ ์ธ๋ถ ์์กด์ฑ๋ ์คํจ ์ํฉ์ ์ฌํํ๊ธฐ ์ด๋ ค์ด ํํ์์ต๋๋ค.
๊ธฐ์กด ๋์์ ํ
์คํธ๋ก ๊ณ ์ โ ์ฑ
์ ๋ถ๋ฆฌ โ ์คํจ ์ํ ์ฌํ โ ์บ์ ์ ์ฉ โ ์ค์ ํ๋ฉด A/B
| ๊ธฐ์กด ๊ตฌ์กฐ | ๋ฆฌํฉํ ๋ง ํ |
|---|---|
| Reducer๊ฐ ์ ๋ ฅ ๊ฒ์ฆ, ๊ธฐ๋ก ์ด์, ์ธ์ ์์ ์กฐ๊ฑด๊น์ง ํ๋จ | Domain validator์ policy๊ฐ ์ ํ ๊ท์น์ ํ๋จ |
| Domain์ด DTO์ Mapper๋ฅผ ์์ | DTO, ์์ฒญ payload, ๋งคํ ์ฑ ์์ Data๋ก ์ด๋ |
| ์ธ๋ถ ์์กด์ฑ์ ์คํจ ๊ฒฐ๊ณผ๋ฅผ ๋ง๋ค๊ธฐ ์ด๋ ค์ | ๋คํธ์ํฌยทKeychainยทํธ์ ์ ์ฅ ๊ฒฝ๋ก๋ฅผ ์ฃผ์ ๊ฐ๋ฅํ ์ธํฐํ์ด์ค๋ก ๋ถ๋ฆฌ |
| ์คํจ ๋ค์๋ ์ฑ๊ณต ์ํ๋ก ๋์ด๊ฐ ์ ์์ | ์คํจ ์ ๊ธฐ์กด ํ๋ฉด ์ํ๋ฅผ ์ ์งํ๋๋ก ํ ์คํธ๋ก ๊ณ ์ |
ํ์ฌ 302๊ฐ์ ์ ํ ํ๊ท ํ ์คํธ๊ฐ ์ ๋ ฅ ๊ท์น, ์ธ์ , ๋คํธ์ํฌ ์คํจ, ์บ์ ์๋ช ์ฃผ๊ธฐ์ ํ๋ฉด ์ํ ์ ํ์ ๊ฒ์ฆํฉ๋๋ค. ๊ธฐ์กด ๋์๊ณผ ์คํจ ์ํ๋ฅผ ํ ์คํธ ์ฝ๋๋ก ๋จผ์ ์ฌํํ ๋ค์ ์์ ํ๊ฒ ๋ฆฌํฉํ ๋ง์ ์งํํ์ต๋๋ค.
๊ฐ์ Profile ์คํ ํ์ผ์์ cache-bypass(์บ์ X)์ cache-enabled(์บ์ O)๋ฅผ ์คํ ์์ ์ ์ ํํ๊ณ , ๊ฐ์ ํ๋ฉด์ ๋ฒ๊ฐ์ ์คํํ์ต๋๋ค.
Trainer Home 30ํ, Trainee Home 30ํ, Diet 20ํ, MyPage 20ํ๋ก ์ด 100ํ์ ์ ํจ ์คํ์ ์์งํ์ต๋๋ค. ๋์ ์์ฒญ ์์ ๋ด๋ถ ์๋ฃ ์์ , ์ด๋ฏธ์ง ๋ฉ๋ชจ๋ฆฌ, Release ์ธก์ ์ฝ๋ ์ ์ธ, ๊ธฐ์กด ๊ธฐ๋ฅ์ด ๋ค์ ๊นจ์ง์ง ์๋์ง๋ฅผ ํจ๊ป ํ์ธํ์ต๋๋ค. ๋ค์ฏ ํ๋ก์ฐ์ ์ง์ฐ ์๊ฐ์ ๋ชจ๋ ๊ฐ์ ๋จ์ผ๋ก ํ์ ๋๊ณ , ์ด๋ฏธ์ง ๊ฒฝ๋ก๋ 20๊ฐ ์ธก์ ๋ฌถ์ยท120ํ ์ฌ์ง์ ์์ ๋ฉ๋ชจ๋ฆฌ ๊ฐ๋๋ ์ผ์ ํต๊ณผํ์ต๋๋ค.
์ธก์ ๊ฐ์ ์ฌ์ฉ์ ๋์ ์์๋ถํฐ ๋ด๋ถ ์ข
๋ฃ marker๊น์ง ๊ฑธ๋ฆฐ ์๊ฐ์
๋๋ค.
ํ๋ณธ ์์ ํ์ ๊ธฐ์ค์ PortfolioPerformanceV2์ ์ ๋ฆฌํ์ต๋๋ค.
Domain/Data: ํ๋ฉด์์ ๋ถ๋ฆฌํ ์ ํ ๊ท์น๊ณผ ๋คํธ์ํฌ ์ฑ ์DomainCacheEngine.swift: ์ธ์ namespace, TTL, ์ค๋ ์ท ์ ์ฅ๊ณผ ์ ๋ฆฌCachedRemoteImage.swift: URL identity, generation guard, ๋ฉ๋ชจ๋ฆฌยท๋์คํฌยท์๊ฒฉ ๋ก๋ฉTNT_PERFORMANCE_VARIANTS: ๋์ผ ์คํ ํ์ผ์ runtime A/B
| ํ์ธํ ๋ด์ฉ | ๋ํ ํ ์คํธ |
|---|---|
| ์ธ์ ์์๊ณผ ์๋จ ์ ๋ ฅ ๊ท์น | SessionBootstrapPolicyTests ยท DietRecordDraftValidatorTests |
| ๋๋ฉ์ธ ์บ์์ freshยทstaleยทcleanup | DomainCacheEngineTests |
| repository ์บ์ hit๊ณผ ๋ณ๊ฒฝ ํ ๋ฌดํจํ | TrainerRepositoryCacheTests ยท TraineeRepositoryCacheTests |
| ์ด๋ฏธ์ง URL identity์ generation guard | CachedRemoteImageTests |
| ์ค์ ํ๋ฉด ์ธก์ ์กฐ๊ฑด | ScreenUseCasePerformanceMeasurementTests |
PortfolioPresentationV1: Diet Before/After ์์๊ณผ ์ด๋ฏธ์งPortfolioPerformanceV2: ๋ค์ฏ ํ๋ก์ฐ์ ํ๋ณธ ์, p50, ํ์ ๊ณผ ์์ฒญ ์163684bc: ์๋ณธ TnT iOS์ ํ๋ก์ ํธ ๊ธฐ์ค์
์๋ณธ trace์ ๊ฐ๋ฐ ์๋ฒ ๋ก๊ทธ๋ ๊ณต๊ฐํ์ง ์์์ต๋๋ค.
๊ณต๊ฐ ๊ฐ๋ฅํ ์ธก์ ๊ฒฐ๊ณผ์ ๊ฒ์ฆ ๋ฒ์๋ PortfolioPerformanceV2์์ ํ์ธํ ์ ์์ต๋๋ค.
Tech ยท iOS 17 ยท SwiftUI ยท The Composable Architecture ยท Clean Architecture ยท Tuist 4.188.0
Measured on ยท Profile ยท iPhone 13 Pro ยท iOS 26.5.2
