일반적으로 서비스를 고객들에게 제공하기 위해 필요한 요소들이 있습니다. 첫 번째는 서비스 페이지로 주로 앱이나 웹의 프론트엔드에서 직접 고객들에게 보여지는 부분이고, 두 번째로 서비스 페이지를 구축하기 위한 데이터를 제공하는 백엔드가 필요합니다. 마지막으로 백엔드가 제공하는 데이터를 관리하는 콘텐츠 관리 시스템입니다.

급변하는 시장 상황과 고객의 요구에 빠르게 대응하기 위해, 때로는 비즈니스 타이밍을 맞추기 위해 설계 단계에서 충분히 고려되지 못한 부분을 구현해 적용한 경험은 누구나 있을 겁니다. 이처럼 미처 고려되지 못했던 기능들이 추가되고, 급하게 구현된 코드들이 쌓이면서 기술 부채와 레거시가 증가하게 돼 결국 유지보수 비용을 증가시키는 요인이 되었습니다.
미처 설계에 충분히 고려되지 못했던 부분이나 급하게 대응한 부분은 앱/웹 프론트엔드뿐만 아니라 백엔드, 콘텐츠 관리 시스템, 심지어는 데이터베이스와 인프라에 이르기까지 광범위하게 발생했습니다.
특히 서비스 변화의 최전선에 있는 프론트엔드와 백엔드는 항상 최선의 선택을 해왔지만, 기술 부채와 레거시가 누적되면서 유지보수 비용 증가와 생산성 감소라는 문제에 직면하게 됐습니다. 무엇보다 프론트엔드의 UI 구성을 위한 데이터와 백엔드의 비즈니스 데이터가 강하게 결합되고, 심지어 동일한 데이터를 가지고도 프론트엔드 플랫폼별로 다른 비즈니스 로직을 구현하는 사례도 있었습니다. 이러한 문제는 서비스의 확장성과 유지 보수성을 저해하는 주요 요인이 되었습니다.
리디는 앞서 언급한 문제점들을 해결하고 보다 효율적인 서비스 운영 환경을 구축하기 위해, ‘어떻게 하면 좀 더 효율적으로 서비스를 운영할 수 있을까?’라는 질문에 대한 해답을 찾기 위해 노력해왔습니다. 그리고 그 해답을 찾는 과정에서 핵심적인 문제점을 발견했습니다. 바로 비즈니스 로직 데이터와 UI 데이터의 강결합이었습니다.
...
"property": {
"is_adult_only": false,
"is_magazine": false,
"is_new_book": false,
"is_novel": false,
"is_open": true,
"is_somedeal": false,
"is_trial": false,
"is_wait_free": false,
"use_free_serial_schedule": false,
"preview_rate": 0
},
...
기존 API 의 UI 에서 사용하는 작품의 배지 표현을 위한 데이터
{% if option.new_release_badge and book.is_new_book %}
{# 모든 배지 중 최우선 #}
<span class="bdage_new_release">
<span class="new_text">NEW</span>
</span>
{% endif %}
기존 웹 Twig Book Macro에서 신간(NEW) 배지를 표현하는 코드
API의 뱃지 정보와 프론트엔드 코드의 뱃지 표현 방식이 강하게 결합되면, API 스펙 변경 시마다 프론트엔드 코드를 수정해야 합니다. 이는 유지보수 및 확장성을 저하시키고, 코드 재사용성을 떨어뜨립니다. 따라서 비즈니스 로직의 데이터와 UI 데이터를 분리해 API와 프론트엔드 코드의 결합도를 낮추는 것이 중요합니다.
“기다리면 무료”로 이용할 수 있는 작품을 뜻하는 배지를 노출하기 위해서는 is_wait_free: boolean 속성이 필요합니니다. 해당 배지를 추가하기 위한 API 에 property.is_wait_free 라는 응답이 더해졌고 이에 따라 여러 부분의 대응이 진행됐습니다.
{% if book.is_wait_free %}
<span class="bdage_wait_free">
<span class="svg_timer">기다리면 무료</span>
</span>
{% endif %}
기존 웹 Twig Book Thumbnail Macro에서 기다리면 무료 배지를 표현하는 코드
if (isWaitFree) {
return (
<Badge className="badge" backgroundColor={dodgerBlue50} size={size}>
<WaitFree viewBox="0 0 20 18" preserveAspectRatio="xMidYMid meet" aria-label="리디 기다리면 무료" />
</Badge>
);
}
기존 웹 React Book Component 의 BookBadgeRenderer에서 기다리면 무료 배지를 표현하는 코드
이렇게 “기다리면 무료”를 나타내는 배지를 표현하기 위한 비즈니스 로직 데이터와 UI 를 표현하기 위한 데이터가 점차 강결합되면서 “기다리면 무료” 배지 표시 로직이 프론트엔드 코드에 복잡하고 다양하게 얽히게 됩니다.
이는 API 스펙을 변경할때 마다 프론트엔드 코드 수정을 유발해 유지보수 비용을 증가시키고, 코드 재사용성을 떨어뜨리는 문제를 야기합니다. 또한, “기다리면 무료” 관련 기능 확장이 어려워지는 등 다양한 문제점을 초래하여, 기능을 확장하거나 변경할 때마다 상당한 개발 비용과 시간이 소요될 수 있습니다. 프론트엔드 코드의 복잡성도 증가하면서 예기치 않은 오류 발생 가능성 또한 높아져 서비스의 안정성을 저해할 수 있습니다.
어떻게 하면 좀 더 효율적으로 서비스를 운영할 수 있을까?
비즈니스 로직 데이터와 UI 데이터의 강결합은 단순히 개발 공수 증가라는 문제뿐만 아니라, 서비스 전반에 걸쳐 아래와 같은 문제점을 야기합니다.
- 유지보수 비용 증가
비즈니스 로직과 UI가 복잡하게 얽혀 있는 경우, 수정 사항 발생 시 연관된 모든 부분을 수정해야 하므로 유지보수 비용이 증가합니다. - 확장성 저하
비즈니스 로직과 UI의 강결합은 서비스 확장을 어렵게 만듭니다. 새로운 기능을 추가하거나 플랫폼을 확장할 때, 기존 코드와의 호환성을 고려해야 하므로 개발 속도가 느려지고, 예상치 못한 오류가 발생할 가능성이 높아집니다. - 테스트 복잡성 증가
비즈니스 로직과 UI가 결합된 상태에서는 각 부분을 독립적으로 테스트하기 어렵습니다. 이는 테스트 과정의 복잡성을 증가시킵니다.
리디의 여러 구글 출신 엔지니어들은 문제해결의 실마리를 구글에서 많이 활용하던 서버 주도 UI (Server Driven UI)에서 찾았습니다.
서버 주도 UI는 UI의 정의, 로직, 데이터 처리를 서버에서 주도적으로 관리하는 아키텍처입니다. 서버는 UI 구성 요소, 레이아웃, 데이터 바인딩 등을 정의하고, 클라이언트는 서버에서 제공하는 UI 정의와 데이터를 기반으로 화면을 렌더링합니다. 이를 통해 빠른 개발 및 배포, 다양한 플랫폼 지원, 유연한 A/B 테스트, 개인화된 경험 제공 등의 장점을 누릴 수 있습니다. 하지만 서버 부하 증가, 네트워크 의존성 심화, 복잡한 아키텍처 등의 단점도 고려해야 합니다.
에어비앤비와 토스의 경험
에어비앤비는 ‘Ghost Platform’을 통해 서버 주도 UI를 구현합니다. 표준화된 GraphQL 스키마를 기반으로 모든 플랫폼에서 일관된 UI를 제공합니다. 핵심은 ‘섹션’과 ‘스크린’ 개념입니다. ‘섹션’은 재사용 가능한 UI 컴포넌트이며, ‘스크린’은 섹션의 레이아웃을 구성합니다. 이 구조로 에어비앤비는 유연하고 효율적인 동적 인터페이스를 구축합니다.
토스 홈팀은 “HomeDST (Home Design Syntax Tree)”를 도입하여 서비스 운영을 효율화했습니다. HomeDST는 서버에서 UI 구성, 레이아웃, 데이터 바인딩을 정의하고, 클라이언트는 이를 렌더링합니다. 앱 업데이트 없이 서버에서 UI 변경이 가능하며, 디버깅이 용이합니다. 또한, 사용자 경험을 개선하고 기능 추가 및 버그 수정을 빠르게 처리할 수 있습니다.
RiGrid 란?
“RiGrid”는 리디(RIDI)와 그리드(Grid)를 결합한 단어로, 리디의 이름과 그리드 시스템을 연상시키는 합성어입니다. 리디 콘텐츠 표준화 프로젝트로 이런 ‘어떻게 하면 좀 더 효율적으로 서비스를 운영할 수 있을까?’란 고민을 해결하기 위해 시작되었습니다.

RiGrid의 원칙과 설계
리디는 효율적이고 확장 가능한 프론트엔드 개발을 위해 RiGrid라는 핵심 원칙을 기반으로 시스템을 구축했습니다. RiGrid는 데이터와 UI의 분리, Grid 기반의 레이아웃, Cell 단위 모듈화, 그리고 표준화된 데이터 표현 방식을 통해 변화에 유연하게 대응할 수 있습니다.
- 비즈니스 데이터와 UI 데이터를 분리
비즈니스 데이터와 UI 데이터를 명확히 분리하여 관리합니다. 이는 데이터 재사용성, 테스트 용이성, 유지보수성, 확장성을 향상시키고 변화에 유연한 대응을 가능하게 합니다. - Grid 기반 구조 설계
모든 페이지는 Grid라는 기본적인 틀 안에서 구성됩니다. Grid는 페이지 레이아웃을 정의하며, 다양한 종류의 Cell을 담을 수 있는 공간을 제공합니다. - Cell 단위 모듈화
Grid 안에는 다양한 종류의 Cell을 배치하여 페이지를 구성합니다. Cell은 모듈화된 컴포넌트 형태로 개발돼 재사용성을 높이고, 개발 생산성을 향상 시킵니다. - 표준화된 데이터
Grid와 Cell에 사용되는 모든 데이터는 IR (Intermediate Representation)이라는 중간 표현의 개념으로 표준화된 형태로 표현됩니다. IR은 데이터의 구조와 의미를 명확하게 정의하여 데이터 호환성과 재사용성을 높입니다.
리디는 REST API 기반의 파편화되어 있는 MSA(Microservice Architecture)를 보다 효율적인 구조로 통합하고 있습니다. 이 과정에서 프론트엔드와 백엔드의 개발 생산성 및 효율성을 극대화하기 위해 BFF(Backend For Frontend) 패턴을 도입하고, 프론트엔드에서 사용될 API 인터페이스를 GraphQL로 채택하여 확장 중입니다.
RiGrid 역시 이러한 흐름에 발맞춰 GraphQL의 다양한 장점을 적극적으로 활용하고자 GraphQL 기반으로 백엔드를 구축하였습니다. RiGrid에서 GraphQL을 사용하면서 고려한 주요 장점들은 다음과 같습니다.
- 명확한 Schema 기반의 인터페이스 설계
GraphQL은 Schema를 기반으로 API의 인터페이스를 명확하게 정의합니다. 이는 개발자들이 API의 구조와 사용법을 쉽게 이해하고, 오류를 줄이는 데 도움을 줍니다. 또한, Schema는 API 문서 자동 생성에도 활용될 수 있어 개발 생산성을 높이는 데 기여합니다. - 기존 GraphQL 자원의 재사용 가능
리디는 이미 GraphQL로 구현된 다양한 자원들을 보유하고 있었습니다. RiGrid 백엔드를 GraphQL로 구현함으로써 기존 자원들을 재사용할 수 있게 되었고, 이는 개발 시간과 비용을 절약하는 데 큰 도움이 됩니다. - GraphQL 서버 관리의 용이성
GraphQL 서버는 다양한 기능을 제공하며, 서버 관리를 용이하게 해주는 도구들도 많습니다. RiGrid 백엔드를 GraphQL로 구현함으로써 서버 관리 효율성을 높이고, 개발자들이 서비스 개발에 집중할 수 있도록 환경을 조성했습니다. - 필요한 데이터만 응답받는 경량화와 유연성
GraphQL은 클라이언트가 필요한 데이터만 요청하고 응답받을 수 있도록 지원합니다. 이는 불필요한 데이터 전송을 줄여 네트워크 트래픽을 감소시키고, 클라이언트 성능을 향상시키는 데 기여합니다. 또한, GraphQL은 다양한 형태의 데이터를 유연하게 요청하고 응답받도록 지원해 개발 생산성을 높입니다.
RiGrid Schema
기본적인 RiGrid의 Schema구조입니다.
type Grid {
...
meta: GridMeta!
cells: [GridCell!]!
...
}
type GridMeta {
...
type: GridType!
layout: GridLayout!
...
}
enum GridType {
BookDetailHome
}
enum GridLayout {
BookDetailHome
}
Grid Schema
- Grid는 layout 과 type 속성을 통해 페이지의 구조와 데이터형을 결정합니다.
interface GridCell {
id: UUID!
layout: CellLayout!
type: CellBindingType!
parent: UUID
order: Int!
}
GridCell Schema
interface BookListCell implements GridCell {
cell: BookList
id: UUID!
layout: CellLayout!
type: CellBindingType!
parent: UUID
order: Int!
}
BookListCell Schema
- 모든 Cell은 GridCell을 구현합니다.
- Cell은 UUID기반으로 고유한 id 값을 가지고 있습니다.
- Cell은 layout 과 type 속성으로 Cell의 구조와 데이터형을 결정합니다.
- Cell들은 리스트로 제공되고 parent 속성과 order 속성을 통해 프론트엔드에서 트리구조로 관리합니다.
// "BookList"라는 layout 을 렌더링 하는 BookListCell
const BookListCell: CellComponent<'BookList'> = ({ contents }) => {
...
return (
<div>
// BookListCell 의 CellBindingType 에 따라 서버에서 알맞은 title 정보를 전달.
{contents.title && (
<Title>
<span>{contents.title}</span>
{contents.moreDetails?.path && (
<a href={contents.moreDetails.path} css={styles.moreDetailsStyles}>
더보기
</a>
)}
</Title>
)}
// BookListCell 의 CellBindingType 에 따라 서버에서 알맞은 작품 리스트 데이터를 전달.
<BookList books={contents.books} />
</div>
);
};
BookListCell 의 프론트엔드 구현의 일부
BookListCell 컴포넌트는 BookList 레이아웃을 기반으로 렌더링되며, type 속성 값에 따라 다양한 데이터를 표시합니다. type 속성은 BookListCell 컴포넌트가 어떤 종류의 작품 목록을 보여줄지 결정하는 역할을 합니다. 예를 들어, type이 “KeywordBookList”라면 특정 키워드를 포함하는 작품 목록을 렌더링하고, “AuthorBookList”라면 특정 작가의 대표 작품 목록을 렌더링합니다.

(위 이미지에 포함된 작품 표지는 내용 전달을 위해 임의로 구성하였습니다.)
RiGridQuery
- 기본적으로 단일 RiGridQuery를 사용하여 특정 그리드 정보와 모든 셀의 스키마를 요청하며, APQ(Automatic Persisted Queries)를 통해 페이로드를 최적화합니다.
- 서버는 요청받은 Grid 정보를 확인한 후, 해당 Grid에 설정된 Cell 들을 구성하여 응답합니다.
RiGrid 구현에서 특이점
- Grid 내 Cell 정보 응답 방식의 비효율성 개선
- 문제점: Grid를 구성하는 모든 Cell 정보를 한 번에 응답하는 방식은 대량의 Cell로 구성된 Grid의 경우 백엔드와 프론트엔드 모두에 과부하를 초래할 수 있었습니다.
- 해결 전략: 백엔드에서 특정 Cell은 비동기로 데이터를 전송하고, 프론트엔드에서는 서버가 지정한 타이밍에 해당 Cell을 렌더링하도록 하여 성능을 개선했습니다. AsyncCell 이라는 Utility Cell 을 도입하여 비동기 렌더링을 가능하게 했습니다.
- 중복 데이터 처리 문제 해결
- 문제점: 작품 상세 페이지 Grid와 같이 일부 Cell들이 동일한 정보를 공유하는 경우 중복 데이터 처리로 인한 비효율이 발생할 수 있었습니다.
- 해결 전략: dataloader 를 도입하여 하나의 요청 내에서만 유효한 중복 쿼리를 제거했습니다. 이를 통해 데이터 접근 횟수를 줄여 성능을 향상시켰습니다.
- 캐싱 전략 도입
- 문제점: 잦은 데이터 요청으로 인한 서버 부하 증가 및 성능 저하가 발생할 수 있었습니다.
- 해결 전략: DataLoader뿐만 아니라 Redis를 이용한 캐싱 전략을 도입하여 성능과 서버 자원 효율성을 증대했습니다.
- 프론트엔드 Grid-Cell 구조 관리
- Tree 구조 재구축: 프론트엔드에서는 서버에서 응답받은 Grid 정보와 Cell 목록을 트리 구조로 재구축합니다.
- 트리 순회 및 컴포넌트 렌더링: 트리를 순회하면서 Cell 정보를 확인하고, 해당 정보에 매핑되는 Cell 컴포넌트를 렌더링합니다.
- 페이지 구성을 위한 Utility Cell 도입
- AsyncCell: 비동기 렌더링을 위한 Utility Cell입니다. AsyncCell로 감싸진 하위 Cell은 서버에서 지정한 렌더링 타이밍에 맞춰 비동기로 렌더링 됩니다.
- ChildCells: RiGrid의 Cell in Cell 구조에서 하위 Cell 렌더링에 사용됩니다.
- FlexColumnCell: Cell in Cell 구조에서 같은 위상의 Cell들의 배치를 관리합니다.
- Cell의 layout과 type 활용
- layout: 서버가 Cell이 그려지는 컴포넌트를 제어합니다.
- type: 서버가 Cell에 전달되는 데이터를 제어합니다.
- 장점: layout과 type을 통해 같은 컴포넌트를 다른 데이터로 재사용하거나, 같은 데이터를 다른 컴포넌트로 재사용할 수 있어 유연한 확장이 가능합니다.
RiGrid 의 Backward Compatibility
대부분의 스키마 변경은 추가적인 성격을 가져 안전하고 하위 호환성을 유지합니다. 하지만 기존 필드를 제거하거나 변경하는 것은 호환성을 깰 수 있습니다. GraphQL 스키마의 변경으로 인한 호환성 문제는 단일 쿼리 기반의 RiGrid 아키텍처에 매우 치명적인 영향을 미치므로, 하위 호환성 유지는 RiGrid의 핵심 고려 사항입니다.
- 유형 또는 필드 제거: 기존 클라이언트가 해당 유형이나 필드에 의존하고 있다면, 제거 시 오류가 발생할 수 있습니다.
- 유형 또는 필드 이름 변경: 클라이언트 코드는 특정 이름의 유형이나 필드를 참조하므로, 이름 변경 시 해당 부분을 수정해야 합니다.
- 필드에 Nullability 추가: 기존에는 null 값을 허용하지 않던 필드에 null 값을 허용하도록 변경하면, 클라이언트에서 null 처리를 추가해야 할 수 있습니다.
- 필드의 인자 제거: 클라이언트가 특정 인자를 사용하여 필드를 호출하고 있다면, 해당 인자 제거 시 호출이 실패할 수 있습니다.
RiGrid는 위와 같은 잠재적인 문제점을 해결하고 하위 호환성을 유지하기 위해 다음과 같은 전략을 사용합니다.
- 기존 필드 변경 금지: 기존 유형이나 필드를 수정하는 대신, 새로운 필드를 추가합니다.
- 새로운 필드 추가 시 고려사항: 새로운 필드를 추가할 때 IR에 맞는 필드명과 타입, 그리고 기본값에 대해 신중하게 고려합니다.
- 호환성 테스트: 변경된 데이터 스키마가 하위 버전의 클라이언트에 미치는 영향을 테스트하고, 서비스 적용전에 파악해 하위 호환성에 문제를 사전에 방지합니다.
- 문서화: 스키마에 대한 가이드를 명확하게 문서화하여 프론트엔드 개발자가 쉽게 스키마를 이해하고 대응할 수 있도록 지원합니다.
RiGrid 성과
비즈니스 로직 데이터와 UI 데이터의 명확한 분리
기존 리디 서비스의 배지 시스템은 비즈니스 로직 데이터와 UI 데이터가 강하게 결합되어 있어 서비스의 유지보수성, 확장성 및 생산성을 저해하는 요소였습니다. 예를 들어, 새로운 배지 종류를 추가하거나 기존 배지의 노출 조건을 변경하려면 백엔드와 프론트엔드 코드를 모두 수정해야 했습니다. 이는 개발 공수를 증가시키고, 변경 사항이 다른 기능에 미치는 영향을 예측하기 어렵게 만듭니다.
하지만 RiGrid는 배지의 종류, 노출 여부, 노출 순서 등 비즈니스 로직 데이터를 서버에서 관리하고, 프론트엔드는 서버에서 전달받은 데이터를 기반으로 배지를 렌더합니다. 즉, 비즈니스 로직과 UI가 분리된 것입니다.
...
badges {
type
urls
text
backgroundColors {
dark
light
}
}
...
RiGrid Book 관련 쿼리의 배지관련 스키마의 일부
...
"badges": [
{
"type": "WAIT_FREE",
"urls": [
"https://active.ridibooks.com/badge/on_book_cover/waitfree.75df8f279d97b6d70041db9353d66053.png"
],
"text": "리다무",
"backgroundColors": {
"dark": "#1496E6",
"light": "#1E9EFF"
}
},
],
...
RiGrid Book 관련 배지 응답의 일부
...
const badges Rendered = useMemo (() => badgesFiltered.map((badge, index) => ({
...badge,
key: badge?.alt ?? `${String (badge?.type)}-${index}`,
images: badge?.images?.map((src, imageIndex) => (
<img key={imageIndex} className={styles.BadgeRendererImageClass} src={src} alt="" />
)),
}))
}, [badgesFiltered]);
return (
<div className={classNames(styles.BadgeRendererClass, className)}>
{badgesRendered.map(badge => (
<BookBadge background={badge.color?.[theme.colorScheme] ?? 'transparent'} alt=
{badge.alt} key={badge.key}>
{badge.images}
</BookBadge>
))}
</div>
);
...
RiGrid의 웹 Book Component 의 BookBadgeRenderer 코드의 일부
RiGrid의 작품 배지 시스템은 모든 플랫폼에서 동일한 표현을 제공하기 위해 이미지 기반으로 설계되었으며, 특히 할인율과 같은 변수형 배지의 표현에 대응하기 위해 여러 이미지를 조합하여 하나의 배지를 구성하는 방식을 채택했습니다. 이는 확장성과 유지보수성을 높이는 동시에 플랫폼 간 일관성을 확보하기 위한 결정입니다.
RiGrid 기반 작품 상세 페이지, 왜 성능이 떨어질까?

