본문 바로가기

Personal Posting/Flutter

Flutter 웹 로딩 속도 최적화

 

Flutter로 관리자페이지나 관제페이지와 같은 웹 개발을 하면서 느꼈던 점은 기존에 사용했었던 ReactJS와 비교해서 특별히 아쉬웠던 점은 없지만 초기 로딩 속도가 좀 불만족스러웠다는 것이다. 둘 다 사용했던 입장에서 각각 자신들만의 장단점은 존재하나 이 부분은 확실히 ReactJS쪽의 우세라고 생각한다. (물론 상대적으로 느린 것이지 실제 사용에는 불편함이 없었다.) 오늘은 Flutter에서 웹 로딩 속도 퍼포먼스를 최적화하는데 도움이 되는 블로그를 찾게 되어 정리해 보았다.

 

1. CanvasKit과 Wasm 렌더링

  1) CanvasKit

    - Flutter 웹에서 기본 렌더러 중 하나로 사용되며 WebGL을 활용해 고성능과 픽셀 일관성을 제공한다.

    - 복잡한 그래픽 애니메이션이 필요한 앱에 적합하지만, 약 1.5MB의 파일 크기로 인해 초기 로딩 시간이 길어질 수 있다.

    - flutter.js API는 CanvasKitmain.dart.js를 병렬로 다운로드하지만, 앱의 모든 위젯이 완전히 로드될 때까지 대기해야 하므로 초기 상호작용이 지연될 수 있다. 

  2) Wasm 렌더링

    - WebAssembly(Wasm)는 CanvasKit보다 앱 크기를 줄이고, JavaScript보다 빠르게 시작할 수 있는 장점이 있다.

    - 현재까지는 실험적인 기능으로 제공되며, 최신 Flutter 문서를 확인하면서 사용해야 한다.

    - 제약 사항:

      - dart:html 패키지는 Wasm 빌드에서 지원되지 않음

      - 대신 package:webdart2wasm, dart2js를 사용할 수 있음

 

2. 코드 분할: Lazy Loading (지연 로딩)

  1) Deferred Imports (지연 임포트)

    - 코드의 일부를 필요할 때만 로드하여 초기 로딩 시간을 줄일 수 있다.

    - 사용 방법:

      - import문에서 deferred 키워드를 사용해 선언

      - 필요한 시점에 loadLibrary() 메서드를 호출해 비동기적으로 라이브러리를 로드

import 'package:myapp/hello.dart' deferred as hello;

Future<void> loadHelloLibrary() async {
  await hello.loadLibrary();
  hello.sayHi();
}

 

  2) Unawaited Function Calls

    - 초기 위젯을 표시할 때 시간이 오래 걸리는 Future 작업을 기다리지 않고 비동기적으로 실행할 수 있다.

    - 이를 통해 앱이 더 빠르게 반응할 수 있지만, 상태 관리 및 리소스 관리에 주의가 필요하다.

void main() {
  unawaited(downloadVideos().then((videos) {
    playlist.add(videos);
  }));
  runApp(const MyApp());
}

 

3. 미디어 파일 최적화

  1) 이미지 해상도 최적화

    - Flutter는 디바이스의 픽셀 밀도에 따라 적절한 해상도의 자산을 자동으로 로드한다.

    - 불필요한 고해상도 이미지나 대체 포맷은 관리 비용을 늘릴 수 있으므로 신중히 고려해야 한다.

  2) 차세대 이미지 포맷 활용

    - WebP와 AVIF는 PNG 및 JPG보다 파일 크기를 훨씬 줄이면서 품질 손실을 최소화

    - 예시: PNG: 319KB → WebP: 38KB → AVIF: 10KB

    - 단, 모든 브라우저가 WebP와 AVIF를 지원하지 않으므로 호환성을 사전에 확인해야 한다.

 

4. 캐싱 전략

  1) 메모리 캐시, 디스크 캐시, 서비스 워커

    - 메모리 캐시: RAM에 저장되어 빠르게 접근 가능하지만 휘발성

    - 디스크 캐시: 느리지만 지속성 제공

    - 서비스 워커: 네트워크 프록시로 작동하며 메모리와 디스크 캐싱 전략을 결합 가능

    - Wasm 파일은 브라우저에서 네이티브 바이너리처럼 캐싱되어 빠르게 로드 가능

 

5. 사전 로딩 (Preloading)

  1) HTML <head> 태그 활용

    - <link> 태그를 사용해 이미지를 미리 로드하여 렌더링 지연 방지

<head>
  <link rel="preload" href="assets/logo.webp" as="image" type="image/webp" />
</head>

 

  2) HTTP 응답 헤더 활용 (Firebase Hosting 예시)

    - Firebase Hosting에서 HTTP 응답 헤더를 활용해 리소스를 사전 로드할 수 있다.

"headers": [
  {
    "key": "Link",
    "value": "<assets/logo.webp>; rel=preload; as=image"
  }
]

 

6. 초기 사용자 경험 개선

  1) 랜딩 페이지

    - HTML/CSS로 제작된 랜딩 페이지에서 Flutter 앱을 미리 로드하여 사용자 클릭 시 즉시 실행되도록 설정할 수 있다.

  2) 로딩 / 스플래시 스크린

    - 빈 화면 대신 CSS/HTML로 작성된 스플래시 화면을 사용해 앱이 빠르게 실행되는 느낌을 줄 수 있다.

    - Flutter Gallery 구현 사례를 참고

 

결론

Flutter 웹 애플리케이션의 초기 로딩과 렌더링 성능을 개선하기 위해 다양한 최적화 전략을 소개했는데, 각 방법에는 장단점이 있으므로 앱의 특성과 사용자 요구에 따라 적절한 전략을 선택하는 것이 중요하다. 이러한 접근 방식을 결합하면 더 부드럽고 반응성이 높은 사용자 경험을 제공할 수 있다.

 

아래 링크의 포스팅을 참고하여 정리한 내용입니다. 원문을 확인하고 싶으시면 아래 링크를 확인해주세요.

출처 - https://medium.com/flutter/best-practices-for-optimizing-flutter-web-loading-speed-7cc0df14ce5c