Ruby on Rails 애플리케이션에 PWA 기능을 추가하여 오프라인 지원 구현하기

Alicia Rojas - Building an offline experience with a Rails-powered PWA - Rails World 2023 - YouTube

3줄 요약

  • 본 발표는 Rails 애플리케이션에 Progressive Web Application(PWA) 기능을 통합하여 오프라인 지원 및 네이티브 앱과 유사한 경험을 제공하는 방법을 다룹니다.
  • 특히, 인터넷 연결이 불안정한 환경에서도 CRUD 작업을 수행하기 위해 Hotwire와 IndexedDB를 활용한 데이터 관리 및 동기화 전략을 제시합니다.
  • Service Worker와 Manifest 설정을 통해 앱의 신뢰성, 성능, 설치 가능성을 향상시키고, Stimulus를 활용한 프론트엔드 로직으로 오프라인 데이터 상호작용을 구현하는 실용적인 접근법을 소개합니다.

본 발표는 Progressive Web Application(PWA)이 웹 애플리케이션에 어떻게 혁신적인 기능을 부여하는지, 특히 Ruby on Rails 프레임워크 내에서 오프라인 지원을 구현하는 데 중점을 둡니다. 발표자인 Alicia Pass Roas는 Telos Labs의 소프트웨어 엔지니어로서, 기술과 지속 가능성에 대한 깊은 이해를 바탕으로 인터넷 연결이 불안정한 지역의 농부들을 위한 애플리케이션 개발이라는 실제 당면 과제를 해결하는 과정을 공유합니다. 이 강연은 PWA의 핵심 개념부터 Rails 애플리케이션에 이를 통합하기 위한 구체적인 기술적 접근 방식에 이르기까지, 웹과 네이티브 앱의 장점을 결합하여 사용자 경험을 극대화하는 방법을 탐구합니다.

PWA의 이해와 이점

PWA는 웹 애플리케이션이 현대적인 웹 API를 활용하여 성능 향상, 푸시 알림, 오프라인 지원, 설치 가능성 등의 기능을 제공하도록 점진적으로 향상된 형태를 의미합니다. 이는 웹 앱의 광범위한 도달 가능성(플랫폼 독립성, 검색 엔진 노출, 저비용)과 네이티브 앱의 강력한 기능(플랫폼 특정 기능, 복잡한 기능)을 결합하여, 두 세계의 장점을 모두 취하는 하이브리드 솔루션입니다. PWA는 네이티브 앱에 비해 개발 비용이 훨씬 적게 들면서도 사용자에게 네이티브 앱과 같은 사용감을 제공할 수 있습니다.

실제 사례: 칠레 정부 프로젝트

이 프로젝트는 칠레 정부 산하 농업 관련 기관의 요청으로 시작되었습니다. 농부와 농업 기술자들이 농장에서 현장 지속 가능성 평가를 수행할 수 있는 도구가 필요했는데, 문제는 인터넷 연결이 불안정하거나 아예 없는 지역이 많다는 점이었습니다. 또한, 사용자들이 기술에 익숙하지 않은 농촌 지역 주민들이었기에 앱은 사용하기 쉽고 공유하기 용이해야 했습니다. 제한된 시간과 예산으로 인해 네이티브 앱 개발 대신, Rails로 웹 애플리케이션을 구축한 후 점진적으로 PWA 기능을 추가하여 오프라인 지원을 구현하는 전략을 채택했습니다.

Rails에서 PWA 구현의 핵심 요소

Rails 애플리케이션을 PWA로 전환하기 위한 두 가지 핵심 요소는 Service Worker와 Manifest입니다.

  • Service Worker: 웹 서버와 브라우저 사이에서 프록시 역할을 하는 특수 JavaScript 자산입니다. 요청을 가로채고, 자산 캐싱, 백그라운드 동기화 등의 기능을 제공하여 오프라인 접근성을 보장하고 앱의 신뢰성을 향상시킵니다. Service Worker는 일반적으로 루트 스코프에서 작동하여 전체 경로를 제어합니다.
  • Manifest: PWA가 사용자의 기기 운영 체제 내에서 어떻게 동작하고 표시될지 브라우저에 알려주는 JSON 파일입니다. 스플래시 화면, 홈 화면 아이콘 등을 정의하여 네이티브 앱과 같은 느낌을 제공하는 데 중요합니다.

이러한 파일들을 Rails에 추가하기 위해 MVC 패턴을 활용합니다. Service Worker Controller를 생성하고, 해당 라우트를 정의한 후, 이 파일들을 뷰 템플릿으로 추가하는 방식입니다. Companion JS를 통해 이 요소들을 애플리케이션과 연결합니다.

Hotwire와 IndexedDB를 활용한 오프라인 CRUD 작업

오프라인 환경에서 CRUD(Create, Read, Update, Delete) 작업을 수행하고 나중에 동기화하는 것이 이 프로젝트의 핵심 도전 과제였습니다. 이를 위해 IndexedDB와 Hotwire가 활용됩니다.

  • IndexedDB: 브라우저 내에서 JSON 객체 데이터베이스를 관리하기 위한 JavaScript API입니다. 세션 및 탭 간의 지속성, 파일 및 복잡한 객체 저장, 대용량 데이터 처리 능력 때문에 선택되었습니다. 비동기 JavaScript(Promises)에 기반하므로, Dexie와 같은 래퍼 라이브러리를 사용하면 개발 편의성이 높아집니다.
  • 오프라인 데이터 생성 및 동기화: 사용자가 오프라인 상태에서 레코드를 생성하면, 서버로의 POST 요청이 실패하므로, 대신 IndexedDB에 레코드를 저장합니다. 이후 온라인 상태가 되면 수동 동기화 버튼을 통해 IndexedDB에 저장된 레코드들을 서버로 전송하고, 성공적으로 동기화된 레코드는 IndexedDB에서 삭제합니다. Stimulus 컨트롤러는 네트워크 상태를 확인하고, 폼 제출 시 오프라인이면 기본 동작을 막고 IndexedDB에 저장하는 로직을 담당합니다.
  • 오프라인 데이터 표시: 서버 측 렌더링 방식에서는 오프라인으로 저장된 데이터가 즉시 뷰에 반영되지 않습니다. 이를 해결하기 위해 template 태그와 Mustache.js 라이브러리를 활용합니다. template 태그 내에 숨겨진 콘텐츠를 정의하고, Stimulus 컨트롤러에서 IndexedDB 데이터를 가져와 Mustache.js를 통해 템플릿에 데이터를 채워 렌더링하고 DOM에 추가함으로써 사용자가 오프라인 데이터와 상호작용할 수 있도록 합니다.

추가 기능 및 고려 사항

  • 오프라인/온라인 토글: 사용자가 네트워크 상태를 수동으로 제어할 수 있는 토글 기능을 제공하여 불안정한 연결 상황에서 유용하게 활용할 수 있도록 합니다.
  • 백그라운드 동기화: Service Worker의 또 다른 API인 백그라운드 동기화를 활용하여 동기화 작업을 자동화할 수 있지만, 초기에는 수동 동기화를 먼저 구현하고 보완 기능으로 추가하는 것이 좋습니다.
  • 유효성 검사: 백엔드 유효성 검사와 프론트엔드 유효성 검사가 일치하는 것이 매우 중요합니다. IndexedDB에 저장되는 모든 레코드가 백엔드에서 유효하도록 보장해야 합니다.
  • 브라우저 호환성: PWA 기능의 브라우저 호환성을 이해하는 것이 중요하며, 특히 iOS Safari는 Android에 비해 일부 기능 지원이 늦을 수 있으므로 caniuse.com과 같은 사이트에서 확인해야 합니다.

결론적으로, Hotwire와 Stimulus는 최소한의 JavaScript로 PWA를 구축하는 데 필요한 모든 기능을 제공하며, 백엔드 개발자도 풀스택 개발자가 될 수 있도록 지원합니다.

Progressive Web Application(PWA) 기능은 애플리케이션의 성능을 비약적으로 향상시키고, 언제 어디서나 누구에게나 적합하게 만들 수 있는 강력한 도구입니다. 특히 인터넷 접근성이 낮은 지역의 비전통적인 사용자층에게도 서비스를 제공함으로써 사회적 영향력을 확대할 수 있습니다. Stimulus는 Rails 애플리케이션에 오프라인 기능을 추가하고, 마치 단일 페이지 애플리케이션처럼 매끄러운 오프라인 경험을 제공하는 데 필요한 최소한의 JavaScript만으로도 강력한 기능을 구현할 수 있게 해줍니다. 이 발표는 Rails 개발자들이 PWA의 잠재력을 최대한 활용하여 더 넓은 사용자층에 도달하고, 견고하며 사용자 친화적인 웹 애플리케이션을 구축할 수 있음을 명확히 보여줍니다.