요즘IT
위시켓
최근 검색어
전체 삭제
최근 검색어가 없습니다.

*FEConf2024에서 발표한 <7가지 플랫폼 서버로 프론트엔드 버프 마법 걸기>를 정리한 글입니다. 발표 내용을 2회로 나누어 발행합니다. 1회에서는 프론트엔드의 라이프 사이클에 대해 간단히 알아보고 4가지 버프 방법에 대해 알아보겠습니다. 2회에서는 나머지 3가지 버프에 대해 알아보고, 시행착오로 배운 것들에 대해 알아봅니다. 본문에 삽입된 이미지의 출처는 모두 이 콘텐츠와 같은 제목의 발표 자료로, 따로 출처를 표기하지 않았습니다.

회원가입을 하면 원하는 문장을
저장할 수 있어요!

다음

회원가입을 하면
성장에 도움이 되는 콘텐츠를
스크랩할 수 있어요!

확인

개발

7가지 플랫폼 서버로 프론트엔드 버프 마법 걸기 (1)

년차,
어떤 스킬
,
어떤 직무
독자들이 봤을까요?
어떤 독자들이 봤는지 궁금하다면?
로그인

*FEConf2024에서 발표한 <7가지 플랫폼 서버로 프론트엔드 버프 마법 걸기>를 정리한 글입니다. 발표 내용을 2회로 나누어 발행합니다. 1회에서는 프론트엔드의 라이프 사이클에 대해 간단히 알아보고 4가지 버프 방법에 대해 알아보겠습니다. 2회에서는 나머지 3가지 버프에 대해 알아보고, 시행착오로 배운 것들에 대해 알아봅니다. 본문에 삽입된 이미지의 출처는 모두 이 콘텐츠와 같은 제목의 발표 자료로, 따로 출처를 표기하지 않았습니다.


FEConf2024에서 발표된 ‘7가지 플랫폼 서버로 프론트엔드 버프 마법 걸기’/정석호 토스 코어 Frontend Infra Ops Unit Lead

 


안녕하세요. 저는 토스 코어 FE 플랫폼 팀에서 Frontend Ops 유닛을 리딩하고 있는 정석호라고 합니다. 오늘은 ‘7가지 플랫폼 서버로 프론트엔드 버프 마법 걸기'에 대해 설명해 보려고 합니다. 저는 특히 프론트엔드와 인프라에 관심이 많아서 이와 관련된 작업들을 주도적으로 하고 있습니다. 최근에는 프론트엔드 서비스의 안정성을 위해 좋은 환경을 가꾸는 것에 집중하고 있습니다.

 

이번 글에서 다루는 것들은 아래와 같습니다. 구체적인 코드 조각이나 구현 방법은 다루지 않으니 참고해 주세요.

 

  1. 풀고자 했던 문제들
  2. 아이디어와 임팩트
  3. 겪었던 시행착오와 운영 이슈

 

 

토스 코어의 프론트엔드

토스 코어에는 86명의 FE 개발자들이 함께 있고 250개의 서비스를 운영하고 있습니다. 제가 속한 플랫폼 팀에서는 86명의 FE 개발자가 사용하는 모노리포를 관리하고 있고 하루 평균 머지 리퀘스트 요청은 50개 정도 됩니다. 또한 250개의 서비스의 배포부터 모니터링까지 같이 관리하고 있습니다.

 

또, 사내에서 사용하는 공통 라이브러리는 약 220개 정도입니다. 이런 인프라 관리를 좀 더 쉽게 하기 위해서 IaC를 통해 형상 관리를 자동화하고 있고, 다양한 개발자들이 기여할 수 있는 환경을 만들기 위해 노력하고 있습니다.

 

토스 코어 팀의 프론트엔드 개발자들이 이러한 다양한 업무들에 집중하는 목적이 무엇일까요?

 

가장 큰 목적은 토스의 프론트엔드 UX/DX를 세계 최강으로 만들기 위함입니다. 토스의 프론트엔드 플랫폼이 세계 최강의 프론트엔드가 되기 위해 어떤 노력을 하고 있는지 하나씩 살펴보겠습니다.

 

프론트엔드 서비스 라이프 사이클

이러한 노력을 알아보기 전에 아래 그림을 통해 프론트엔드 서비스가 어떻게 만들어지고 유저에게 어떻게 전달되는지 알아보겠습니다.

 

 