(위 이미지에 포함된 작품은 내용 전달을 위해 임의로 구성하였습니다.)
오픈 전 테스트를 통해 RiGrid 기반 작품 상세 페이지의 성능이 기존 페이지보다 떨어진다는 사실을 인지하고 있었지만, 서비스의 안정성을 고려하여 부분 전환 방식을 선택하게 되었습니다.

부분 전환으로 인한 Middleware의 구조적 한계
- 리디의 작품 상세 페이지는 방대한 정보량과 서비스 측면에서의 중요성 때문에 변경에 신중할 필요가 있었습니다. RiGrid 프로젝트에서는 페이지 전체를 한 번에 전환하는 대신 일부 정보 요소만 RiGrid로 전환하는 전략을 선택했습니다.
- 문제는 부분 전환을 위한 Middleware가 필요하게 되었고, 이 Middleware의 구조적인 한계로 인해 전체 페이지의 latency에 악영향을 미쳤다는 점입니다.
RiGrid, 앞으로 어떻게 개선해야 할까?
작품 상세 페이지의 부분 전환은 서비스 안정성을 위한 불가피한 선택이었지만, 근본적인 성능 개선을 위해서는 전체 전환이 필수적입니다. 리디 고객들은 새로워진 작품 상세 페이지에 긍정적인 반응을 보였고, 리디는 꾸준히 RiGrid 기반으로 작품 상세 페이지 전환 작업을 진행하고 있습니다.
작품 상세 페이지 전체 전환이 완료되면 Middleware의 필요성이 사라지게 됩니다. Middleware는 기존 페이지와 RiGrid 페이지를 연결하는 과정에서 발생하는 병목 현상의 주요 원인 중 하나였기 때문에, Middleware 제거는 성능 개선에 핵심적인 역할을 할 것으로 기대됩니다.

