Frontend
글 13편
-
죽은 파일이 살아있는 파일보다 최신이었다
감사의 목적은 번들 축소가 아니었다 죽은 코드 감사를 시작한 이유는 흔한 것 — 번들 크기나 파일 수 — 이 아니었다. “죽은 코드를 살아있다고 착각하고 거기에 작업하는 사고”를 막는 것이 목적이었다. 계기는 그 사고가 이미 여러 번 일어났기 때문이다. 조사해보니 2주 동안 같은 ...
-
같은 버그를 두 번 고친 날, V1/V2 이중 스택을 정리하기로 했다
계기: 같은 버그를 양쪽에서 따로 고쳤다 한 화면에 V1과 V2 두 벌의 구현이 공존하고 있었다. 신규 작성 화면은 V2를 쓰고, 월 업데이트 화면은 V1을 쓰는 식이었다. 카테고리 상태가 어긋나는(desync) 버그가 나왔을 때, 이걸 V1 쪽에서 고치고 며칠 뒤 V2 쪽에서 또...
-
엑셀 라이브러리가 두 개였다 — xlsx에서 exceljs로 통일하기
문제 한 프로젝트 안에서 엑셀을 내보내는 경로가 두 개였고, 각각 다른 라이브러리를 쓰고 있었다. 경로 라이브러리 헤더 스타일 AG Grid export xlsx 불가 리포트 export exceljs 적용됨 xlsx(SheetJS)의 커뮤니티 버전은 셀 스타일을 지원하지 않는다....
-
PDF 다운로드가 7초 걸렸는데, 범인은 한글 폰트였다
문제 제품 배출량을 산정하는 B2B 웹앱에서 결과 리포트를 PDF로 내려받는 기능이 있었다. 버튼을 누르면 약 7초가 걸렸다. 그동안 화면은 로딩만 돌고 아무 일도 일어나지 않는다. 사용자가 “먹통이 됐나” 하고 다시 누르기 충분한 시간이다. 구현은 @react-pdf/render...
-
RTK Query 워터폴을 평탄화하고, 캐시를 켜자 stale이 드러났다
문제 대시보드 탭 하나를 여는 데 요청이 직렬로 줄줄이 이어졌다. summary 조회 → 첫 제품 자동 선택 → 해당 제품의 LCA 선택 → 상세 데이터 호출 각 단계가 앞 단계의 응답을 기다린 뒤에야 시작된다. 전형적인 워터폴이다. 게다가 이 API 그룹은 keepUnusedDa...
-
AG Grid의 autoHeight는 행 가상화를 끈다
문제 입출력 데이터를 입력하는 그리드 화면이 있었다. 행이 수백 개인 상황에서 셀 하나를 편집할 때마다 눈에 띄게 버벅였다. 값을 타이핑하는 속도를 화면이 못 따라오는 수준이었다. 원인 1: 편집할 때마다 columnDefs가 통째로 재생성됐다 columnDefs를 useMemo로...
-
TanStack Query에서 로그아웃은 토큰만 지우는 게 아니다
문제: 로그아웃했는데 이전 사용자 데이터가 보인다 같은 백엔드를 쓰는 쌍둥이 Next.js 프론트엔드 — 관리자 포털과 사용자 포털이다. 두 앱 모두 인증은 Zustand, 서버 상태는 TanStack Query로 나눠 관리한다. 이 분리 자체는 흔하고 합리적인 구성이다. 문제는 ...
-
localStorage에 남은 isAuthenticated: true가 로그인을 막았다
문제: 로그인 페이지가 “로딩 중…“에서 안 넘어간다 사용자 포털에서 올라온 버그다. 한동안 안 쓰다가 다시 들어오면 로그인 화면이 “로딩 중…“만 띄운 채 멈춘다. 폼이 안 나오니 로그인할 방법이 없다. localStorage를 비우면 정상으로 돌아왔다. localStorage를...
-
invalidateQueries를 refetchQueries로 바꿨더니
문제: mutation 후 목록이 즉시 안 바뀐다 관리자 포털과 사용자 포털 양쪽에서 같은 QA 피드백이 반복됐다. 항목을 삭제하거나 생성했는데 목록이 그대로다. 탭을 옮겼다 오거나 새로고침하면 그제야 반영된다. mutation 성공 후 invalidateQueries를 호출하고 ...
-
게이트웨이가 죽었는데 사용자가 F5를 누른다 — 브라우저 서킷 브레이커
문제: 새로고침이 서버를 한 번 더 때린다 같은 백엔드를 공유하는 쌍둥이 Next.js 프론트엔드가 있다. 관리자 포털과 사용자 포털. 게이트웨이가 502/503/504를 뱉으면 두 앱 모두 전역 오버레이를 띄워 “잠시 후 다시 시도해 주세요”라고 안내하고 있었다. 문제는 그 다음...
-
navigator.clipboard는 HTTPS에서만 동작한다
문제: 복사 버튼이 아무 반응이 없다 관리자 포털의 대시보드 화면에는 토큰을 복사하는 버튼이 있다. 로컬에서는 잘 됐다. 배포 환경에 올리니 버튼을 눌러도 아무 일도 일어나지 않았다. 에러 토스트도 없고 콘솔에도 아무것도 안 찍혔다. 원인은 코드가 아니라 배포 환경이다. 이 시스템...
-
탭 상태를 useState에 두지 마라 — URL 파생 상태로 바꾸기
문제: 사이드 메뉴로 이동하면 탭이 안 바뀐다 관리자 포털의 여러 목록 화면이 탭을 갖고 있다. 탭 상태는 ?tab= 쿼리 파라미터에 실려 있어서 링크 공유와 새로고침이 된다. 이걸 담당하는 게 useTabQuery 훅이었다. QA에서 올라온 증상은 이랬다. 사이드 메뉴에 ?tab...
-
사이드바 권한 분기 100줄을 지우고 ICON_MAP만 남기다
문제: 사이드바가 권한을 안다 사용자 포털의 사이드 메뉴는 상수 배열로 하드코딩돼 있었다. 두 그룹의 메뉴가 파일 안에 박혀 있고, 각 항목에 permission 문자열이 붙어 있다. const OAUTH_MENU_ITEMS = { IAM: { label: "IAM 관리", ico...