この記事はGoodpatch Advent Calendar の7日目の記事です。
はじめに
フロントエンド/モバイルアプリエンジニアの古家です。
Goodpatchが提供するオンラインホワイトボード『Strap』では、各種図形や付箋に加えて画像を貼り付けられます。
今回は、日々みなさんが貼り付けている画像について、Strapで行った改善をご紹介します。
背景
Strapのような広大なエリアを拡大縮小できる表示領域(以下、ボード)では、ユーザーはいくつもの画像を自由なサイズや場所に配置できなければなりません。 当然、アプリケーションとしてはメモリ消費や描画速度について対策が必要です。
Strapでは、これらの課題への対策の一つとして、ボードの拡大率によって画像の描画解像度の調整を行なっていました。
ボードの拡大率 | ボード解像度 | 画像解像度 |
---|---|---|
100%~ | 1.5 | 1 |
50% ~ 100% | 1 | 1 |
~ 50% | 0.5 | 0.5 |
問題: 画像が荒く表示される
ところが、一部のユーザーにおいて画像の解像度が正しく表示されない問題が起きているのが、フィードバックから判明しました。 どうやら解像度の調整が正しく働いていないようです🧐
ヒアリングからは、次のようなことが分かりました。
- 元画像の解像度(縦横サイズ)はそれほど低くない
- 画像はそれほど小さく表示されていない
原因: 画像の解像度は一律に決められない
さまざまな画像サイズ、ボード拡大率で再現を試みた結果、1つの原因が分かりました。 画像の描画解像度を、ボードの拡大率から一律に決めていたせいで、一部の条件で意図しない解像度で描画されていました。
このように、ボードの拡大率は低い場合でも、ユーザーにとっては大きなサイズで描画されているケースを見落としていました。 逆のパターンとして、実際は低い解像度で十分な状況でも、高解像度で描画される場合もありそうです。
対策: 画像の見た目の解像度で描画する
対策として、ボードの拡大率に加えて、画像自体の拡大率を考慮するようにしました。 いわゆるボード上の見た目のサイズを元に解像度を決定することで、画像エレメントごとに適切な描画解像度を決定できるようになりました。
// 見た目の拡大率 = ボードの表示解像度(拡大率) * 画像の拡大率 const scaledResolution = boardResolution * imageScale; if (scaledResolution > 0.5) { return 1.0; } if (scaledResolution > 0.25) { return 0.5; } return 0.25;
結果
無事に適切な解像度で画像が描画されるようになりました🎉
なお、実際にはdevicePixelRatioなども考慮しつつ最終的な描画解像度を決定しています。
今回問題となった解像度ロジックについては、ボード上の表示パフォーマンス向上を目的としたものでした。 この変更によってパフォーマンスが著しく低下しては元も子もありません。 次のような記事を参考に、変更の前後でパフォーマンスに大きな影響がないことも確認しています。
今回のケースでは、ユーザーが実際に利用しているボード拡大率や画像サイズにも左右されるため、一概にパフォーマンスを判断することは難しい面もあります。 チーム内でも協議し、判定ロジック部分で大きくパフォーマンスへの影響は見られないと判断し採用することにしました。
さいごに
ユーザー自身がアップロードした画像を扱う場合、それを表示するクライアント側でも表示解像度の調整やキャッシュ処理などを行うことは常套手段です。
加えてStrapでは、今回ご紹介した描画解像度のほかにも、表示領域に応じた描画順や表示のチューニングを行い、自然な利用体験とパフォーマンスの担保を目指しています。
余談ですが、Androidアプリのエンジニアでもある筆者は、これまで非力なデバイスで画像を表示するために、様々な工夫をしなければなりませんでした。 そんな経験も今後の開発に活かしていければと思っています。(とはいえ最近は便利なライブラリもたくさんありますが。Android怖くないよ!🥰)
最後に、Strapチームでは一緒にデザインの可能性を広げてくれる仲間を積極採用中です! お、このサービス面白そう!と思ったそこのあなた!ご応募お待ちしております!
また、Goodpatchとしてもデザイン好きなエンジニアの仲間を募集しています 🤗
- 新卒採用エンジニア 23卒
- 中途採用フロントエンドエンジニア
- 中途採用Androidデベロッパー
- 中途採用iOSデベロッパー