RiGrid 기반의 새로운 업무 수행 방식
마케팅용 랜딩 페이지와 검색 페이지를 추가로 RiGrid 로 전환하면서 효율성, 생산성, 협업, 확장성 측면에서 좋은 성과를 거두었습니다.
- 협업 효율성 극대화
기획 단계에서부터 Cell 단위로 UI를 설계함으로써 UI 구조를 명확하게 정의할 수 있게 되었습니다. 이는 기획, 디자인, 개발팀이 UI 구조를 공유하고 함께 논의하는 과정을 통해 상호 이해도를 높이고, 개발 과정에서의 오류를 줄이는 데 크게 기여했습니다. 또한 다양한 형태의 콘텐츠를 일반화하고 재사용 가능한 UI를 원칙으로 합의해 디자인의 재사용성을 높여 작업 효율성을 향상시켰고 개발팀과의 협업 과정에서 디자인 변경에 대한 부담을 줄여 원활한 소통을 가능하게 했습니다. - 빠른 개발 속도
이미 정의된 RiGrid 스키마를 기반으로 프론트엔드 개발을 선제적으로 진행하여 백엔드 개발 완료 시점에 맞춰 실제 데이터를 적용하는 데 큰 문제가 없었습니다. 이는 병목 현상 감소 및 개발 기간 단축으로 이어졌습니다. - 유연한 레이아웃 구성 및 효율적인 콘텐츠 관리와 실험의 용이성
RiGrid의 유연한 구조는 다양한 Cell 조합을 가능하게 하여 마케팅용 랜딩 페이지의 레이아웃을 효과적으로 구성하는 데 기여했습니다. 또한, Cell 단위의 관리 및 조합 기능은 콘텐츠 관리를 용이하게 하고 운영 효율성을 높였습니다. Cell 단위의 조합과 레이아웃 구성으로 다양한 형태의 페이지를 손쉽게 만들어낼 수 있고, 이를 통한 실험으로 고객의 반응을 효과적으로 측정할 수 있게 되었습니다. - Server Driven 방식의 장점 및 확장성 검증
검색 페이지 개발에서는 UI 개발 생산성 향상이라는 긍정적인 효과를 가져왔습니다. 프론트엔드 개발자는 비즈니스 로직에 얽매이지 않고 UI 구현에만 집중하여 더 빠르고 효율적으로 작업할 수 있었습니다. 백엔드 개발자는 기존 REST API 개발 방식과 크게 다르지 않은 환경에서 작업하면서도 RiGrid의 이점을 활용할 수 있었습니다.
마치며
지금까지 RiGrid를 소개해드렸습니다. 리디는 계속되는 변화에 유연하게 대응하기 위해 RiGrid를 지속적으로 발전시켜 나가고 있습니다. 콘텐츠 관리 시스템 구축하고, 성능 최적화에 힘쓰며, 리디 앱에도 RiGrid를 적용하여 사용자 경험을 향상시킬 계획입니다. 앞으로 RiGrid의 놀라운 변화를 기대해 주세요. 긴 글 읽어주셔서 감사합니다.
고객과 발맞춰 새로운 콘텐츠 경험을 선보이는
리디와 함께할 당신을 기다립니다.