집 나간 네트워크는 돌아왔는데 React.lazy는 왜 안 돌아올까

5 hours ago 2

들어가며 파트너(업주)님이 영업 내내 주문을 받는 배민주문접수 웹뷰를 개발하던 중 QA 과정에서 네트워크 OFF -> ON으로 변경 후 다른 화면으로 이동 시 오류 화면이 노출된다는 티켓을 전달받았습니다. 원인을 파악해 보니 브라우저가 모듈 로드 실패를 기억하고 있었고, 이는 버그가 아니라 HTML 스펙에 명시된 동작이었습니다. 더 곤란한 것은 프런트엔드 빌드 도구인 Vite 공식 문서가 안내하는 해결책 중 하나가 새로고침이었다는 점입니다. 배민주문접수 웹뷰는 새로고침을 하면 앱 상태가 초기화되는 SPA(single page application)라 그 방법을 사용할 수 없었습니다. React.lazy 사용을 통째로 포기했다가 되살린 과정을 공유합니다. 실패를 기억하는 곳을 찾아가기 네트워크는 복구됐는데 화면은 그대로였다 배포일이 이틀 앞으로 다가온 시점이었습니다. 지체할 시간 없이 곧바로 티켓의 증상 재현에 나섰습니다. 앱을 켠 상태에서 네트워크 연결을 해제합니다. 다른 화면으로 이동합니다. 네트워크를 다시 연결합니다. "오류가 발생했습니다." 페이지가 보입니다. 어느 화면으로 이동해도, 몇 번을 다시 시도해도 같습니다. 네트워크는 이미 정상인데 왜 계속 실패하는 것인지 궁금했습니다. Sentry를 확인해 보니 모듈을 받아오지 못했다는 에러가 여러 화면에 걸쳐 쌓여 있었습니다. 당시 배민주문접수 웹뷰는 화면(라우트) 단위로 React.lazy와 dynamic import를 사용하여 코드 스플리팅을 하고 있었습니다. // pages/Foo/index.ts export default lazy(() => import('./ui/Foo')); 네트워크 연결이 끊어진 동안 아직 로드되지 않은 화면으로 이동하면 dynamic import가 실패했습니다. 여기까지는 예측할 수 있는 실패였습니다. 문제는 네트워크가 돌아온 뒤에도 계속 실패한다는 점이었습니다. React.lazy 재시도가 통하지 않았다 처음 의심한 것은 React.lazy였습니다. React 공식 문서에는 Promise와 그 결과가 캐시되어 load 함수가 중복 호출되지 않으며, 실패 시 가장 가까운 ErrorBoundary로 에러를 전달한다고 안내합니다. 한 번 실패한 뒤에 다시 시도할 방법이 있는지 문서만으로 알 수 없어서 React 리포지토리의 ReactLazy.js를 열어 봤습니다. React.lazy 컴포넌트는 내부에 상태 하나를 들고 있...

Read Entire Article