logo
줌패닝 PoC 후 react-flow를 선택한 과정

이미지 보기

줌패닝 PoC 후 react-flow를 선택한 과정

줌패닝 기능 구현을 위한 라이브러리 선택에서 깊은 PoC의 과정과 결과를 소개해요

  • 24.11.24 작성

  • 읽는 데 20

TOC

들어가며

안녕하세요! 회사에서 Zoom & Pan 기능이 필요한 프로젝트를 담당하게 되었어요. 지금껏 해왔던 평범한 웹 개발 방식이 아니다 보니 라이브러리를 조사하고 기술을 검증하는 과정을 거쳤어요. 기획적인 요구사항에 대해서 기술적인 실현 가능성이 있는지를 살펴야 했고, 개발적으로도 편의성과 확장성이 좋은지를 면밀하게 비교하며 검토했어요. 그 밖에도 다양한 기준으로 깊게 비교하고 playground 개발까지 진행했죠. 결론적으로는 react-flow를 선택하여 더 깊은 수준의 playground 개발 및 본격적인 실무 적용을 진행하고 있어요. 오늘은 이 과정에서 줌패닝 라이브러리로 react-flow를 선택한 이유와 줌패닝 라이브러리의 전반적인 PoC를 진행한 과정을 소개하려고 해요.

PoC란?

우선 PoC는 개념 검증(Proof of Concept) 의 약자로, 기술적인 가능성을 검증하는 것이라고 할 수 있어요. 처음 라이브러리를 선택할 때는 이러한 PoC를 통해 라이브러리의 활용성과 확장성을 검증하고, 실제 프로젝트에 적용할 수 있는지를 판단하는 것이 중요했어요. 함께 일하는 프론트 팀원들에게도 선택한 라이브러리에 대한 공감과 이해, 피드백을 얻기 위함도 있었어요. 목적에 대해서는 아래에서 더 자세히 설명할게요.

1. 목적

1.1. Zoom & Pan이 필요한 이유

Zoom & Pan 기능은 간단하게 말하면 ‘피그마처럼 조작하는 기능’이에요. 화면을 드래그해 이동하거나 확대/축소를 하는 기능이죠. (자세한 설명은 뒤에서 더 하겠습니다.) 이 Zoom & Pan 기능은 제가 팀에서 새롭게 담당하게 된 프로젝트에서 굉장히 중요하게 여겨지는 구현 요구 사항입니다.

1.2. 본 문서의 작성 배경

  • 라이브러리별 분석 로그 : 지금까지 팀 서비스에서 Zoom & Pan 기능을 활용한 적도, 활용할 필요도 없었어요. 때문에 관련 라이브러리 선택과 도입에 있어 면밀한 분석이 필요했습니다.
  • 프론트 파트 피드백 : 결정 과정에서 독단적으로 결정하기보다는 프론트엔드 개발자 간의 도입 배경과 라이브러리간 비교 정보를 공유한 후 의견 수렴을 거쳐 최종 도입하고자 했어요.
  • 도입 배경 기록 : 라이브러리 선택에 있어 히스토리를 남기는 차원에서도 도움이 될 것 같아요.

1.3. 기획 요구사항

  1. 피그마와 같은 Scroll / Zoom / Pan 의 UI 기능을 지원한다.

    1. wheel up/down : y축 스크롤 이동
    2. shift + wheel up/down : x축 스크롤 이동
    3. ctrl + wheel up/down : 확대/축소
  2. 확대/축소 시 크기가 변경되는 요소와 아닌 요소를 구분한다.

    1. 일반적으로는 확대/축소에 따라 크기가 변경
    2. layout, RNB, dropdown list 등 일부 요소는 크기를 유지
  3. 확대/이동에 대해 너무 범위를 벗어나지 않게 영역을 설정한다.

    1. 확대/축소 시 최대/최소 범위 설정
    2. 이동 시 최대/최소 범위 설정

2. 용어 설명

먼저 Zoom과 Pan의 의미를 정확히 알고 넘어갈게요.

2.1. Zoom (확대/축소)

  • 정의 : 컨텐츠의 크기를 동적으로 조절하는 기능
  • 주요 기능
    • Wheel Zoom: 마우스 휠을 사용한 확대/축소
    • Pinch Zoom: 터치 디바이스에서 두 손가락을 이용한 확대/축소
    • Double-Click Zoom: 더블 클릭을 통한 단계별 확대/축소

