UI 컴포넌트 통합을 통한 프론트엔드 유지보수성 개선
서비스의 규모가 커짐에 따라 사용자에게 노출되는 UI 컴포넌트의 일관성을 유지하는 것은 개발자에게 중요한 도전 과제가 됩니다. 특히 블로그나 SNS와 같이 게시물 카드가 다양한 페이지에서 반복적으로 사용되는 경우, 이를 관리하는 로직이 파편화되면 사소한 디자인 변경에도 막대한 비용이 발생하게 됩니다.
본 글에서는 서버 사이드 렌더링(SSR)과 클라이언트 사이드 렌더링(CSR)으로 나뉘어 있던 게시물 렌더링 로직을 하나의 JavaScript 클래스로 통합하여 유지보수성을 극대화한 과정을 공유하고자 합니다.
파편화된 로직의 한계
기존 시스템에서는 게시물을 표시하기 위해 두 가지 방식을 병행하여 사용해왔습니다.
-
서버 사이드 렌더링: 초기 페이지 로딩 시 Thymeleaf 프래그먼트(
postitem.html,postview.html)를 사용하여 HTML을 생성했습니다. -
클라이언트 사이드 렌더링: ‘더보기’ 기능이나 새로운 글 작성 시 비동기로 데이터를 가져와 JavaScript 내부의 문자열 템플릿을 통해 HTML을 생성했습니다.
이러한 병행 구조는 다음과 같은 명확한 문제점을 야기했습니다.
-
중복 코드의 발생: HTML 구조가 변경될 때마다 타임리프 템플릿과 JavaScript 내부 코드를 동시에 수정해야 했습니다.
-
이벤트 바인딩의 복잡성: 좋아요 처리나 ‘더보기’ 버튼의 동작 등 상호작용 로직이 여러 파일(
like.js등)에 흩어져 있어 흐름을 파악하기 어려웠습니다. -
UI 불일치: 두 로직 중 하나라도 누락될 경우, 페이지마다 게시물의 모양이나 동작이 미세하게 달라지는 문제가 발생했습니다.
해결책: Postcard 클래스 기반의 컴포넌트화
게시물의 HTML 생성, 데이터 바인딩, 그리고 이벤트를 단일 지점에서 관리하기 위해 Postcard 클래스를 도입하는 리팩토링을 단행했습니다.
1. 캡슐화를 통한 책임의 통합
postcard.js에 정의된 클래스는 게시물 데이터를 생성자(Constructor)로 전달받아, 해당 데이터에 기반한 HTML 생성부터 마크다운 렌더러(Toast UI Editor) 초기화, 그리고 좋아요 처리 로직까지 모두 스스로 관리합니다.
이로 인해 기존에 별도 파일로 존재하던 like.js의 전역 함수는 Postcard.handleLike() 메서드로 내재화되었으며, 전역 오염을 방지하고 응집도를 높일 수 있었습니다.
2. 템플릿의 단일화
모든 페이지에서 Postcard.createHTML() 메서드를 호출하도록 구조를 변경했습니다. 이제 메인 피드든, 게시물 상세 페이지의 댓글 영역이든 상관없이 동일한 클래스 인스턴스를 통해 일관된 UI를 보장받게 되었습니다.
리팩토링 과정과 성과
이번 리팩토링을 통해 프로젝트 전반에 걸쳐 대대적인 코드 정리가 이루어졌습니다.
-
레거시 코드 제거: 더 이상 사용하지 않는 타임리프 프래그먼트 파일들과 중복된 좋아요 처리 스크립트를 삭제하거나
Deprecated처리하여 프로젝트의 복잡도를 낮추었습니다. -
선언적인 렌더링:
index.html과viewer.html에서는 복잡한 HTML 문자열 대신card.render()라는 명확한 명령어를 통해 UI를 구성하게 되었습니다. -
상태 관리의 최적화: 좋아요 상태 변경 시
onLikeChange콜백을 통해 외부 상태와 동기화할 수 있는 인터페이스를 갖추어, 데이터 흐름이 더욱 투명해졌습니다.
마치며
프론트엔드 프레임워크를 사용하지 않는 환경에서도 클래스 기반의 컴포넌트 설계는 코드의 품질을 획기적으로 개선할 수 있는 강력한 도구입니다. 이번 통합 작업을 통해 ‘하나의 기능을 수정하기 위해 여러 파일을 뒤져야 하는’ 비효율에서 벗어나, 게시물 카드라는 단일 컴포넌트의 생명주기를 한 곳에서 통제할 수 있게 되었습니다.
기술적 부채를 해결해 나가는 과정은 결국 더 빠른 기능 배포와 안정적인 서비스 운영으로 이어질 수 있습니다.
링크:
링크: » 일본어로 보기 (日本語で見る)
링크: » 영어로 보기 (Switch to English)
공유: