물류 운영·출력 흐름
조회부터 예약·Excel·라벨 출력까지 이어지는 업무 흐름을 웹과 모바일 장비 경계로 연결했습니다.
- 맡은 범위
신규 구축/출력 연동
업무 운영 / WebView·Android 출력
- 기술 환경
Web
- React
- TypeScript
- Vite
- React Router
- TanStack Query
- Zustand
- XLSX
- Vitest
Mobile
- Expo
- React Native
- Expo Router
- WebView
- Android native module
- TypeScript
- Bluetooth
문제
예약 접수, 다건 처리, Excel 미리보기, 출력은 같은 업무 흐름이지만 PC 브라우저와 모바일 장비는 별도 앱·저장소와 실행 조건을 가졌습니다. 웹의 초기 로딩 비용을 줄이는 일과 Android 권한·Bluetooth·프린터 SDK를 다루는 일을 분리하면서도 요청 데이터와 실패 기준은 이어져야 했습니다.
핵심 판단
웹은 조회·예약·Excel·출력 요청의 상태와 초기 로딩을 책임지고, 모바일은 WebView contract 이후의 권한·Bluetooth·프린터 출력을 책임지도록 경계를 나눴습니다.
Web
2026.04 ~ 2026.06
물류 운영 웹
반복 업무 화면을 단순히 늘리는 것이 아니라, API 연동, 반응형 UI, Excel 처리, 출력 경로가 같은 기준으로 움직이도록 구성했습니다.
Mobile
2026.04 ~ 2026.06
모바일 출력 브릿지 앱
웹 화면은 WebView로 유지하면서, 모바일에서만 필요한 장비 출력은 native module에 맡기도록 경계를 나눴습니다.
확인한 결과
웹 초기 진입 비용과 모바일 출력 완료를 서로 다른 실행 환경과 검증 기준으로 확인했습니다.
물류 운영 웹
- 웹 초기 JS entry
- 2,405.50 → 616.59 kB
- 약 74% 감소. route·spreadsheet 지연 로딩 결과
- 웹 gzip 기준
- 815.10 → 204.38 kB
- 약 75% 감소. 동일 초기 entry 비교
모바일 출력 브릿지 앱
- 모바일 출력 검증
- Android 16 / API 36
- 권한·Bluetooth 연결·실물 라벨 출력 흐름 확인
남긴 기준
하나의 사용자 흐름이어도 브라우저 성능과 장비 출력은 같은 완료 기준으로 묶지 않는다는 원칙.
세부 구현 및 검증 기록
서로 다른 저장소와 앱으로 구축된 React 운영 웹과 모바일 출력 앱을 하나의 사용자 흐름으로 설명하되, 화면 상태와 장비 SDK의 책임은 섞지 않았습니다.
Web
물류 운영 웹
문제
초기 화면과 Excel 처리 코드가 한 번에 묶이면 첫 로딩이 무거워지고, PC 브라우저와 모바일 WebView 출력 경로가 섞이면 같은 기능도 서로 다른 기준으로 검증될 수 있었습니다.
판단
- 업무 화면을 먼저 늘리기보다 데이터 연동, 화면 상태, 출력 요청의 경계를 나눴습니다.
- 초기 진입에 필요하지 않은 route와 spreadsheet 처리는 실행 시점으로 미뤘습니다.
- PC 출력, 모바일 브라우저 fallback, WebView/native 출력 요청을 별도 흐름으로 판단했습니다.
해결
- 공통 shell, table, modal, form, feedback 구조 위에 주요 업무 흐름을 얹었습니다.
- 예약 접수, 다건 처리, 주소록 선택, Excel 미리보기, 출력 요청 변환을 하나의 흐름으로 연결했습니다.
- 번들 분석 결과를 기준으로 route-level lazy loading과 spreadsheet library lazy loading을 적용했습니다.
실행
- 조회, 예약, 주소록, Excel, 출력 흐름을 같은 shell 안에서 이어지도록 먼저 묶었습니다.
- 모의 데이터와 실제 API adapter를 분리해 화면 상태와 연동 상태를 따로 확인했습니다.
- 출력 흐름은 PC와 모바일 조건을 나눠 formatter, preview, native 요청을 각각 검증했습니다.
- 앱, 인증, 공개 API, UI를 더 나눈 실험에서는 500.67 kB(gzip 164.69 kB)까지 줄었지만 초기 인증·API 경계와 첫 클릭 loading 부담이 커져 채택하지 않았습니다.
- 최종 지연 로딩 범위는 116개 파일·573개 테스트로 확인했고, PC 실물 라벨 출력 경로는 별도로 8개 파일·73개 테스트를 확인했습니다.
성과
- 초기 JS entry
- 약 74% 감소
- 초기 진입에 필요하지 않은 화면과 Excel 처리 코드를 분리
- gzip 기준
- 약 75% 감소
- 동일 기준 초기 로딩 비용 감소
- 반응형 확인
- 모바일~데스크톱
- 모바일, 태블릿, 데스크톱 주요 폭에서 확인
확인
- 주요 viewport에서 overflow, modal clipping, dropdown 위치를 확인했습니다.
- 출력 formatter, bitmap, command, browser fallback 흐름을 회귀 기준으로 확인했습니다.
- lint/test/build와 bundle 분석을 반복해 채택한 최적화 범위를 구분했습니다.
Mobile
모바일 출력 브릿지 앱
문제
웹 버튼으로 출력 요청을 보내는 것과 실제 모바일 장비에서 출력되는 것은 다른 문제였습니다. WebView, 권한, native module, 장비 상태가 한 흐름에 묶이면 실패 지점을 찾기 어려웠습니다.
판단
- 업무 화면은 웹에 두고, 장비와 직접 맞닿는 출력 책임은 native module로 분리했습니다.
- WebView bridge 요청과 native 응답을 구조화된 contract로 다뤘습니다.
- 개발/운영 URL과 앱 식별자, 설치 산출물 기준을 나눴습니다.
해결
- WebView bridge와 Android native module 사이의 요청/응답 흐름을 정리했습니다.
- 출력 payload 변환, 장비 상태 확인, 실패 메시지를 별도 단계로 나눴습니다.
- 모바일 브라우저 fallback과 앱 WebView 출력 경로를 구분했습니다.
실행
- 웹에서 전달되는 출력 데이터를 native 출력 payload로 변환하는 경계를 먼저 잡았습니다.
- Bluetooth 권한, 장비 탐색, 연결 상태, 출력 명령을 단계별로 확인했습니다.
- 로컬 개발, 테스트 설치, 운영 설치 조건을 분리해 잘못된 환경으로 붙는 문제를 줄였습니다.
- Android 16/API 36에서 SDK 내부 장비 탐색 호출까지 따라가 취소 흐름과 BLUETOOTH_SCAN·BLUETOOTH_CONNECT 권한을 보완했습니다.
- 명령 queue 수락과 실제 종이 출력 완료는 다른 검증 기준으로 분리했습니다.
성과
- 출력 요청 경계
- WebView -> native
- 웹 payload와 장비 출력 명령을 분리
- 장비 출력 검증
- 실기기 확인
- emulator가 아닌 Android 기기 기준으로 확인
확인
- Android 실기기에서 권한, 장비 연결, 출력 요청 흐름을 확인했습니다.
- WebView bridge 요청과 native 출력 응답이 분리되는지 확인했습니다.
- 개발/운영 설치 기준과 URL 분기를 확인했습니다.