インフラジスティックス・ジャパン株式会社のBlog

インフラジスティックス・ジャパン株式会社のチームメンバーが技術トレンド、製品Tips、サポート情報からライセンス、日々の業務から感じることなど、さまざまなトピックについてお伝えするBlogです。

Web における ソフトウェア パフォーマンス - Software Performance [Web]

f:id:pnishimura:20190628144207p:plain

弊社のブルガリアオフィス勤務の コンスタンティン・ディネフ (Konstantin Dinev) が Web における ソフトウェア パフォーマンス(性能)についての非常に有効なブログ記事を寄稿しました。

Web アプリケーションのパフォーマンスについてお悩みの方は是非ご参考頂ければ幸いです。

原文(英語)は こちら

---------------------------------------------------------------------------------------------------------

ソフトウェア製品を製造する際に考慮すべき要素として、最も重要ではないにしても、パフォーマンス(性能)は最も重要な要素の1つです。

新しいユーザーによるソフトウェアの採用、およびそれらのユーザーのソフトウェアへの定着するか否かは、そのソフトウェアのパフォーマンスの良し悪しに大きく依存します。

Google の検索エンジンに関する非常に有名な逸話として、「意味のある検索結果とは、検索開始から3秒以内にユーザーに返される必要がある」という話があります。

3秒を過ぎると、ユーザーはブラウザの更新ボタンを押して、何か問題があるのでは?と考えます。

ただし、検索エンジンにとってパフォーマンスは重要ではありません。

ユーザーは、毎日使用するすべてのソフトウェアが、高速にロードされ、対話に流動的に対応することを期待します。


ソフトウェアのパフォーマンスの側面 - Software Performance Dimensions
ソフトウェアのパフォーマンスとは、私たちが実装できる単一の機能でも、私たちが単純に測ることができる測定でもありません。
ソフトウェアのパフォーマンスとは、ソフトウェアの「一般的な振る舞い」と言えます。

私たちが製造するソフトウェアのすべての機能は、それらが個々の場合でも、組み合わせた場合でも、どれだけうまく機能するかを考慮に入れる必要があります。

ソフトウェアのパフォーマンスを測定し、それを改善するために試みることができる3つの主な側面があります。
  - ロード時のパフォーマンス
  - 実行時のパフォーマンス
  - ソフトパフォーマンス

私たちのソフトウェアのパフォーマンスを向上させようとするときは、3つの側面すべてを考慮する必要があります。
それらのどれか一つだけを追いかけても、私たちのユーザーの一般的な満足度は向上しません。


ロード時間のパフォーマンス - Load Time Performance
これはおそらく私たちが観察し測定できる3つの側面の最も簡単なひとつです。
ロード時のパフォーマンスとは、単にソフトウェアアプリケーションのロード速度です。
デスクトップアプリケーションの場合、ロード時間とは、ソフトウェア実行可能アプリケーションを起動するユーザーの操作からユーザーがソフトウェアとの対話を開始できる時間までの時間です。
この測定値を「Time to Interactive (対話までの時間)」と呼びます。ロード時間のパフォーマンスは、新しいユーザーをオンボーディング(利用開始)するために非常に重要です。


実行時のパフォーマンス - Run-time Performance
実行時パフォーマンスは、ソフトウェアがユーザーの操作にどの程度反応するかによって定義されます。
実行時のパフォーマンスは、アプリケーション内のナビゲーションごと、およびアプリケーション内のコンポーネントとの対話ごとに異なります。
実行時パフォーマンスの測定は、個々のコンポーネントの応答性、一般的なビューの応答性、ビュー間のナビゲーション、メモリ消費など、複数のレベルで行われます。
実行時のパフォーマンスは、ユーザーの定着にとって重要です。


ソフトパフォーマンス - Soft Performance
ソフトパフォーマンスは、ソフトウェアの一般的なユーザビリティによって定義されるため、最も複雑な側面です。
ユーザーを観察し、ソフトウェアが意図している一般的なタスクを実行することがユーザーにとってどれほど簡単で直感的であるかを評価することによって測定されます。

ソフトパフォーマンスはそれだけでたくさんの側面を持っています。

ユーザーが使いたい機能を見つけてナビゲートするのがいかに簡単か?、
アプリケーションの外観をどのように魅力的にするか?、
エンドユーザが行った誤った操作を行ったことをエンドユーザ自身が理解するために、
ソフトウェアが作り出すエラーメッセージがどれほど有用なものであるか?、など。


Web におけるパフォーマンス - Performance in Web
Web でのパフォーマンスは、ソフトウェアの作成方法やクライアントマシンのハードウェアには依存しないため、複雑な問題です。
また、使用されているブラウザの種類や、資産とリソースの最適化方法にも大きく左右されます。

