- 목차 -

제가 실무에서 경험한 웹 최적화에 대한 이야기를 해보려고 합니다. 웹 최적화는 웹 개발을 하다보면 한 번쯤은 고민하게 되는 주제인데요, 요즘은 프레임워크들이 워낙 지원을 많이 하고 잘 되어있어도 정말 간단한 페이지가 아니라면 한없이 부족합니다. 저도 처음에는 어디서부터 시작해야 할지 막막하고 뭘 해야될지 모르겠어서 “이걸 진짜 해야돼?”” 같은 생각이 들다가도, 제가 웹을 사용할 때를 생각해보니 웹에 접속했을 때 5초가 지났는 데도 로딩화면이 지속되면 웹사이트에 접속을 포기하는데요. 특히 한국은 빨리빨리 민족이라고 하잖아요. 로딩이 느리면 이탈률이 정말 높아지는 것 같습니다. 그만큼 로딩 속도가 중요하다는 뜻이겠죠? 로딩 속도 개선을 할 수 있는 방법은 정말 많습니다. 일단 무작정 구현하고 고통받으며 소스 리팩토링을 진행하고 무한반복이었습니다. 여러 프로젝트를 통해 경험을 쌓고, 실패를 하며 적용을 해봤던 다양한 최적화 방법들을 소개하겠습니다.

이미지 최적화

이미지는 웹 페이지에서 가장 많은 리소스를 차지하는 요소 중 하나입니다. 특히 제가 작업한 웹은 아동 학습용 웹이라서 모든 게 이미지로 구성되어있었습니다. 이미지 최적화는 웹 최적화의 가장 핵심입니다.

포맷 변경

JPEG, PNG, GIF 같은 포맷 대신 WebP를 사용합니다. WebP는 더 높은 압축률을 제공하면서도 품질 저하가 적은 웹용 포맷입니다. 제 경험으론 단순한 도형은 PNG, 그라데이션이 많거나 이미지가 복잡할 수록 더욱 용량 차이가 많이 났습니다.

용량비교

파일 관리

사용하지 않는 큰 이미지는 작은 사이즈로 변경합니다. 또 중복되지 않도록 주의를 기울입니다. 개발을 진행하다보면 당연히 까먹어서 동일한 파일이 여러개 사용될 때도 있는데, 괜찮습니다! 리팩토링할 때 하나씩 바꿔주면 됩니다. 시작부터 심혈을 기울이는 걸로…

Lazy Loading

스크롤을 내려 이미지가 위치할 때 이미지를 로드하는 Lazy Loading 방식을 사용합니다. 이미지가 연달아서 20개가 있는 상품리스트 페이지를 접속했을 때를 생각해봅시다. 아무리 작은 사이즈여도 수량이 많다면 다운로드를 하는 데 시간이 오래 걸리겠죠? Lazy Loading을 사용하여 필요할 때 다운로드를 하면 초기 로딩 시간을 매우 단축할 수 있습니다.

컨텐츠 최소화 및 압축을 통해 콘텐츠 로딩을 빠르게 해줍니다. 로딩 속도는 웹 페이지 안에 있는 콘텐츠를 불러올 때 시간이 가장 많이 소요됩니다. 한번은 어드민에서 누군가가 1GB 이미지를 배너에 넣었는데, 메인 로딩 속도가 10초도 넘게 걸렸던 적도 있습니다. 당연한 얘기지만 리소스 용량도 중요하다는 점 잊지맙시다.

소스코드 관리

최소화 및 압축

CSS및 Js 에 사용되지 않는 코드를 제거하여 파일을 최소화하고 적절하게 번들링 또는 스플리팅 합니다. HTTP 요청 수를 줄이거나 필요한 코드만 로드하여 성능을 향상시킬 수 있습니다. 사실 현대에서는 빠른 네트워크 환경으로 크게 영향을 주는 부분은 아니니, 시간을 많이 투자할 필요는 없다고 생각합니다.

스크립트 비동기 로드

스크립트는 대부분 HTML 보다 무겁습니다. 용량도 커서 시간이 소요되고 무엇보다 처리하는 것도 시간이 필요합니다. HTML을 읽는 중에 script 태그를 만나면 script를 먼저 다운, 실행하기 위해 DOM 생성을 멈춥니다. 스크립트를 다운받고 실행한 후에야 남은 페이지를 처리할 수 있습니다. 백그라운드에서 스크립트를 다운로드 하는 defer 또는 async 속성을 활용하여 적절한 상황에 맞게 스크립트를 로드합니다.

<script src="example.js" async></script>
<script src="example.js" defer></script>

font preload

