コンテンツへスキップ
Angularアプリのパフォーマンスを向上させる方法は?

Angularアプリのパフォーマンスを向上させる方法は?

Angularアプリのパフォーマンスを向上させる方法は?このブログ記事を読んで、未使用のJavaScriptとCSSを減らす方法から遅延読み込みAngular方法を見つけてください。

8min read

Angularは、最新のWebアプリケーションを開発するための非常に人気があり、広く採用されているフレームワークになっています。このテクノロジーは非常に強力で、機能が豊富です。Web開発者として必要なものはすべてすぐに使用でき、フレームワーク上に構築されたアプリケーションを簡単に構成、保守、および拡張Angularできます。

そして、これまでに 1 つ以上のAngularアプリケーションをすでにまとめていると思いますが、それらは最適でしょうか?

ソフトウェア パフォーマンス シリーズの第 2 回では、Angularの最適化について説明し、私が作成したAngularサンプル アプリを使用してAngularアプリケーションのパフォーマンスを向上させる方法を示します。Chrome Dev Tools を使用して初期灯台スコアを導き出し、アプリケーションの初期の位置を特定します。では、何をどう改善できるのか、具体的に見ていきましょう。

このシリーズの他のブログ:

ソフトウェアパフォーマンス [Web]パートI

Angularアプリケーションのパフォーマンスを向上させる方法

この記事では、私がまとめたサンプルAngularアプリケーションを使用します。この記事の執筆時点では、アプリケーションは次の機能とライブラリを使用しています。

  • Angular 16
  • Ignite UI for Angular 16
  • RxJS 7
  • PWA (Angular service worker)
  • Server-side rendering (express server)
  • Angular localization

Angular Build

開発環境でアプリケーションを実行しているときは、すべてがうまく実行されているように見えますが、初期の灯台スコアはあまり高くありません。

 Lighthouse score with development environment run

低得点のセクションを改善するための提案を見ると、問題がどこから来ているのかがわかります 最初の大きな問題は、クライアントに転送されるリソース(JavaScript、スタイル、静的リソース)のサイズです。 

Angularアプリのパフォーマンスを向上させる機会

T彼の問題は、開発用ではなく、Angularアプリケーションの製品ビルドを実行することで簡単に解決できます。デプロイする前に、常に製品構成でビルドしてください。これにより、警告が解決され、サイズが小さくなります。JavaScriptについてそしてCSSの.レッツ 見て下さいangular.json私たちのルートにあるファイルあるngular リポジトリを使用して、プロダクションビルドの違いを確認します。 

"configurations": {
  "production": {
    "budgets": [
      {
        "type": "initial",
        "maximumWarning": "2mb",
        "maximumError": "5mb"
      },
      {
        "type": "anyComponentStyle",
        "maximumWarning": "10kb"
      }
    ],
    "fileReplacements": [
      {
        "replace": "projects/common/src/environments/environment.ts",
        "with": "projects/common/src/environments/environment.prod.ts"
      }
    ],
    "localize": true,
    "optimization": true,
    "outputHashing": "all",
    "sourceMap": false,
    "namedChunks": false,
    "extractLicenses": true,
    "vendorChunk": false,
    "buildOptimizer": true,
    "serviceWorker": true,
    "i18nMissingTranslation": "error",
    "ngswConfigPath": "projects/bellumgens/src/ngsw-config.json"
  },
  "bg": {
    "localize": [
      "bg"
    ]
  }
}

ここにはかなり多くの構成がありますしかし この場合最も重要なのは"optimization": trueのものだ。本番環境でアプリケーションを実行すると、ロード時間のパフォーマンス面でスコアの差が顕著になります。 

開発環境でのプロダクションビルドのLighthouseスコア

商談リストをもう一度見ると、提案の数ははるかに少なくなっています テキスト圧縮についてにリストされている最大の機会は、未使用のJavaScriptと静的リソースのキャッシュです。

パフォーマンス改善の残された機会

Angular Pre-Rendering and Server-Side Rendering 

Angularはシングル ページ アプリケーション (SPA) フレームワークです。既定では、アプリのライフサイクルは、クライアントからの要求に応じて、アプリケーションをホストするサーバーが、必要なすべてのスクリプトとスタイルの参照を含む HTML ファイルを提供するようになっています。ただし、本文の内容は空です。スクリプトとスタイルが要求され、提供されると、アプリケーションはブートストラップされ、特定のアプリケーションの JavaScript ロジックに基づいてコンテンツが設定されます。Angularは、最初の HTML ドキュメントで実際のコンテンツを提供することで、このライフサイクルを改善するための 2 つのメカニズムを提供します。これを行うには、ドキュメントを提供する前に、アプリケーションの JavaScript ロジックを実行する必要があります。それを行う方法:

  • ビルド時(プリレンダリング)–ほとんどが静的コンテンツを含むページの場合。
  • または、サーバー上のランタイム (サーバー側レンダリング) で、リクエストごとに最新のコンテンツを配信する必要がある、より動的なコンテンツを含むページの場合。

Angularサンプル アプリではサーバー側レンダリングを有効にし、Express エンジンを使用してテキスト圧縮と静的リソース キャッシングを有効にしています。これは、Express Server のロジックに以下を追加することで実現します。

