안드로이드 운영체제 버전과 웹뷰 문제
웹뷰(WebView)에서 문제가 생겼을 때 똑같은 테스트 장비의 모바일 브라우저로 보면 멀쩡하게 나와서 사람을 황당하게 만드는 경우가 종종 있다.
예컨대 모바일 크롬에서는 정상적으로 표시되는 페이지가 완전히 같은 크기의 웹 뷰에서만 엉망으로 출력된다면 그 이유는 무엇일까?
우선 안드로이드 버전별 웹뷰의 차이점을 간략하게 짚어보자. 안드로이드 4.4 미만 버전, 4.3 밑으로는 안드로이드 웹뷰의 렌더링 엔진은 크롬과 다르다. 이 기간동안 웹뷰의 바탕이 되는 것은 애플의 Webkit 코드 이다. 사파리 브라우저에 가까운 것이다. 물론 2013년 6월 크롬 버전 28이 나오기 전에는 크롬도 Webkit 엔진을 사용했다. 그리고 변경된 Blink엔진 또한 Webkit 기반이다보니 한 2년 전만 해도 별 문제가 없었던 것이다.
그런데 크롬은 안드로이드 운영체제와는 별개의 앱으로 독자적으로 업데이트 될 수 있는 반면에 웹뷰는 안드로이드 5.0 이전까지는 시스템 업그레이드를 거쳐야만 업데이트 할 수 있었다. 이런 상황에서 시간이 점점 지나면서 파편화 이슈가 맞물리면 “안드로이드 버전은 4.4 언저리에서 지원이 끊긴 상태라 구형 웹뷰를 갖고 있는데 크롬 앱은 업데이트 되면서 렌더링 엔진이 갈아치워진” 어정쩡한 핸드폰이 늘어나기 시작한다. 가면 갈수록 크롬에서 렌더링된 페이지와 웹뷰에서 렌더링된 페이지가 서로 다른 경우가 생기게 되는 것이다. 특히 CSS3 지원 문제가 골치아픈데 vendor-prefix 문제부터 시작해서 버그 픽스의 반영 여부 등등이 누적되다보면 모바일 브라우저에서 잘 나온다고 떡하니 웹뷰에 올렸다가 와장창 박살나는 페이지를 볼 수 있다.
안드로이드 진영에서도 이 문제를 인지하고 있었던지 안드로이드 5.0부터는 웹뷰도 독자적으로 업데이트 될 수 있도록 변경되었다. 하지만 2016년 8월 1일자 자료만 봐도 안드로이드 5.0 이상인 기기는 전체의 50%를 겨우 넘는 수준에 불과하다. 아직도 버전별 점유율에서는 안드로이드 4.4가 29.2%나 된다.
내가 부딪힌 문제는 크게 vh, vw 지원 문제와 repeating-linear-gradient() 구현상의 렌더링 문제였다.
화면 크기가 워낙 다양한 세상이다보니 % 기반으로 엘리먼트의 width, height를 지정하는 것이 기본사양처럼 되었는데, vh와 vw도 이 다중 해상도 문제를 해결하는 데 아주 훌륭한 열쇠이다. 특히 % 기반으로 화면을 짜다 보면 margin-top 같은 곳에서 크게 혼쭐나는 경우가 있다. margin-top에서 %값을 주면 width를 기반으로 값을 계산해버리기 때문이다. 왜 이런 황당한 스펙이 지정되었는가는 논란의 여지가 있을 수 밖에 없는데 우선 long-page 등의 디자인을 생각해보면 웹에서 width보다 height의 변화가 극심하다는 것은 자명한 사실이다. 따라서 parent의 높이값에 맞춰 margin-top이 변화하는 디자인은 width에 기반한 경우보다 훨씬 불안하고 예측 불가능한 디자인이 될 것이다. 한편으로 margin:3%; 같은 코드에서 상하좌우 margin 값은 같아야 할까 달라야 할까? 어느 쪽도 명쾌하게 정답이라고 말하기 힘들 것이다. 이런 황당한 스펙을 지정하게 된 배경에 어떻게 고민이 없었을까. 그렇다고 해도 상/하 값을 계산하는 데 좌우 길이가 영향을 준다는 디자인이 용서가 되는 것은 아니다. 모바일에서 landscape와 portrait 전환이 일어날 경우를 생각해보자. 이건 또 하나의 지옥문을 연 것과 마찬가지다. 세로에서 가로로 전환될 때 부모의 높이가 %, 자식의 margin-top이 %라고 가정해보면 부모의 높이는 절반 정도로 줄어들고 자식의 margin-top 값은 거의 두 배가 늘어난다. 이런 상황에서 페이지가 의도대로 렌더링 된다면 기적이나 마찬가지다. 결국 margin-top 을 %로 조절할 수 없다는 결론에 도달하면 media 쿼리를 이용해 섬세하게 breakpoint를 설정하는 방법이 차선책이 될 것인데 media 쿼리는 조금만 해상도가 복잡해져도 황당할 정도로 테스트 비용이 늘어나게 된다. 여기까지 막다른 골목에서 고통받다 보면 Card-based 디자인이나 Grid 등 최신 트렌드인 웹 디자인이 단순히 미적인 측면을 넘어서 개발 과정의 비용을 줄일 수 있도록 많은 고민을 했다는 사실을 깨닫고 무릎을 탁 치게 된다.
이런 고민으로부터 해방될 수 있는 열쇠 중 하나가 바로 vh인데, vh는 100일때 뷰 포트의 높이 100%에 해당하므로 margin-top:3vh; 같은 식으로 높이의 3%에 해당하는 margin 값을 쉽게 줄 수 있도록 되어 있다.
그런데 vh 같은 스펙은 IE에서 잘 지원되지 않는 것은 물론이고 안드로이드 웹뷰에서도 최소 킷캣(4.4)은 되어야 똑바로 보이기 시작한다.
vh나 vw를 사용하면 전체 안드로이드 사용자 중에 20% 정도가 제대로 된 화면을 볼 수 없게 된다. 물론 국내에서는 그 비율이 상당히 낮기는 하겠지만 그렇다고 무시해도 좋은 수준은 결코 아닌 것이다.
CSS 문제 중에 또 하나 골치아팠던 점은 repeating-linear-gradient 속성이었다. 배경색에 빗금을 치는 부분이 있어서 그림파일로 때우는 것 보다 CSS로 구현하는 것이 여러모로 낫다고 판단했는데 구형 웹뷰에서 빗금이 너무 굵게 렌더링되는 버그가 있었다. 결국 CSS를 걷어내고 8px X 8px 짜리 빗금 배경화면을 반복하는 것으로 수정하였다.
해상도와 버전이 각각 파편화되고 제조사별 특징까지 파편화되는 안드로이드 생태계에 만병통치약은 아직인 것일까?