2.2. Pan (이동)

  • 정의 : 확대된 컨텐츠의 시점을 이동하는 기능
  • 주요 기능
    • Drag Pan: 마우스 드래그를 통한 이동
    • Touch Pan: 터치 스크린에서의 한 손가락 드래그
    • Momentum Pan: 드래그 후 관성 이동

3. 라이브러리 분석 기준

아래의 판단 기준들을 중심으로 조사를 진행했어요.

  • 기술 : 기술적으로 어떤 장단점이 있는지
  • 정보 : 공식문서가 얼마나 잘 구성되어 있는지
  • 정보 : 커뮤니티는 얼마나 활성화가 되어 있는지(Github Stars, npm trends로 판단)
  • 지속성 : 라이브러리의 유지보수가 진행되고 있는지
    • recoil 유지보수 중단의 뼈아픈 사례 고려
    • 최근 업데이트 및 Issue, Pull Request로 파악
  • 적합성 : 지원하는 기능들이 얼마나 프로젝트에 적합할지

아래의 구체적 수치는 2024년 11월 16일 기준입니다.

4. react-zoom-pan-pinch

react-zoom-pan-pinch

4.1. 개요

4.2. 특징

  • 마이크로소프트가 공식 스폰서
react-zoom-pan-pinch
  • storybook 형식으로 구성된 공식문서
react-zoom-pan-pinch

4.3. 장점

  • 빠르고 쉬운 사용성
  • 모든 주요 브라우저와 터치 디바이스 지원
  • 타입스크립트로 작성되어 타입 지원이 우수
  • 강력한 제스처 컨트롤(핀치, 더블탭, 휠)
  • 부드러운 애니메이션과 고성능
  • 활발한 커뮤니티와 지속적인 유지보수
  • 간편한 커스터마이징 기능
  • 확장된 hook과 component

4.4. 단점

  • 일부 복잡한 사용 사례에서 설정이 번거로움
  • 고급 기능 사용 시 러닝 커브가 있음

4.5. 사용 예시

import React, { Component } from "react";

import {
  TransformWrapper,
  TransformComponent,
  useControls,
} from "react-zoom-pan-pinch";

const Controls = () => {
  const { zoomIn, zoomOut, resetTransform } = useControls();

  return (
    <div className="tools">
      <button onClick={() => zoomIn()}>+</button>
      <button onClick={() => zoomOut()}>-</button>
      <button onClick={() => resetTransform()}>x</button>
    </div>
  );
};

const Example = () => {
  return (
    <TransformWrapper
      initialScale={1}
      initialPositionX={200}
      initialPositionY={100}
    >
      {({ zoomIn, zoomOut, resetTransform, ...rest }) => (
        <>
          <Controls />
          <TransformComponent>
            <img src="image.jpg" alt="test" />
            <div>Example text</div>
          </TransformComponent>
        </>
      )}
    </TransformWrapper>
  );
};

5. react-panzoom

5.1. 개요

  • Github : react-panzoom github
  • Fork : 5
  • GitHub Stars : 15k
  • Pull Requests : Open 2 / Closed 148
  • Issues : Open 0 / Closed 11
  • 최근 업데이트: 2024년 10월

5.2. 특징

  • 공식문서는 따로 없지만 자세한 README
react-panzoom

5.3. 장점

  • 가벼운 번들 크기
  • 간단한 API
  • 기본적인 기능에 충실

5.4. 단점

  • 고급 기능 부족
  • 모바일 지원이 제한적
  • 커뮤니티 규모가 작음

5.5. 사용 예시

import PanZoom, { Element } from '@sasza/react-panzoom'

// ...

<div style={{ width: 300, height: 300 }}>
  <PanZoom>
    <Element id="orange" x={50} y={60}>
      <Circle />
    </Element>
    <Element id="red" x={120} y={150}>
      <Square />
    </Element>
  </PanZoom>
</div>

6. @use-gesture/react

6.1. 개요

6.2. 특징

정식 공식문서가 깔끔하고 자세히 제공

use-gesture/react

