처음으로 제대로 된 프론트엔드 직장을 다녔던 때를 떠올리면 아직도 마음이 쓰립니다.
완전히 코딩 초보는 아니었어요. 학교에서 풀스택 프로젝트도 꽤 해봤죠.
하지만 실무 경험은 전혀 없었습니다. 실제 트래픽도 없었고, 사용자 이탈을 걱정하며 QA가 압박하는 상황도 겪어본 적이 없었죠.
회사에 들어가 보니, 이커머스 홈페이지는 체감상 정말 느렸습니다.
QA는 매주 같은 메시지를 남겼어요.
"홈페이지 또 느려요 😭"
"히어로 영역 + 상품 그리드 로딩 너무 오래 걸려요"
"3초 넘게 걸려서 유저들이 떠나요"
리포트를 열어보면 끔찍한 워터폴이 보였고, 저는 그저 멍해질 수밖에 없었습니다.
스택만 보면 최신이었어요: S3 + CloudFront + SPA.
“모듈화”를 위해 추천 영역이나 배너 같은 부분은 iframe으로 구성되어 있었습니다.
이론상으로는 플러그 앤 플레이 구조였죠. 하지만 실제로는 무겁고 깨지기 쉬운 시스템이었습니다.
뭔가 잘못됐다는 건 느꼈지만, 그걸 설명할 언어가 없었습니다.
각 iframe이 사실상 거대한 중복 의존성 그래프를 드러내고 있다는 걸 그땐 몰랐죠.

하나의 SPA는 처음 만들 때는 정말 깔끔해 보입니다.
하나의 앱, 하나의 배포.
상품 리스트, 상세 페이지, 이벤트, 프로모션… 전부 한 곳에 넣으면 되죠.
다른 곳에서 재사용하고 싶으면 iframe으로 감싸서 넣으면 끝.
빠르고 실용적인 선택처럼 보입니다.
하지만 그게 함정입니다.
iframe은 단순히 UI를 임베드하는 게 아닙니다.
런타임 전체를 임베드하는 것입니다.
우리는 단순히 "배너"를 넣은 게 아니라,
거대한 React 애플리케이션을 작은 창 안에 또 하나 띄우고 있었던 겁니다.
각 “모듈”은 사실상 새로운 앱 인스턴스를 브라우저에서 다시 부팅하게 만들고 있었어요.
이 시스템은 기술적으로는 최신이었지만, 구조적으로는 과부하 상태였습니다.
iframe이 문제를 만든 게 아니라, 문제를 숨길 수 없게 만든 것이었습니다.

이 문제는 보통 여기서 가장 먼저 드러납니다.
유저는 단순한 프로모션 페이지를 열었을 뿐인데,
브라우저는 전체 쇼핑몰 애플리케이션을 다운로드합니다.
상품 목록 로직, 상세 페이지, 이벤트 처리, 라우팅, 공통 컴포넌트…
시간이 지나며 쌓인 모든 것들이 포함됩니다.
즉, 키오스크 하나 보려고 쇼핑몰 전체를 로딩하는 셈입니다.
모놀리식 SPA는 기능이 늘어날수록 번들이 커지기 때문에 이런 문제가 생깁니다.
결과적으로:
iframe은 이 불일치를 눈에 보이게 만들었습니다.
작은 화면 하나를 위해 전체 앱을 초기화해야 했고,
그 비용을 페이지 내에서 여러 번 반복해서 지불하게 만든 거죠.
핵심 문제:
UI는 작아 보이지만, 실제 런타임 비용은 거대하다.
그리고 iframe은 이 거짓말을 드러냈다.

두 번째 문제는 더 미묘해서 더 오래 방치되기 쉽습니다.
문제의 시작은 클라이언트 렌더링 SPA였습니다.
검색 엔진이 JavaScript를 실행할 수는 있지만,
핵심 콘텐츠를 여기에 의존하는 건 위험한 선택입니다.
iframe은 여기에 한 단계 더 복잡성을 추가했습니다.
SPA 자체도 인덱싱이 불안정한데,
iframe으로 콘텐츠를 분산시키면서 더 어려워진 겁니다.
중요한 포인트는 이겁니다:
iframe을 제거해도 문제가 해결되진 않습니다.
핵심은 서버에서 콘텐츠를 렌더링하는 것(SSR) 입니다.
한동안 저는 이걸 단순히 “성능 문제”라고 생각했습니다.
그래서 네트워크 지연, 이미지 용량, CDN 캐시 같은 것들을 살폈죠.
물론 중요했습니다.
하지만 본질은 아니었습니다.
진짜 문제는 아키텍처의 형태였습니다.
앱은 너무 많은 책임을 가지고 있었고,
너무 많은 코드가 공유되고 있었으며,
하나의 배포 단위에 너무 많은 것이 들어 있었습니다.
iframe은 문제를 만든 게 아니라,
그걸 여러 번 실행하게 만들어서 드러낸 것뿐이었습니다.
그때 깨달았습니다.
문제를 잘못 보고 있었다는 것을.
그래서 매니저에게 요청했습니다.
단순한 최적화가 아니라, 구조적인 개선을 하자고요.
이 대화는 코드만큼 중요했습니다.
우리는 완전히 새로 만들지 않았습니다.
마이크로 프론트엔드로 전환하지도 않았습니다.
대신 시스템을 작고, 깔끔하게 만들었습니다.
사용되지 않는 코드들을 제거했습니다.
이건 사소해 보이지만,
죽은 코드도 여전히 다운로드되고, 파싱되고, 실행됩니다.
빌드 속도를 개선했습니다.
이건 단순히 시간을 절약한 게 아니라,
개발 방식 자체를 바꿨습니다.
빌드가 빠르면:
필요한 것만 로딩하도록 했습니다.
"지금 필요 없는 기능은 다운로드하지 않는다"
이 단순한 원칙이 큰 변화를 만들었습니다.
결과는 명확했습니다.
이건 단순한 숫자가 아닙니다.
팀의 행동 자체를 바꿉니다.
브라우저가 로딩해야 하는 것을 줄여라.
iframe이 문제인 게 아닙니다.
SPA가 문제인 것도 아닙니다.
문제는 이겁니다:
거대한 모놀리스를 여러 번 로딩하는 구조
좋은 구조는 보통 다음을 포함합니다:
이 프로젝트에서 가장 어려웠던 건 코드가 아니라 인정이었습니다.
아키텍처가 문제라는 걸 인정하는 것.
문제를 버그 단위로 보지 않고 패턴으로 보기 시작했을 때,
비로소 해결의 방향이 보였습니다.
이글은 원문을 번역했습니다. 원문도 제가 작성했습니다: https://dev.to/deadlocker/i-joined-my-first-job-and-the-homepage-took-forever-to-load-e9o