過去10年間で、Windows XP と Internet Explorer 6、7、8(それぞれ9と10も)のサポートが終了したことで、状況はずっと良くなりました。

ただし、最新バージョンの Windows には、まだ Internet Explorer 11 が付属しています。
一部のレガシーアプリケーション、特に ActiveX モジュールをまだ含んでいるアプリケーションでは、IE11 を実行する必要があります。

このシナリオがエッジケースであると思うなら、まだ存在するそのようなエンタープライズアプリケーションがたくさんあることを知っておくべきです!

IE11 を念頭に置いて、Web アプリケーションのパフォーマンスはさらにトリッキーになります。

Web アプリケーションについて考慮する必要があるさまざまなパフォーマンスの側面と、ユーザーに可能な限り最適なパフォーマンスを提供するためにどのように取り組むべきかを見てみましょう。

前述の概要に基づいて、ロード時のパフォーマンス、実行時のパフォーマンス、およびソフトパフォーマンスを調べてみましょう。


Web でのロード時間 - Load Time in Web
ロード時間パフォーマンスは、ブラウザでのユーザー要求からアプリケーションが対話式になるまでの間に、アプリケーションのロードにかかる時間です。

Web アプリケーションのロード時間パフォーマンスを測定するために使用できるさまざまなツールがあります、そして一般的にそれらはツールが測定する各パフォーマンス面を改善するためにあなたが何をすべきかに関する提案をあなたに与えるでしょう。

現在、私がお勧めするのは、アプリケーションの Lighthouse スコアを測定することができる「Lighthouse Google Chrome 拡張機能」を使うことです。

f:id:pnishimura:20190628144207p:plain

Lighthouse performance report

最初に確認する必要がある値は、次のとおりです。
First Contentful Paint
First Meaningful Paint
Time to Interactive


First Contentful Paint
First Contentful Paint は、最初のテキストまたはイメージがページにレンダリングされるときです。
First Contentful Paint は、アプリケーションに必要なリソースをダウンロードする時間と、DOM のレンダリングを開始する前にブラウザが実行する必要がある作業に完全に依存します。

アプリケーションの First Contentful Paint までの時間を短縮するには、最初にアプリによってダウンロードされるリソースのサイズと数を最小限に抑える必要があります。また、外部スタイルシートなど、レンダリングを妨げる外部リソースの数も最小限に抑える必要があります。

それが終わったら、必ず次のことも実行してください。

1. リソースのキャッシング。

2. JavaScript ファイルや CSS スタイルシートなどのテキストベースの資産の縮小化。

Uglify.js は友達です!

3. テキストベースの資産の圧縮化。

最近のすべてのブラウザは、Brotli や gzip 圧縮をサポートしています。

4. テキストベースの資産から未使用のコードを削除。

Angular などの最新の JavaScript フレームワークでは、クライアントマシンに配信されるペイロードのサイズを最小限に抑えるために、ツリーの揺れとコード分割のメカニズムが採用されています。古いコードベースでは、使用されなくなった古いスタイルシートへのリンク、および廃止された JavaScript ファイルへのリンクを必ず削除してください。


First Meaningful Paint
First Meaningful Paint は、ページの主要コンテンツが表示されているときです。
ページはまだ完全にインタラクティブではありませんが、エンドユーザーにはレンダリングされたコンテンツが表示されます。

アプリケーションの First Meaningful Paint までの時間を短縮するには、アプリケーションの クリティカル レンダリング パス の最適化を検討する必要があります。
クリティカルレンダリングパスは、アプリケーションの HTML、CSS、およびJavaScript リソースの受信から、これらのリソースが生成することを意図した最終結果を表すユーザー画面上のピクセルのレンダリングまでの間に実行する必要がある集合操作です。

First Meaningful Paint が作成されるまでにアプリが要する時間を最適化するには、レンダリングブロッキングリソース、特に CSS の最適化に取り組みます。 CSS はレンダリングをブロックするリソースです。スタイルシートがないと、アプリケーションの外観がまったく異なるためです。

CSS リンク参照に適切なメディアルールを提供することで CSS を最適化できます。たとえば、CSS に特定のデバイスの向きや特定の画面サイズに関するメディアクエリの注釈が付けられている場合、それはレンダリングのブロックとは見なされず、レンダリングが遅れることはありません。

つまり、メディア固有の CSS をメインの CSS ファイルから分割して別々にロードすると、アプリケーションのパフォーマンスが向上します。
クリティカル レンダリング パス のパフォーマンスの最適化に関する詳細情報と提案については、以下の記事を参照してください。