6.3. 장점

  • 다양한 제스처 지원
    • drag, pinch, scroll, wheel, hover, move 등 포괄적인 제스처 지원
    • 복잡한 제스처 조합 가능
  • 유연한 API
    • Hook 기반 설계로 높은 커스터마이징 가능
    • 함수형 프로그래밍 패러다임과 잘 어울림
  • 높은 성능
    • 네이티브 이벤트 처리 최적화
    • 불필요한 리렌더링 방지
  • 애니메이션 라이브러리와의 호환성
    • react-spring과 완벽한 통합
    • framer-motion 등 다른 애니메이션 라이브러리와도 호환

6.4. 단점

  • 러닝 커브
    • 자유도가 높은 만큼 초기 학습이 필요
    • 복잡한 제스처 구현 시 코드가 다소 복잡해질 수 있음
  • 추상화 수준
    • 로우 레벨 API로 인해 간단한 기능도 직접 구현 필요
    • 기본적인 줌/팬 기능만 필요한 경우 과도한 설정 필요
  • 라이브러리 의존성
    • 고급 애니메이션 기능을 사용하는 경우 react-spring 라이브러리 필요
    • animated.div와 같은 자체적인 문법 사용으로 강결합 예상

7. react-flow

7.1. 개요

  • Github : react-flow github
  • 공식문서 : react-flow docs
  • Fork : 1.7k
  • GitHub Stars : 26k
  • Pull Requests : Open 12 / Closed 1,477
  • Issues : Open 99 / Closed 1,937
  • 최근 업데이트: 2024년 3월

7.2. 특징

  • 정식 공식문서가 깔끔하고 자세히 제공(비교군 라이브러리 중 최고)
react-flow

7.3. 장점

  • 완성도 높은 기능
    • 내장된 줌/팬 기능
    • 노드 간 연결선 자동 라우팅
    • 다양한 노드 타입 제공
    • 미니맵, 컨트롤 패널 등 부가 기능
  • 성능 최적화
    • 가상화(virtualization) 구현으로 대규모 그래프 처리 가능
    • 효율적인 렌더링 최적화
  • 개발 편의성
    • 직관적인 API
    • 풍부한 문서화와 예제
    • TypeScript 완벽 지원
  • 확장성
    • 커스텀 노드/엣지 타입 정의 가능
    • 다양한 이벤트 핸들러 제공
    • 플러그인 시스템 지원

7.4. 단점

  • 번들 크기
    • 상대적으로 큰 번들 사이즈
    • 기본 기능만 필요한 경우 과도할 수 있음
  • 러닝 커브
    • 다양한 기능 만큼 학습이 필요
    • 복잡한 사용 사례의 경우 설정이 까다로움
  • 라이선스 제한
    • 일부 고급 기능은 유료 버전에서만 제공
    • 기업용 기능은 별도 라이선스 필요

8. 라이브러리 비교 분석

react-use-gesture는 @use-gesture/react의 전신입니다.
2021년에 native JavaScript 등 react 외의 언어를 지원하기 위해 분리되었습니다.

npm trends

8.2. 기능 비교

기능react-zoom-pan-pinchreact-panzoom@use-gesture/reactreact-flow
핀치 줌🟢🟡🟢🟢
더블클릭 줌🟢🟢🟢🟢
바운더리 제한🟢🟢🟢🟢
관성 스크롤🟢🔴🟢🟢
TypeScript🟢🟢🟢🟢
커스텀 컨트롤🟢🟡🟢🟢
모바일 지원🟢🟡🟢🟢
복합 제스처🟡🔴🟢🟢
node-edge 방식🔴🔴🔴🟢

🟢: 완벽 지원, 🟡: 부분 지원, 🔴: 미지원

8.3. 최종 선정 기준

  • 유지보수성 : 계속 유지보수가 활발해야 함
  • 커뮤니티 : 레퍼런스와 트러블슈팅에 필요
  • 적합성 : 프로젝트의 요구사항 고려
  • 개발 편의성 : 라이브러리 의존성(결합도) 및 개발사용성 고려
  • 확장성 : 미래를 대비하는 유연함과 확장 가능성

9. PoC 기술 체험용 playground

10. 선정 결과

10.1 선택된 라이브러리

: react-flow