export const app = (lang: string) => {
  // server scaffolded by [ng add @nguniversal/express-engine]
...
  // enable compression [npm install compression]
  const compression = require('compression');
  server.use(compression());
...
  // Serve static files from /browser with 1y caching
  server.get('*.*', express.static(distFolder, {
    maxAge: '1y'
  }));
...
}

サーバー側のレンダリングでアプリを提供し、lighthouse テストを再度実行します。初期負荷はさらに改善され、最初の満足のいくペイントは1秒未満になり、速度指数は1.2秒に短縮されました。

Lighthouse のスコアとAngularサーバーサイドレンダリング

Angular最適化のための残された機会は、未使用のJavaScriptとCSSを減らすことです。

パフォーマンス改善のための残された機会

これらに対処するには、アプリケーションのリファクタリングを行う必要があります。

Angular Lazy-Loading 

未使用のJavaScriptを減らすための最善のアプローチは、遅延ロードされたルートを作成することです。これにより、トップレベルのモジュールに不要なコンポーネントがAngularフレームワークに通知され、JavaScript がモジュールに分割され、要求されたルートがロードされたときにのみロジックがロードされます。

このブログで使用しているAngular例のアプリでは、ホーム ルートの一部ではないigx-gridなどの大きなコンポーネントを利用しています。このコンポーネントを使用するルートを別のモジュールに分割しています。このように、そのコンポーネントを使用するルートが読み込まれた後にのみ、そのコンポーネントが読み込まれます。モジュールを分離すると、ルートは次のようになります。

export const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'register', component: RegistrationComponent },
  { path: 'unauthorized', redirectTo: 'unauthorized/', pathMatch: 'full' },
  { path: 'unauthorized/:message', component: UnauthorizedComponent },
  { path: 'emailconfirm', component: EmailconfirmComponent },
  { path: 'strategies', loadChildren: () => import('./strategies/strategies.module').then(m => m.StrategiesModule) },
  { path: 'emailconfirm/:error', component: EmailconfirmComponent },
  { path: 'players', loadChildren: () => import('./player-section/player.module').then(m => m.PlayerModule) },
  { path: 'team', loadChildren: () => import('./team-section/team.module').then(m => m.TeamModule) },
  { path: 'notifications', loadChildren: () => import('./notifications/notifications.module').then(m => m.NotificationsModule) },
  { path: 'search/teams/:query', component: TeamResultsComponent },
  { path: 'search/players/:query', component: PlayerResultsComponent },
  { path: '**', component: HomeComponent }
];

Theteam.moduleは私が使っているグリッドを読み込むものなので、そのコードはこんな感じです:

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    // ...
    IgxGridModule,
    // ...
    TeamComponent,
    // ...
  ]
})
export class TeamModule { }

ビルドを見ると、これは最初の分割の結果です。

Angularアプリを遅延読み込みモジュールに分割する

Angularアプリケーションのパフォーマンスを向上させるためにもう1つ必要なことは、CSSのサイズを使用されるスタイルに制限することです。私はIgnite UI for AngularをUIライブラリとして使用しており、コンポーネントテーマのカスタマイズと最適化に関する優れたハウツー記事があります。

Optimizing Images 

Angular最適化のもう1つの側面は、画像の最適化です。Lighthouse Checkは、タイプやサイズごとに最適でない画像を使用しているかどうかを教えてくれます。ロードする画像が、それらが入るコンテナよりも大きくないこと、および最適なエンコーディングであることを確認してください。私は今、画像に.webp形式を使用しています。品質は少し低下しますが、それでも、アプリケーションは最高忠実度の画像を必要としません。

画像は、読み込まれた後にレイアウトがシフトします。したがって、画像に幅と高さの属性を設定して、画像を読み込む前にブラウザーが寸法を認識できるようにすることをお勧めします。画像にアスペクト比の設定(幅と高さ)がない場合、Lighthouseから警告が表示されます。これにより、レイアウトのシフトが減少するか、完全になくなります。

NgOptimizedImage to Enforce Image Best Practices 

Angular、画像のベストプラクティスを強制し、画像読み込みを最適化する指令を公開します。NgOptimizedImageという名前で、かなり使いやすいです。必要なのはCommonModuleもしまだNgModuleベースのAngularアプリケーション中ならインポートするか、使いたいコンポーネントにインポートNgOptimizedImageだけです。次に、画像ソース属性を設定するために usesrcではなく、代わりにngSrcinthes. を使います。

<img ngSrc="/assets/wallpapers/strat-editor.webp" width="600" height="347" class="preview-image" alt="Strategy Editor" />

最後に、各画像の読み込み優先度をさらに指定し、重要でないすべての画像を遅延読み込みするようにアプリに指示できます。width属性とheight属性を削除すると、アプリを実行すると次のようになります。

 NgOptimizedImage enforcing best practices

以上です。

まとめ...

Angularアプリケーションのパフォーマンスを向上させるには、さまざまな条件下でアプリが効率的かつ確実に動作するように、継続的な監視、最適化、ベスト プラクティスが必要になる場合があります。しかし、最終的には、これが究極のUXを提供し、ユーザーを引き付けて維持し、競争力を維持し、ビジネスの成功を達成する方法です。

Ignite UI for Angular

デモを予約