필자는 현재 프런트엔드 개발자지만 Webkit 기반의 브라우저를 개발한 적이 있다. 주로 HTML5 스펙 지원과 각종 CSS 기능을 지원하기 위해 렌더링 엔진을 다양한 운영체제에 맞게 포팅하는 것이었다. 렌더링 엔진의 추상화된 레이어는 동일하지만, 실제 장치에서 가용한 하드웨어에 따라 성능 차이가 존재한다. 단일 스레드를 사용했는지, 프로세스를 분리해서 구현했는지, GPU를 사용할 수 있는지 등에 따라서 렌더링 결과와 성능은 천차만별이었다. 렌더링 차이는 보통 렌더링 엔진이 다른 경우에 발생하지만, 같은 렌더링 엔진을 사용하더라도 기능 차이가 있는 이유가 여기에 있다.. 그에 따라 사용자와 프런트엔드 개발자에게는 크로스 브라우저 이슈라는 엄청나게 신경 쓰이면서 고된 업무를 떠안아야 하는 숙명이 생기기도 했다. 그 옛날에는 크로스 브라우저 이슈(브라우저나 장치마다 렌더링이 다른 문제)를 해결하는 것이 돈이 되었던 것도 어느 정도 수긍이 간다.
어쨌든 브라우저를 개발하는 것이 얼마나 복잡한 시스템을 만드는 일인지 이때 많이 알게 되었다. 간혹 transform: translateZ(0);
을 일종의 기법으로 사용하기도 하지만 이것을 구현하기 위해 렌더링 엔진이 얼마나 복잡하게 돌아가는지 알게 된다면 깜짝 놀랄 것이다. 프런트엔드 개발자로서 브라우저 내부 구현을 일일이 알아야 만 웹페이지를 개발할 수 있는 것은 아니지만 어느 정도 특징과 영향도를 알고 개발하는 것은 심도 있는 개발에 많은 도움이 된다.
얼마 전 Chromium의 블로그에 RenderingNG
라는 글이 발표되었다. 이 글을 그대로 번역하기보다 프런트엔드 개발자 입장에서 궁금할 만한 내용을 추려서 브라우저의 발전 방향을 파악할 수 있도록 정리했다. 원문의 모든 것을 다루고 있지는 않기 때문에 더 많은 내용이 궁금하다면 RenderingNG의 원문과 함께 읽어 보면 도움이 될 것이다.
RenderingNG(Rendering Next Generation)는 Chromium의 차세대 렌더링 아키텍쳐다. RenderingNG의 가장 큰 목적은 크로스 브라우저 이슈를 최대한 없애고 안정적인 렌더링 성능을 구현하는 것이다.
어느 순간 짜잔하고 "우리가 새로운 걸 가져왔어. 한번 써볼래?"는 아니다. Chromium 기반의 브라우저를 사용하고 있는 지난 8년에 걸쳐서 차곡차곡 개선하고 적용해 온 아키텍쳐며 Blink 엔진에 적용되고 있다. Chrome 사용자는 RenderingNG를 이미 쓰고 있다는 의미다. RenderingNG가 우리가 전혀 알지 못했던 새로운 기술은 아니다. 이 글을 통하여 많은 에버그린 브라우저가 어떤 방향으로 변화하고 있는지를 이해하는 데 도움이 될 것이다.
출처: https://developer.chrome.com/blog/renderingng/
처음 RenderingNG 소식을 접했을 때 Chromium 혼자서 또 새로운 표준(가령 Pepper plugin API 같은)을 만들려는 시도가 아닌가 의구심이 들었다. 그러나 Gecko, Webkit도 궁극적으로 모든 브라우저가 공통의 기준선을 만들고 개발자가 신뢰할 수 있는 렌더링 기능과 안정적인 성능을 제공하는데 같은 생각을 하고 있고 표준화된 테스트를 만들고 있다는 것을 보고 어느 정도 의구심이 해소되었다.
RenderingNG의 글을 보고 필자가 궁금했던 내용을 크게 두 가지로 꼽았다.
Chromium은 RenderingNG를 구축하는 동안 수만 개의 단위, 성능 및 통합 테스트를 작성해왔다. 수만 개의 테스트라니 상상도 하기 어려운 숫자이지만 렌더링의 안정성 측면에서 매우 많은 테스트가 필요한 것은 공감한다.
그 중 웹 플랫폼 테스트는 브라우저, 장치 및 운영체제 사이에 렌더링이 다른 문제를 테스트하고 해결할 방법이다. 이 테스트는 모든 브라우저에서 실행될 수 있도록 작성되어야 하며, 따라서 모든 브라우저가 다른 브라우저 구현체와 호환되는 기능을 제공한다는 신뢰를 준다. 웹 플랫폼 테스트는 Chromium, Edge, Firefox, Safari 등 다양한 브라우저 개발자들과 함께 만든다고 하니 Chromium팀의 독주(?)로 인한 편파적인 테스트는 아닐 것이다.
다음 그림은 주요 브라우저의 웹 플랫폼 테스트의 호환성 점수를 나타낸다.
출처: https://wpt.fyi/compat2021?feature=summary
서두에서 예로 들었던 transform: translateZ(0);
을 테스트하는 케이스도 있다. 레이어 합성(Layer Composite) 구현이 잘 된 브라우저라면 렌더링 결과에서 녹색 사각형만 보여야 한다. 그렇지 않을 경우 빨간색 사각형이 보이게 된다. 이 테스트를 통과한 브라우저는 다른 브라우저와 렌더링 호환율이 향상된다고 생각하면 된다.
테스트 URL - https://wpt.live/css/css-transforms/perspective-translateZ-0.html
웹 플랫폼 테스트는 깃허브에서 관리되고 있으므로 관심이 있거나 기여하고 싶은 사람은 방문해 보자.
브라우저가 구동되는 장치나 운영체제에 따라 안정적인 성능을 제공하는 것도 RenderingNG의 중요한 목표다. 확장 가능한 성능(Scalable Performance)는 웹 페이지가 원활히 동작하고 반응성이 높으면서도 로우엔드 및 하이엔드 시스템과 운영체제에 따라 안정적으로 잘 수행되는 아키텍처를 구성하는 것이다. 하드웨어가 제공하는 모든 것을 활용해서 안정적인 성능을 제공하고 필요할 때만 하드웨어를 사용한다.
이를 위해 캐싱, GPU 하드웨어 가속, 성능 격리(Performance Isolation) 등의 기법을 더 적극적으로 활용하고 있다.
캐싱은 이미 렌더링 된 픽셀을 재활용하는 것이다. 특히 스크롤 빠르기와 프레임 속도가 빨라진다. 또한 스크롤은 다른 스레드에서 동작하므로 메인 스레드의 속도를 늦추지 않는다. 반대로 메인 스레드에서 무거운 자바스크립트 작업이 실행 중이더라도 스크롤의 속도는 떨어지지 않는다는 의미다.
출처: https://developer.chrome.com/blog/renderingng/
또한 GPU를 사용하면 병렬로 픽셀을 생성하고 화면에 그릴 수 있으므로 속도가 빨라진다. RenderingNG는 모든 플랫폼과 장치에서 GPU를 보다 적극적으로 활용하여 렌더링 및 애니메이션을 빠르게 한다. GPU 가속은 대개 별도의 프로세스에서 진행되므로 메인 프로세스의 속도를 떨어트리지 않을 수 있다.
이런 기법은 메인 스레드 혹은 메인 프로세스와 별개로 실행되므로 렌더링에 의한 메인 실행 컨텍스트에서 처리 속도 저하에 영향을 적게 미친다. 반대로 말하면 메인 스레드 혹은 메인 프로세스가 바쁘게 돌아가더라도 렌더링 속도는 빠르게 유지될 수 있다. 이러한 형태를 성능 격리(Performance Isolation)라고 한다.
출처: https://developer.chrome.com/blog/renderingng/
그 외에도 content-visibility나 OffscreenCanvas 지원, iframe을 더욱 격리하는 옵션 등 불필요한 렌더링은 배제하고 성능 격리를 더욱 적극적으로 도입하여 부드러운 렌더링을 제공하려는 기능들이 많이 보인다. 서두에도 말한 것처럼 이것이 전부는 아니다. 각각 자세한 내용은 해당 블로그에서 앞으로 계속 설명할 예정이라고 한다.
RenderingNG로 발표한 내용 중에서 프런트엔드 개발자가 알고 있으면 좋을 내용을 간략하게 추려보았다. 웹 페이지를 개발하다 보면 "지원 브라우저가 뭐예요?", "몇 버전까지 지원해야 하나요?", "모바일은 지원하나요?", "안드로이드와 iOS 둘 다 지원하나요?" 와 같은 질문을 하게 된다. 웹 페이지가 다양한 플랫폼과 브라우저를 지원하는데 그만큼 큰 노력이 들기 때문에 미리 결정하는 것이다. RenderingNG로 인하여 공통의 기준선을 갖고 브라우저 간 렌더링 호환성이 높아진다면 얼마나 좋을까 하는 생각을 해본다. 시간이 흘러 "크로스 브라우저 이슈가 뭐예요?"라는 날이 온다면, 그날은 동료들과 함께 조촐하게 랜선 회식이라도 해보자. (RenderingNG의 모든 개선 사항은 2021년에 완료하는 것이 목표라는데....아...)
원문에서 사용한 이미지 라이선스