먼저 토스 코어의 UX 팀이 디자인 시스템을 만들어 주고, 디자이너 분들이 디자인 툴을 활용해 디자인을 합니다. FE 개발자들은 이를 기반으로 소스 코드를 작성하고 웹서비스를 배포합니다. 이렇게 배포된 서비스는 네이티브 앱안에 있는 웹뷰를 통해 사용자에게 제공됩니다.

 

그럼 토스 코어에서 세계 최강의 프론트엔드 플랫폼을 만들기 위해 어떤 노력을 하고 있을까요? 위 그림에서 파란색으로 칠한 부분이 바로 이번 글의 주제이자 토스 코어의 7가지 마법입니다. 이제부터 7가지 마법에 대해 하나씩 알아보겠습니다.

 

 

이미지 최적화 마법

Next.js 이미지 컴포넌트

첫 번째 주제는 이미지 최적화 마법입니다. Next.js를 활용해 개발해 보신 분이라면 Next.js의 이미지 컴포넌트를 사용해 봤을거라 생각됩니다. Next.js의 이미지 컴포넌트는 아래와 같은 특징을 가지고 있습니다.

 

  1. 기기에 적절한 디바이스 별 사이즈로 자동 변환
  2. 이미지 로딩 시 Layout Shift 방지
  3. 고해상도 이미지를 저 해상도로 우선 표시(Blur-up)
  4. 외부 이미지 사용 가능(e.g. CDN)

 

3년 전 토스를 돌아보면, 대부분의 서비스가 Next.js의 SSG(Static Site Generation)를 통해 만들어진 CSR(Client Side Rendering) 서비스였습니다. 하지만 Next.js의 이미지 컴포넌트는 SSR 서버의 온디맨드 기능이기 때문에 SSG로 만들어진 페이지에서는 사용이 불가능하다는 아쉬움이 있었습니다.

 

즉, Next.js의 이미지 옵티마이제이션 디폴트 로더는 오직 Next.js에서만 사용할 수 있고, Next.js에서도 SSG나 CSR에서는 사용할 수 없습니다.

 

 

Next.js 이미지 컴포넌트 사용 문제 해결하기

토스 팀에서는 Next.js의 디폴트 로더를 사용하지 않고 Next.js와 독립된 이미지 최적화 API를 이용해 앞서 말한 것을 해결해 보고자 했습니다.

 

 

가장 쉽게 접근할 수 있는 방법은 AWS의 Lambda@Edge를 사용하는 것입니다. 앞단에는 CDN을 배치하고 뒷단에는 이미지 최적화 로직을 수행하는 람다를 배치하여 서비스에 이를 사용할 수 있게 구성했습니다. 하지만 람다를 운영하면서 각종 시행착오를 겪었습니다.

 

서비스를 이중화하기 위해서는 다른 제공 업체의 서버리스 펑션 서비스를 사용해야 하는 경우도 발생하고, 기존 소스코드가 오래되었다면 Node.js의 버전을 강제로 업데이트해야 배포할 수 있는 리스크도 존재했습니다. 뿐만 아니라 트래픽이 갑자기 몰리게 되면 람다 서비스 비용이 기하급수적으로 커질 수도 있었습니다.

 

저는 이러한 문제를 이미 토스 서버 플랫폼에서 잘 해결해나가고 있다고 생각했습니다. 그래서 이미 잘 만들어진 토스 서버 플랫폼 인프라에 서버를 띄워보고 싶다는 생각을 했습니다. 이렇게 하면 DC1 / DC2 이중화 및 점진적인 배포도 지원이 되고, 그라파나를 통한 서버 지표 모니터링은 물론 실시간 로깅도 가능합니다.

 

이 시도를 통해 안정적으로 IDC 인프라를 사용하여 앞서 말한 장점들을 모두 얻을 수 있었습니다. 다시 말해 이미지 최적화 마법을 통해 모든 환경에서 이미지 최적화를 사용할 수 있게 되었습니다. 현재는 250개의 서비스에서 최적화된 이미지를 사용할 수 있게 되었습니다. SSR은 물론 SSG 및 CSR, 그리고 Next.js가 아닌 환경에서도 이미지 최적화 마법을 사용 중입니다.

 

 