웹 폰트는 사이트의 디자인을 개선하지만, 잘못 사용하면 성능에 악영향을 미칠 수 있습니다. 작은 부분일 것 같지만 전에 잘못된 폰트파일을 사용하여 메인 페이지 로딩이 8초이상 걸렸던 적도 있었습니다. 😓 폰트 파일 용량이 그렇게 클 수 있는지는 처음 알았네요.

  • 불필요한 폰트 제거 - 사용하지 않는 폰트는 로드하지 않기
  • 서브셋 폰트 사용 - 필요한 것만 포함된 서브셋 폰트를 사용
  • Preload 사용 - 중요한 폰트는 Preload를 사용하여 미리 로드

폰트는 가장 먼저 로드하는 것이 좋습니다. 폰트 사이즈 속성을 부여하기는 하지만 폰트마다 간격도 다르고 크기가 다르기때문에 폰트가 나중에 로드되어 적용되면 바로 화면에서 티가나고, 최악의 경우는 레이아웃이 틀어진 게 눈에 띄게 보입니다. CRP 높일 수 있는 방법 중 하나인 폰트 preload다. 폰트를 먼저 로드 함으로써 이후에 콘텐츠를 로드를 할 때 먼저 불러온 폰트를 적용하여 초기 로드 속도를 높일 수 있다. @font-face로 폰트를 로드 시키는 방법보다는 head 태그에서 preload로 로드 후 적용하는 편이 초기 로드 속도에 유리합니다.

🙅‍♀️

@font-face {
  font-family: 'NanumSquareBold';
  src: url('/fonts/NanumSquareBold.woff') format('woff')
}

<link rel="preload" as="font" type="woff" href="'/fonts/NanumSquareBold.woff'">

웹뷰

요즘에는 웹뷰를 사용하는 앱들이 많아졌습니다. 하이브리드 앱이라고 하는데, 껍데기는 안드로이드나 iOS 소스로 패키징하고, 안에 있는 콘텐츠들은 웹을 호출하는 방식입니다. 모바일 API(디바이스 기능)도 사용할 수 있으면서 배포와 유지보수가 편리합니다.

저는 실무에서 웹뷰 작업을 할 일이 가장 많았습니다. 처음에는 지식이 부족해서 일단 구현을 하는 것이 우선이었는데, 유지보수를 하면서 꽤 많은 노력을 쏟아야 했습니다. 기기 안에 들어가는 웹이다 보니 PC에서 보는 것보다 렌더링이 확실히 느렸습니다. 당연히 웹 기반이므로 웹 성능 최적화와 다 동일한 작업이었지만, 더 빡세게 해야 웹과 겨우 비슷해졌었던… 네이티브 개발자들과 노력을 엄청 했던 기억이 있네요.

웹뷰 설정 최적화

하드웨어 가속을 활성화하여 렌더링 성능을 향상시킵니다.

webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);

최신 JavaScript 엔진을 사용하고, 가능하면 JIT(Just-In-Time) 컴파일을 활성화합니다.

webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);

메모리 관리

컨텐츠를 보는 웹 앱이었는데 영상, 음원, 이미지 등 리소스가 많아서 앱 정보에서 보니 캐시가 엄청 쌓였고 사용을하다보면 정말 상상도 못하게 느려졌습니다. 안드로이드 개발자와 트리거를 주고받아 학습이 끝낼 때마다 캐시를 지우는 코드를 넣어 해결했습니다.

필요 없는 웹뷰 객체는 꼭 제거해주어 메모리 누수를 방지합니다.

webView.destroy();

캐싱 전략: 적절한 캐싱 정책을 사용하여 자주 변경되지 않는 리소스를 캐싱합니다. 웹뷰의 캐시 설정을 최적화합니다.

webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setDatabaseEnabled(true);

웹뷰 초기화 지연 로드

필요할 때까지 웹뷰 초기화를 지연시켜 앱 초기 로드 시간을 단축합니다.

webView.post(new Runnable() {
    @Override
    public void run() {
        // WebView 초기화 코드
    }
});

🖥️ 성능 모니터링 및 테스트

항상 마무리가 중요하죠! 이렇게 노력한 결과물을 “오, 좀 빨라졌는데?” 로만 지나치면 조금 아쉽잖아요? 얼마나 렌더링이 빨라졌는지 성능 테스트를 통해 최적화의 효과를 검증하는 것도 중요합니다.

Lighthouse, Chrome DevTools를 사용하여 퍼포먼스나 로드시간을 지속적으로 측정하고 부족한 부분을 최적화 해줍니다.

오늘 소개한 글 적용 결과 ✨

lighthouse 결과

학습을 하는 웹뷰로 메인 페이지부터 애니메이션이 엄청나게 들어간 페이지였는데, 리소스가 가장 중요했습니다. 당연히 어떤 웹이고 어떤 것을 가장 취급을 하는지가 중요

이런 작업들을 통해 웹뷰의 성능을 최적화하고, 사용자에게 더 나은 경험을 제공하는 개발자가 되어봅시다!💪