10.2. 선택 근거

  1. 커뮤니티
    • github Stars, fork, npm trends 등을 종합적으로 평가
    • 공식문서의 다양한 예시 코드 및 지원 기능 고려
    • code sandbox에 다양한 활용 예제들 참고 가능
  2. 안정성과 성숙도
    • 지속적인 유지보수와 버그 수정 기록 확인
  3. 기능의 완성도
    • 모든 필수 기능이 기본적으로 구현됨
    • 모바일 지원이 우수
    • 고급 기능(복합 제스처, 바운더리 제한 등) 제공
  4. 확장성
    • node-edge 방식으로 확장 가능
    • 개발 난이도 상승은 현재 구현 사항 만족 범위에서 최대한 개발적으로 풀어볼 계획

10.3. 선정 후 고려사항

  1. 라이브러리의 가장 큰 매력 포인트였던 redo/undo 파악이 안 됨(유료 플랜)
  2. 유료 플랜이 꽤 비쌈(기본 월 139달러, 팀 월 269달러), 선행 개발했던 타 팀에서는 유료 플랜 사용을 안 하고 있음

11. 결론

  • react-flow 라이브러리를 선택했어요.
  • 자세한 인터페이스를 제공하고, 여러 선택 옵션들이 있는 것에 잘 활용하기 위한 러닝커브가 우려되는 것은 사실이에요.
  • 하지만 인터페이스의 코드단에서 주석으로 설명이 많이 되어있고, 공식문서가 방대하고 다양한 케이스의 예시코드와 devtools 등 개발 편의성도 확보할 수 있어요. 그밖에도 비공식 예시코드(code sandbox 등)가 다양해요.
  • 또한 wheel customization(복합 제스처)으로 wheel / ctrl+wheel / shift+wheel 등 다양한 wheel 동작을 설정할 수 있어요.
  • 정리하면 큰 커뮤니티와 기능성, 확장성이 보장되어 있어요.
  • 이런 면에서 프로젝트에 가장 적합하다고 판단돼요.

마치며

PoC 느낀점

이렇게 깊게 PoC를 해본 적이 없었는데 과정에서 느낀 점이 있어요.

  • 라이브러리의 선택은 현재의 기획과 정책 뿐만 아니라, 미래의 알 수 없는 기능 구현까지 고려하여 확장성 있는 라이브러리를 선택해야 한다.
  • 단, 라이브러리 자체도 미래에는 어떻게 될 지 알 수 없기 때문에, 결합도가 낮고 변경이 용이한 구조를 고려해야 한다.
  • 라이브러리 선택은 개발자의 개인적인 취향이나 경험에 따라 달라질 수 있지만, 팀 내에서의 공감과 피드백을 통해 더 나은 선택을 할 수 있다.
  • PoC를 통해 라이브러리의 활용성과 확장성을 검증하고, 팀원들과의 공유를 통해 더 나은 결정을 할 수 있다.

Contribution

react-flow 공식문서를 읽고 있는데, 오타가 있거나 연결된 링크가 엉뚱한 링크를 담고 있는 것들을 발견하곤 했어요. 이전에는 그냥 넘어갔을 텐데, 그래도 애정을 가지고 딥다이브하고 있는 라이브러리인 만큼 바로잡고 싶어졌어요. 그래서 docs 내용을 담고 있는 xyflow/web에 수정 pull request를 올렸고, merge되었어요.(링크)

contribution

이후에도 더 발견하여 pull request를 올려둔 상태이고, 수정이 필요한 부분이 있다면 계속 수정 요청을 올려 더 좋은 공식문서를 위해 일조하고 싶어요.

정리

이번 PoC를 통해 라이브러리 선택의 중요성과 과정을 배울 수 있었어요. 지금은 라이브러리 선택을 완료하고, react-flow playground를 개발해보고 있어요. 기술적 검증과 확장의 범위를 확인하고 숙련도를 높이기 위해서 말이죠. 앞으로도 이런 경험을 통해 더 나은 개발자로 성장하고 싶어요.

프로젝트를 마무리하고 어느 정도 숙련도가 높아지면, react-flow의 사용에 관련된 블로그 포스팅을 작성하여 많은 사람들이 쉽게 쓸 수 있게 지식을 전하겠습니다. 감사합니다.

profile

FE Developer 박승훈

노력하는 자는 즐기는 자를 이길 수 없다