Mirrativ Tech Blog

株式会社ミラティブの開発者(バックエンド,iOS,Android,Unity,機械学習,インフラ, etc.)によるブログです

iOS 18 で Animated WebP 再生時のパフォーマンスが著しく悪くなった問題と対応

こんにちは、iOSエンジニアのいっちー(@0IcchI)です。

ミラティブでは、iOS 18のリリースに備えて、アプリ上に新しい不具合が発生していないかの調査とその対応を進めてきました。

その過程でAnimated WebPの再生に起因する致命的な不具合に出会ったので問題とその対応について紹介します。

背景

ミラティブではアプリ内で画像を表示する際にSDWebImageを使用しており、Animated WebPの再生にも用いています。

SDWebImageはAnimated WebPの再生に2種類のコーダーを提供しています。

  1. SDImageAWebPCoder

    • iOS標準のImageIOフレームワークに含まれるコーダー
  2. SDImageWebPCoder

    • SDWebImage独自のコーダー

SDWebImageWebPCoderのREADMEではそれぞれの違いについて以下のように記述されています。

AppleのImageIOはiOS 14、tvOS 14、watchOS 7、macOS 11以降でWebPのデコードをサポートしています。

そのため、これらのプラットフォーム上では、SDWebImageは組み込みのSDWebImageAWebPCoderを使用してWebP画像をデコードできます。

ただし、いくつかの制限がある可能性があり、詳細はSDWebImageのIssue #3558を確認してください。これらのプラットフォームでこのコーダーを強制的に使用することもできます。

引用:GitHub - SDWebImage/SDWebImageWebPCoder: A WebP coder plugin for SDWebImage, use libwebp

これまで、ミラティブでは iOS標準のImageIOフレームワークに含まれるコーダーであるSDImageAWebPCoderを使用してきました。

SDWebImageではSDImageCodersManagerに使用したいコーダーのインスタンスを渡すことで、以降の処理で画像の表示などにそのコーダーを利用することができます。

SDImageCodersManager.shared.addCoder(SDImageAWebPCoder.shared)

発生していた事象

iOS 18のベータ版を用いた検証により、Animated WebPを再生する際に、以下のような深刻なパフォーマンス問題が確認されました。調査の中で、この問題はiOS 17では発生しておらず、iOS 18から発生する問題であることが分かりました。

事象1: Animated WebPの再生時にUIがフリーズする

不具合挙動ではUI描画が数秒間固まり、ユーザー操作が不能になっている。

左:正挙動 右:不具合挙動

事象2: Animated WebPの再生速度が極端に低下する

不具合挙動では正常な再生ができていない。

左:正挙動 右:不具合挙動

このようなパフォーマンスの問題は、ユーザー体験を大きく損なうため無視できるものではありませんでした。

問題の分析

Instrumentsを用いて問題を分析した結果、次のことが分かりました。

  1. ハングの検出

    • 事象1発生時に5秒以上のハングを検出。
  2. CPU使用率の上昇

    • 両事象発生時にCPU使用率が異常に高くなることを確認。

ハングの検出とCPU使用率の上昇

さらにCPU使用率が上昇している箇所を詳しく分析したところ、Animated WebPのデコード処理に多大な時間がかかっていることが分かりました。

これはImageIOライブラリ中の処理であることが分かります。

デコード処理の詳細

インターネット上で調査したところ、ImageIOフレームワークではiOS 17以前においても、Animated WebPのフレーム間の差分処理のパフォーマンスに問題がある可能性が指摘されていました(参考記事: Bandisoftの説明)。

これがiOS 18でより深刻化している可能性がありそうです。

対応方法

調査を進めた結果、SDWebImage独自コーダーを用いるSDWebImageWebPCoderを利用すると、iOS 18においてもiOS 17以前と同等のパフォーマンスが出ることが分かりました。

SDImageCodersManager.shared.addCoder(SDImageWebPCoder.shared /* SDImageAWebPCoder.shared */)

上記の対応によって、iOS 18におけるAnimated WebPの再生時のCPU使用率が改善し、ハングも発生しなくなりました。

パフォーマンス比較

補足

この問題の再現確認ができるようにiOS 17とiOS 18でのパフォーマンスを比較するプロジェクトを作成し、Appleに報告しています。

今後のiOSアップデートで改善されることを願います!

We are hiring!

ミラティブでは一緒に開発してくれるエンジニアを募集しています!

speakerdeck.com

mirrativ.notion.site

www.mirrativ.co.jp