비디오 썸네일 마법

Video 태그의 썸네일 속성

다음으로 비디오 썸네일 마법에 대해 알아보겠습니다. video 태그를 사용할 때 아래와 같이 poster 속성을 사용하여 비디오가 로딩될 때 보여줄 썸네일 이미지를 설정할 수 있습니다.

 

 

이 속성을 사용하여 썸네일을 설정하려면 영상을 만들고 이미지를 뽑아낸 다음, 이미지를 업로드하는 작업이 필요합니다. 다시 말해 실제로 업로드된 주소를 기준으로 poster 속성에 주소를 적고 실제 서비스 배포를 해야 합니다. 이런 작업은 생산성을 떨어뜨리고 꽤나 귀찮은 작업일 수 있습니다.

 

썸네일 속성 설정을 위한 문제 해결하기

위와 같이 poster 속성 설정을 위한 비효율적인 작업 문제를 해결하기 위한 방법은 어떤 것이 있을까요? 썸네일 이미지를 실시간으로 생성해 주는 서버를 생각해 봤습니다. 아래 그림과 같이 원하는 특정 시간과 함께 비디오 주소를 넣으면 해당 시간에 맞는 프레임을 동적으로 생성해 주는 서버입니다.

 

 

이 아이디어를 통해 비효율적인 작업 없이 동영상을 업로드함과 동시에 썸네일을 사용할 수 있게 해결할 수 있습니다. 썸네일을 바꾸고 싶을 때도 썸네일 이미지 업로드 과정 없이 시간 파라미터만 바꾸면 썸네일이 교체되도록 할 수 있습니다.

 

동영상에서 썸네일 이미지를 캡쳐하여 서버에 업로드하고, 업로드된 이미지를 poster 속성에 매번 지정해야 하는 비효율적인 문제를 해결할 수 있는 두 번째 마법이었습니다.

 

 

폴리필 마법

세 번째로 소개드릴 마법은 폴리필 마법입니다. 인터넷 환경에는 다양한 브라우저들이 존재하고, 특정 브라우저에서는 지원되지 않는 구현체들도 간혹 존재합니다. 대표적으로 인터넷 익스플로러 11에서는 Promise 객체를 지원하지 않습니다. 이러한 문제를 어떻게 해결할 수 있을까요?

 

폴리필 사용

대표적인 방법은 폴리필을 이용하는 것입니다. 폴리필이란, 아래와 같이 빈 구현체를 채워주는 스크립트라고 이해할 수 있습니다.

 

 

폴리필을 가장 쉽게 사용하려면 바벨을 사용하면 됩니다. @babel/preset-env라는 라이브러리를 사용하여 아래와 같이 인터넷 익스플로러 11을 기준으로 최소 지원 브라우저를 설정하여 구현체를 채울 수 있습니다.

 

 

폴리필의 문제점과 해결 방안

하지만 이 방법을 최신 브라우저에서 쓰면 단점이 존재합니다. 최신 브라우저에서는 이미 지원하는 구현체들을 내려받게 되어 사용자, 서비스 제공자, CDN 모두에게 불필요한 네트워크 비용이 발생하게 됩니다.

 

 

이러한 문제를 해결할 수 있는 방법인 폴리필 서버에 대해 알아보겠습니다. 폴리필 서버에서는 유저 에이전트의 정보를 읽고 해당 유저의 브라우저에 어떤 폴리필 구현체가 필요한지 체크하여 필요한 구현체만 전송하는 작업을 수행합니다.

 

이런 아이디어는 저희뿐 아니라 다양한 클라우드 서비스에도 존재합니다. 대표적으로 polyfill.io라는 서비스가 있습니다. 하지만 몇 달 전에 어떤 기업에 인수되고 나서 보안 안정성 문제가 발생했고, 해당 서비스를 이용한 트위터 등에서 화면이 제대로 보여지지 않는 문제가 발생했습니다. polyfill.io의 사이트도 접근 불가능한 사이트가 되어버렸습니다.

 

토스에서는 애초부터 다른 서비스의 불확실한 안정성에 우리 서비스를 맡기고 싶지 않았습니다. 조금 더 독립적이고 외부에 의존하지 않는 안정적인 서비스를 운영하고 싶었고, 자체적인 서비스를 구현하게 되었습니다.

 

 