developers.google.com


Time to Interactive
Time to Interactive は、あなたのページが完全にインタラクティブになるのにかかる時間です。 つまり、コンテンツが完全に表示されるだけでなく、すべてのページイベントハンドラが表示されるコンテンツにすでに登録されており、ページは 50ミリ秒以内にユーザーの操作に応答します。

いくつかのアプリケーションは、対話性を犠牲にして First Contentful と First Meaningful Paint を最適化します。 これは、ユーザーにとって最適とは言えない体験を生み出すため、ユーザーを敬遠する可能性があります。 完全に表示されるページと、イベントハンドラがまだ添付されていないためにユーザーの操作に応答しないページを表示するのはかなり混乱します。

Time to Interactive を最適化するために、ページの読み込み中に実行されている不要なJavaScript の実行をすべて延期または削除します。 対話時間の最も重要な尺度は、JavaScript の起動時間と JavaScript のペイロードサイズです。


Web での実行時パフォーマンス - Run-time Performance in Web
実行時パフォーマンスは、アプリケーションがユーザーの操作にどの程度反応するかによって定義されます。

アプリケーションのパフォーマンスのボトルネックを特定する最善の方法は、ブラウザ開発者ツールを使用することです。
私の個人的な好みは Chrome 開発者ツール です。

f:id:pnishimura:20190628150243p:plain

Chrome Dev Tools performance tab

アプリケーションのメモリリークを特定するには、開発ツールが提供するメモリプロファイラを使用するのもよいでしょう。これらはアプリケーションのパフォーマンスを低下させる原因になります。

Angular や React などの SPA(シングルページアプリケーション)フレームワークを使用する場合、アプリケーション全体が1つの Web ページとして実行され、リソースを適切に解放しないと、パフォーマンスが低下するだけでなく、一定期間使用された後にクラッシュすることもあります。

メモリプロファイリングとリークの検出についてのよい入門書がここにあります。

Web アプリケーション内の個々のコンポーネント、およびそれらすべての間の対話性によって、アプリケーションの実行時のパフォーマンスが決まります。 Web アプリケーションの優れた実行時パフォーマンスを確保するためには、次のガイドラインを考慮する必要があります。

1. DOM ノードの数と DOM ノードツリーの深さを最小限に抑えます。

DOM ノードをできるだけ少なくするようにしてください。推奨事項は、合計で1500未満のDOMノード、および32未満のDOMツリーの深さです。

2. DOM 要素にアタッチするイベントハンドラの数を最小限に抑えます。

イベントハンドラはできるだけ少なくするようにしてください。たとえば、リスト内の同じ種類の要素に対してイベントハンドラを繰り返す場合は、個々のイベントハンドラではなく、リスト内のターゲット要素に単一の委任イベントハンドラをアタッチします。

3. アプリケーション内の画像のサイズを適切に設定します。

画像が中に配置されているコンテナよりも大きくないことを確認します。画像が大きいと、ロード時間とランタイムパフォーマンスが大幅に遅くなります。

4. オフスクリーンイメージの読み込みを延期する。

すぐに表示されるべきではないイメージには、読み込みの延期ポリシーがあることを確認します。


Web のソフトパフォーマンス - Soft Performance in Web
ソフトパフォーマンスは、アプリケーションの一般的な UX(ユーザーエクスペリエンス)によって定義されます。

ソフトパフォーマンスを測定することはできませんが、あなたができることはあなたのアプリケーションのユーザビリティのボトルネックを発見するためにあなたのアプリケーションのコアコンポーネントのためのユーザビリティ調査を実行することです。

このような研究は、物理的な観察を行う UX の専門家によって、またはユーザビリティ研究に参加している被験者のユーザインタラクションを記録するソフトウェアによって作成および実行されます。

ユーザビリティ研究のための優れたツールは Indigo.Design です。

これはあなたがあなたのアプリケーションの模擬プロトタイプを作成することを可能にし、そしてそれからユーザビリティ研究を定義し実行することを可能にします。

このツールが生成するレポートのサンプルは こちら です。

一般に、アプリケーションのソフトパフォーマンスを向上させるには、次のことが必要です。

1. 主要機能にすぐにアクセスできるか?

ユーザーの大部分が特定の機能にアクセスするようにしたい場合は、直接その機能をユーザーに提示するか、それにつながるナビゲーション要素を作成します。コア機能はあなたのページとの2つのユーザーインタラクション内でアクセス可能であるべきです。

2. コアナビゲーション要素はページ上で簡単に区別できるか?

