heyday2024 님의 블로그
[리그오브레전드 앱 프로젝트] Trouble Shooting 기록 본문
.
첫번째 트러블슈팅: 렌더링 방식 설정 고민
1. 문제 발생
프로젝트에서 페이지 별로 다양한 렌더링 방식을 적용하는 과정에서 SSR과 ISR을 적용하는 방식에 대한 고민이 생김.
렌더링 방식 종류:
Incremental Static Regeneration (ISR), Server-Side Rendering (SSR), Client-Side Rendering (CSR), Static Site Generation (SSG)
<Pre-Rendering (Dynamic) - Server Side Rendering (SSR)>
1) fetch에 no-store 옵션 주기
2) page.tsx 컴포넌트에 dynamic 추가하기
< Incremental Static Regeneration(ISR) >
1) fetch에 옵션 주기
2) page.tsx 컴포넌트에 revalidate 추가하기
각각의 방식 중에 fetch 함수에서 렌더링 방식을 미리 정의해서 사용할지, 각 페이지에서 렌더링 방식을 명시적으로 관리할지 고민이 되었음.
2. 원인 추론
- 과제를 진행하면서 주어진 요구사항은 Riot Games API의 응답 데이터를 받아 페이지의 용도에 따라 렌더링 방식을 고려하고 구현하는 것임.
- fetch 함수에서 렌더링 방식을 미리 설정하면 코드의 중앙 집중화가 가능했으나, 훗날에 다시 다른 페이지들에서 쓰일 수 있는 fetch 기능의 함수들이 페이지별로 다양한 요구사항을 만족하기엔 유연성이 부족할 수 있다고 판단함.
3. 해결 방안
- fetch 함수에서 렌더링 방식을 처리하는 방법의 장단점 분석
- 장점:
- 재사용성이 높아 모든 페이지에서 일관된 렌더링 방식 사용 가능.
- 렌더링 방식 설정이 중앙화되어 유지보수가 용이.
- 단점:
- 유연성이 떨어져, 특정 페이지에서 다른 렌더링 방식이 필요할 경우 한계 발생.
- API 호출 함수가 순수 데이터를 반환하지 않고, 불필요하게 렌더링 방식 로직이 포함됨.
- 장점:
- 페이지에서 렌더링 방식을 명시적으로 처리하는 방법의 장단점 분석
- 장점:
- 페이지마다 필요에 따라 렌더링 방식을 다르게 설정 가능.
- fetch 함수는 순수하게 데이터를 가져오는 역할만 하므로 재사용성 높음.
- 단점:
- 렌더링 방식 설정이 분산되어 중복 코드 발생 가능.
- 모든 페이지에서 일일이 렌더링 방식을 설정해야 하는 유지보수 부담.
- 장점:
- 결론
- 페이지 레벨에서 렌더링 방식을 명시적으로 설정하는 방향으로 결정.
- Riot Games API 호출 함수는 데이터를 가져오는 역할만 하도록 단순화하고, 각 페이지에서 revalidate(ISR) 또는 dynamic(SSR) 등을 사용해 렌더링 방식을 정의함.
4. 결과
- 코딩, 코드 검수하는 과정에서 각 페이지의 코드 볼 때 마다 해당 페이지가 어떤 렌더링 방식을 쓰는지 조금 더 빠르고 쉽게 그리고 명확하게 분별할 수 있게되어 좋았음. (revalidate나 dynamic, use client, 별 추가된 거 없음 등의 근거로 각각의 페이지가 어떤 렌더링 방식으로 작동되는 지 바로 보임 ....)
- fetch 함수는 순수 데이터를 반환하는 역할로 단순화되어 훗날에 내가 다른 페이지들을 더 만들고 싶을 때 페이지별 렌더링 방식 선택에 대한 유연성이 높아지고, fetch 함수의 재사용성이 높아질 수 있음.(==> 프로젝트 확장성과 유지보수성을 고려한 구조로 개선됨.)
교훈 및 개선점
프로젝트 요구사항에 따라 렌더링 방식을 중앙화할지 분산할지 고민이 필요하며, 상황에 따라 적절한 전략 선택이 중요함을 깨달았다. 페이지별 어떤 렌더링 방식을 적용할지 고민하고 그것을 적용하는 과정이 꼭 필요하고 이는 사용자 경험을 향상시켜줄 뿐만 아니라 리소스 관리 차원에서 효과적임을 꺠달았다.
두번째 트러블 슈팅
1. 문제 발생
아이템 페이지를 다 구현하고 아이템 페이지를 살펴보는 중, 예상치 못하게 아이템을 간략히 설명하는 부분에 HTML 태그와 특수 기호가 포함된 데이터가 노출되는 현상을 발견함.
해당 HTML 태그가 렌더링된 상태로 나타나면서 사용자 경험에 부정적인 영향을 줌.
2. 원인 추론
- Riot으로부터 응답 받은 아이템 관련 데이터에 HTML 태그와 특수 기호가 포함된 경우가 있었음.
- 응답 데이터에서 모든 아이템의 plaintext 영역을 확인하기 어려웠고, 이 떄문에 미처 발견하지 못한 예외 상황에 대한 처리를 하지 못함.
3. 해결 방안
- HTML 태그 및 특수 기호 제거 함수 작성
데이터를 렌더링하기 전에 HTML 태그와 특수 기호를 제거하는 함수를 작성하여, 데이터의 안정성을 보장하기로함.
// html 태그 제거하는 함수
const removeHtmlTags = (input: string): string => {
return input.replace(/<[^>]*>/g, "").replace(/@[^@]*@/g, "");
};
4. 결과
- HTML 태그와 특수 기호가 포함된 데이터가 정상적으로 정리되어 사용자 인터페이스에 문제없이 렌더링됨.
- 예상치 못한 데이터 형태에 대한 대응책을 마련함으로써, 유사한 문제가 발생할 가능성을 크게 줄임.
교훈 및 개선점
- API 응답 데이터 타입의 중요성 인식
데이터 타입을 관리하는데 집중했었고, 그렇게 미리 타입들을 지정함으로서 응답받는, 그리고 요청하는 데이터에 관한 오류를 최소화했다고 생각했다. 하지만, 그것을 넘어 같은 타입의 데이터라도 예외적인 데이터 형태가 존재할 수 있음을 꺠달았다. 위 상황처럼 모든 데이터들의 내용을 확인하기에는 너무 많은 데이터들이 있다. 하지만 그럼에도 불구하고 외부에서 응답 받는 데이터를 쓸 떄에는 항상 예외성을 고려하여 명확한 타입 정의와 예외 처리 로직을 추가해야함을 깨달았다. - 데이터 정제 로직의 필요성
데이터를 UI에 직접 출력하기 전에 정제 및 검증 과정을 반드시 거쳐야 하고 그 데이터를 이용해서 렌더링된 페이지를 꼭꼭 다시 확인하는 습관을 갖어야겠다.
마지막 트러블슈팅
1. 문제 발생
Riot API와 통신하기 위해 설정한 headers에 필요한 정보를 누락하여 API 요청이 정상적으로 이루어지지 않았는데 이것을 너무 늦게 발견함.
또한, Riot API 키는 24시간마다 만료되기 때문에 배포된 환경에서 지속적으로 요청을 보낼 수 없는 문제가 발생함.
2. 원인 추론
- headers 설정 오류
Riot API와의 통신에 필요한 headers 값을 일부 누락한 상태로 배포하여, API 요청이 실패됨. - API 키 만료 문제
Riot API 키가 24시간마다 만료되는 제한 사항으로 인해 배포 환경에서 안정적인 요청이 불가능했음. - API 키 타입의 차이
Riot API는 두 가지 키(PERSONAL KEY와 PRODUCTION KEY)를 제공:- PERSONAL KEY: 개인 공부용으로 사용, 요청 제한이 있음(1초 20회, 2분 100회).
- PRODUCTION KEY: 실 서비스용으로 사용, 요청 횟수 제한이 더 완화됨. Riot에 승인 요청 필요.
3. 해결 방안
- headers 수정
코드를 다시 꼼꼼히 살펴보았고, 왜 오랜 시간 내 눈에 안보였는지는 모르겠지만, headers에 누락된 정보들을 넣어줌.
API 키 만료되는 문제 해결
<PERSONAL API KEY와 PRODUCTION API KEY의 차이 이해 및 사용>
- PERSONAL KEY: 개인 프로젝트나 테스트 환경에서 사용. 요청 제한(1초 20회, 2분 100회).
- PRODUCTION KEY: 상용 환경에서 사용. Riot에 요청하여 승인받아야 하며(오래걸림...), 요청 횟수 제한이 더 완화됨.
4. 결과
- Riot API와 통신이 정상적으로 이루어지며, 누락된 headers 값을 수정한 후 데이터 요청이 성공적으로 처리됨.
교훈 및 개선점
공식 문서를 좀 더 꼼꼼히 확인하고, 코드를 공식 문서에서 따라 칠 때는 특히 코드 검수가 항상 꼼꼼히 이뤄지도록 해야함. 이런 외부 데이터를 응답받아 사용할 떄는 더더욱 코드 작성할 떄 정확하게 해야 나중에 배포 시에 곤란해지지 않음... 항상 배포할 떄 여유롭게!!! 시간을 좀 넉넉히 두고!!! 배포를 진행해야겠음. 생각보다 배포할 떄 여러 문제가 생기고 예상하지 못한 문제들 떄문에 많은 시간을 쏟게 되는 것 같음.