어떤 방법으로 구현되었는지 살펴볼까요? 위 그림을 보면 오리지널 람다를 바라보고 있는 CDN을 통해서 구현된 것을 알 수 있습니다. 람다에서 유저 에이전트 헤더를 사용해서 파라미터를 받았고, 그 유저 에이전트 헤더를 파싱해서 어떤 구현체를 포함할지 확인하고, CDN을 통해 자바스크립트 번들을 브라우저에게 전달해줍니다.

 

이런 폴리필 마법으로 인해 인터넷 익스플로러에서는 732 KB의 번들을 내려받는 반면 크롬이나 사파리에서는 거의 빈 함수만 내려받는 정도의 수준으로 가벼운 번들만 전송받을 수 있었습니다.

 

 

이 내용은 이번 글뿐만 아니라 토스 테크 블로그에 똑똑하게 브라우자 폴리필 관리하기라는 내용으로 작성되어 있으니, 필요한 분들은 이 글을 읽어보고 자세한 구현을 따라해 보아도 좋을 것 같습니다.

 

 

스켈레톤 마법

다음은 스켈레톤 마법입니다. 우리가 어떤 웹페이지의 화면을 띄울 때는 반드시 필요한 구간이 있습니다. 바로 네트워크 구간입니다. 네트워크 연결이 되어 있지 않다면 페이지를 띄우기는 어려울 것입니다. 실제로 SSR 서버에서 이 웹뷰의 페이지를 내려받는 순간까지 웹뷰에는 아무런 화면이 뜨지 않습니다. 이런 경우에 사용할 수 있는 방법이 바로 스켈레톤입니다.

 

Loading…

네트워크를 통해 페이지를 내려받아서 렌더링 하기 전에 화면에 보여줄 수 있는 방법은 여러 가지가 있습니다. 빈 화면을 보여줄 수도 있고, 빙글빙글 돌아가는 로더 페이지를 보여줄 수도 있습니다. 하지만 사용하는 웹서비스의 모든 페이지에서 동일한 로더를 보게 되면 사용자 경험이 좋지 않을 것 같습니다.

 

 

스켈레톤

저는 이런 사용자 경험을 개선하기 위해 접속한 페이지의 UI 형태를 미리 알고, 해당 UI 형태의 스켈레톤을 보여주는 방법을 생각했습니다. 웹뷰가 로딩되는 동안 이 스켈레톤 UI를 보여주는 것입니다. 스켈레톤 서버를 따로 실행하여 접속한 URL을 파싱 해서 파싱 한 데이터를 기반으로 미리 정의한 스켈레톤 타입을 페이지에 맞게 보여주는 방식입니다.

 

 

그럼 간단한 예시를 살펴보겠습니다. 아래와 같이 특정 JSON에 특정 주소에 따라 스켈레톤 타입을 정의해둘 수 있습니다. 이 타입을 활용해 ‘shopping/상품목록’에 접속했을 때는 list-only라는 스켈레톤을 보여주고, ‘tossfeed/목록페이지’에 접속했을때는 card-only라는 스켈레톤을 보여줄 수 있습니다.

 

 

이처럼 다양한 스켈레톤 타입을 미리 구현해두고 페이지에 맞는 스켈레톤을 보여준다면 유저는 똑같은 로딩 화면을 보지 않고 상황에 맞는 스켈레톤을 보게 되어 사용자 경험이 좋아질 수 있습니다.

 

 

지금까지 토스의 7가지 플랫폼 서버 마법 가운데 4가지를 알아봤습니다. 다음 글에서는 5~7번째 마법인 애셋, 오픈 그래프, 웹 모듈 마법에 대해 알아보겠습니다. 또한 이 과정에서 겪은 시행착오도 공유하려고 합니다.

 

 

요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.

좋아요

댓글

공유

공유

FEConf
500
명 알림 받는 중

작가 홈

FEConf
500
명 알림 받는 중
프론트엔드 컨퍼런스 FEConf 공식 계정입니다.

좋아요

댓글

스크랩

공유

공유

요즘IT가 PICK한 뉴스레터를 매주 목요일에 만나보세요

요즘IT가 PICK한 뉴스레터를
매주 목요일에 만나보세요

뉴스레터를 구독하려면 동의가 필요합니다.
https://auth.wishket.com/login