임팩트: WebView↔Native 통신 개선 — 반응 시간 Before/After(ms), 사용자 체감 개선
AS-IS
네이티브 로직을 호출해야할 경우 앱스킴을 호출하여 통신하고 있습니다.
앱스킴 호출에는 크리티컬한 이슈가 있습니다. 2개 이상의 앱스킴이 동시 호출되면 1개를 제외한 나머지의 앱스킴은 무시되는 현상이 발생합니다.
그래서 페이지 접근 시 앱스킴이 무시되는 현상을 방지하기 위해 500ms의 delay를 줍니다.
사용자가 빠르다고 느끼는 피드백 속도는 100ms이기 때문에 한참 부족한 반응성을 가집니다. (앱 스킴 2개만 호출해도 1000ms…)
TO-BE
js interface를 적용하면 동시 호출시 씹히는 현상을 방지할 수 있습니다. 다만, mounted 생명 주기에 js interface를 호출할 경우, 정상적으로 호출되긴 하지만, 앱 단에서 웹뷰의 콜백함수 호출을 하지 못합니다.
mounted 실행 시 리소스가 모두 다운로드 된 타이밍이라고 단정지을 수 없습니다. 리소스는 비동기로 다운로드됩니다.
따라서 리소스 다운을 추적하는 DOMContentLoaded 이벤트를 추적합니다.
addEventListener를 통해 리소스가 모두 다운된 후 js interface를 호출하니 문제가 해결되었습니다.
App Scheme (AS-IS)
장점
- 구현이 단순함
- 기존 인프라 활용
고려할 점
- 동시 호출 시 1개 외 무시됨
- 호출 간 500ms delay 필요
- 2개 호출 시 최소 1000ms 소요
JS Interface (TO-BE)
장점
- 동시 호출 가능 (씹힘 없음)
- delay 불필요 → 반응성 대폭 개선
- 콜백 기반 양방향 통신
고려할 점
- DOMContentLoaded 이후 호출 필요
- mounted 시점에서는 콜백 수신 불가
| 항목 | 비교 | 값 (ms) |
|---|---|---|
| 사용자 체감 기준 | 100 ms | |
| JS Interface | 50 ms | |
| App Scheme (1회) | 500 ms | |
| App Scheme (2회) | 1000 ms |
js interface가 정상 동작하는 프로세스는 아래와 같습니다.
앱 뷰 생성 → 웹 뷰 created → 웹뷰 mounted → 웹 리소스 리로드 → js interface 호출 → 네이티브 로직 실행 → 웹 리소스 호출 → 웹 로직 실행 → 완료
컴포넌트 mounted보다 웹 렌더링 이벤트가 나중에 호출되는데 이 부분을 알고 넘어가야할 문제인 것 같습니다.