あなたの「行動への呼びかけ」であるか、コア機能にナビゲートするナビゲーション要素があるなら、それがページの他の部分と混ざらないことを確かめてください。ページがロードされたときにオフスクリーンにならないようにします。それより大きいフォントと対照的な色を使用してください。

3. 情報の流れは一貫しているか?

関連情報がページに散らばっていないことを確認してください。通常、ユーザーは左上隅から斜めに情報を調べます。

4. あなたのコンテンツはアクセスしやすいか?

a11y(アクセシビリティ) は Web には欠かせません。アプリケーションのアクセシビリティテストを必ず実行してください。
Lighthouse Chrome 拡張機能では、アクセシビリティレポートも作成されています。

以下の例は、Ignite UI for Angularグリッドコンポーネント は、データフィルタリングの有用性についてどのように取り組んだか?について説明します。

コンポーネントで使用できる2つの異なるフィルタリング UI がありますが、どちらか一方との一般的な対話は、コンポーネントとの2つの対話内で、ユーザーがフィルタリング結果を取得するというものです。

最初のモードでは、グリッドヘッダ要素の真下に静的な行に常に表示されるフィルタチップがあります。
フィルタチップをクリックすると、フィルタ行が対応する列のフィルタ入力に遷移し、入力にフォーカスが移り、フィルタする条件(文字列列の場合は「含む」)がすでに選択されています。
UI は入力可能です。ユーザーが入力を開始すると、入力内容に従って列がフィルタリングされます。

f:id:pnishimura:20190628165146g:plain

Ignite UI for Angular - igx-grid (グリッドコンポーネント)

ご覧のとおり、フィルタリングされた結果は、コンポーネントとの2つのユーザーの対話の中でユーザーが利用できます。 スクリーンショットからはっきりしないのは、このコンポーネントにも完全にアクセスできるということです。 フィルタチップ要素はキーボードのみでアクセスすることもでき、フィルタリングはキーボードのみを使用しても適用することができる。 要素も画面読み取り可能です。 私はこのコンポーネントを例として挙げていますが、それはアプリケーションと比較するのに十分複雑だからです。


その他の考慮事項 - Other Considerations
3つのパフォーマンスの側面すべてをまとめて検討する必要があることに注意してください。 一方に集中すると、もう一方に悪影響を及ぼす可能性があります。

例としては、実行時のパフォーマンスに重点を置き過ぎることが考えられます。これは、ソフトパフォーマンスの面で低下を招く可能性があります。逆の場合も同様です。

この例を、Web ページ上のグリッドコンポーネントを使用して説明します。

グリッドコンポーネントは、一般に、大量の表形式データを視覚化することを目的としています。 ロード時および実行時のパフォーマンスに関する Web アプリケーションの要件を満たすには、レンダリングする DOM 要素を仮想化し、ユーザーがコンポーネントのコンテナで垂直方向および水平方向にスクロールするときに DOM 要素を交換または再利用する必要があります。 これが既存のさまざまなグリッドコンポーネントでどのように見えるかを見てみましょう。

f:id:pnishimura:20190628165539g:plain

ag-grid (他社製品) の 縦スクロール

f:id:pnishimura:20190628170626g:plain

igx-grid (インフラジスティックス製品) の縦スクロール

どちらのグリッドも実行時のスクロールパフォーマンスが優れていることに注目してください。
ただし、最初のグリッド(ag-grid)は、実行時のパフォーマンスを向上させるために行われた、デバウンスされたスクロール処理が原因で発生する、ちらつき があります。

これは、スクロールイベントとレンダリングの間に遅延があることを意味します。
その結果として、最初のグリッドはランタイムパフォーマンスを優先してソフトパフォーマンスが低下しています。


まとめ - Conclusion
ソフトウェアのパフォーマンスは非常に幅広いトピックであり、この記事で私が行ったことは、ソフトウェアのパフォーマンスを一般的なパフォーマンスの概念として見ながら、その表面を削り取ったことです。

また、私の同僚である、Brian Lagunas (ブライアン・ラグナス) は、WPF のパフォーマンスに関するヒントを掲載した素晴らしい記事 を作成しています。

次回は、フレームワークとテクノロジに固有のパフォーマンスの側面における、Angular Web アプリケーションのパフォーマンスについて詳しく解説したいと思います。


著者 - WRITTEN BY

f:id:pnishimura:20190628171116j:plain

Konstantin Dinev - コンスタンティン・ディネフ
Director of Product Development @Infragistics https://www.infragistics.com/
情熱的なコーダーであり、eSports にも夢中。個人的な時間にて「Bellum Gem」にも取り組んでいます。

jp.infragistics.com