web-dev-qa-db-ja.com

Angular2アプリのロードパフォーマンスを改善するにはどうすればよいですか?

Angular2アプリの読み込みが遅いのですが、読み込み時のパフォーマンスを改善するにはどうすればよいですか?

Angular2、TypeScriptをhtml5で使用します。

現在、アプリの読み込みには4秒かかります。 Firebaseでホストし、cloudflareを使用します。

私がやっていること/ info:

  • 画像を圧縮しました。
  • CSSを縮小します
  • Jsを縮小します。
  • スクリプトで非同期を使用しています。
  • 私のスクリプトはにあります。
  • スクリプトは約700kbです
  • Googleスピードテストを使用して65%を取得しました
  • 使用しているライブラリの縮小版を使用しました。 bootstrapなど.
  • Systemjsを使用します。
  • これは、使用しているシードアプリです。 https://github.com/mgechev/angular-seed

フロー:

アプリが読み込まれると、ブルースクリーン(これはbootstrap css)を表示し、4秒後にアプリが読み込まれ、非常に高速に動作します。ただし、ロードには4秒かかります。 systemjsが縮小するapp.jsファイルは、アプリ全体の速度を低下させ、十分な速さでビューを表示していないようです。

これは私のウェブサイトの速度テストです:https://www.webpagetest.org/result/161206_F5_N87/

これは私のウェブサイトです:

https://thepoolcover.co.uk/

私のアプリや他にできることについてもっと情報が必要な場合はお知らせください。

51
AngularM

「コード分割」はどうですか。

Webpackサイトから:

「大きなWebアプリの場合、特に特定の状況下でのみコードのブロックが必要な場合、すべてのコードを単一のファイルに配置するのは効率的ではありません。Webpackには、バンドラーはそれらを「レイヤー」、「ロールアップ」、または「フラグメント」と呼びます。この機能は「コード分割」と呼ばれます。

ここにリンク:

https://webpack.github.io/docs/code-splitting.html

Angular CLIはWebpackを使用することに注意してください。

また、アプリがデータ呼び出しでブートストラップする場合、それらの呼び出しが戻るのを待っているコンポーネントのレンダリングを保留していないことを確認してください。約束、非同期など.

8
Tim Consolazio

単一ページのアプリケーションは、必要なものをすべて一度にロードするため、一般的にロードに時間がかかります。

私も同じ問題に直面していました。私のチームは、次の方法を使用して、8秒から2秒でロードするプロジェクトを最適化しました。

  1. モジュールの遅延読み込み:遅延読み込みモジュールは、起動時間の短縮に役立ちます。遅延読み込みでは、アプリケーションは一度にすべてを読み込む必要はなく、アプリが最初に読み込まれたときにユーザーが見たいものを読み込むだけで済みます。遅延ロードされるモジュールは、ユーザーがルートに移動したときにのみロードされます。 Angular2は、最終リリースRC5でモジュールを導入しました。 ステップバイステップガイドについては以下を参照してください。

  2. Aot Compilation:AoTでは、ブラウザはアプリケーションのプリコンパイル済みバージョンをダウンロードします。ブラウザは実行可能なコードをロードするため、最初にアプリをコンパイルするのを待たずに、すぐにアプリケーションをレンダリングできます。

    ペイロードサイズを削減します:アプリが既にコンパイルされている場合、Angularコンパイラをダウンロードする必要はありません。コンパイラーはAngularの約半分なので、省略するとアプリケーションのペイロードが大幅に削減されます。詳細については、 this を参照してください。

  3. Webpack:Webpackは、アプリケーションのソースコードを便利なチャンクにバンドルし、そのコードをサーバーからブラウザーにロードするためのツールである、人気のあるモジュールバンドラーです。 Angular 2 Webアプリケーションをwebpackで設定できます( このガイド を参照)。

  4. index.htmlからスクリプト、スタイルシートを削除します:index.htmlで不要なスクリプトとスタイルシートをすべて削除します。サービスを呼び出すことにより、これらのスクリプトをコンポーネント自体に動的にロードできます。

    そのコンポーネントのオンデマンドで任意のスクリプトをロードできるファイルscript.service.tsを作成します

\ script.service.ts

import { Injectable } from '@angular/core';
declare var document: any;

@Injectable()
export class Script {

  loadScript(path: string) {
    //load script
    return new Promise((resolve, reject) => {
      let script = document.createElement('script');
      script.type = 'text/javascript';
      script.src = path;
      if (script.readyState) {  //IE
        script.onreadystatechange = () => {
          if (script.readyState === "loaded" || script.readyState === "complete") {
            script.onreadystatechange = null;
            resolve({ loaded: true, status: 'Loaded' });
          }
        };
      } else {  //Others
          script.onload = () => {
            resolve({ loaded: true, status: 'Loaded' });
          };
      };
      script.onerror = (error: any) => resolve({ loaded: false, status: 'Loaded' });
      document.getElementsByTagName('head')[0].appendChild(script);
    });
  }
}

これは、スクリプトを動的に読み込むための単なるサンプルコードであり、必要に応じて自分でカスタマイズおよび最適化できます。スタイルシートの場合、styleUrlを使用してコンポーネントにロードする必要があります。

  1. ブラウザキャッシュを使用:ブラウザキャッシュを使用すると、Webページファイルがブラウザキャッシュに保存されます。あなたのページはリピート訪問者のためにはるかに速くロードされるので、同じリソースを共有する他のページもロードされます。詳細情報 https://varvy.com/pagespeed/leverage-browser-caching.html

  2. app.component.tsのコードを最小化する:app.component.tsに存在するコードを最小化します。これらのコードは、アプリのロードまたはリロード時に常に実行されます。

  3. アプリの初期化にデータを設定する:プロジェクトまたはコンポーネントで同じAPI呼び出しを複数回使用している場合、または複数のコンポーネントの同じデータに依存している場合、APIを複数回呼び出すのではなく、アプリの初期化時にサービス内のオブジェクトとしてデータを保存します。そのサービスはプロジェクト全体でシングルトンとして機能し、APIを呼び出さずにそのデータにアクセスできます。


ステップごとのモジュールの遅延読み込み

  1. モジュール構造:アプリを個別のモジュールに分割する必要があります。たとえば、アプリにはユーザー側と管理者側があり、それぞれに独自の異なるコンポーネントとルートがあるため、この2つの側をモジュールadmin.module.tsとuser.module.tsに分けます。

  2. ルートモジュール:すべてのAngularアプリにはルートモジュールクラスがあります。慣例により、app.module.tsという名前のファイルにあるAppModuleというクラスです。このモジュールは、上記の2つのモジュールとブートストラップ用のAppComponentをインポートします。必要に応じて複数のコンポーネントを宣言することもできます。 app.module.tsのサンプルコード:

\ app.module.ts

import { NgModule } from '@angular/core';
import { UserModule } from './user/user.module';
import { AdminModule } from './admin/admin.module';
import { AppComponent } from './app.component';
import { LoginComponent } from './login.component';

@NgModule({
  imports: [UserModule, AdminModule],
  declarations: [AppComponent, LoginComponent],
  bootstrap: [AppComponent]
})
export class AppModule { }
  1. ルート:これで、ルートで次のように指定できます

\ app.router.ts

import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { LoginComponent } from './login.component';

const routes: Routes = [
  { path: 'login', component: 'LoginComponent' }, //eager loaded
  { path: 'admin', loadChildren: './admin/admin.module#AdminModule' }, // Lazy loaded module
  { path: 'user', loadChildren: './user/user.module#UserModule' }  //lazy loaded module
];

これで、アプリケーションがロードされると、LoginComponentとAppComponentコードのみがロードされます。これらのモジュールは、/ adminまたは/ userルートにアクセスしたときにのみロードされます。したがって、ブラウザにロードするためのペイロードのサイズが小さくなり、高速ロードが実現します。

  1. Nesting Modules:app.moduleと同様に、すべてのモジュールには独自のコンポーネントとルートのセットがあります。プロジェクトが大きくなるにつれて、モジュール内のモジュールのネストは最適化する最適な方法です。必要なときにいつでもモジュールを遅延ロードできるからです。

ご注意ください

上記のコードは説明のためだけのものです。完全な例を参照してください https://angular-2-training-book.rangle.io/handout/modules/lazy-loading-module.html

111
Vikash Dahiya

コードベースとバックエンド全体に手を加えずに問題を正確に診断することは困難です(他の人が示唆しているように、問題はangularではないかもしれません)。

そうは言っても、 angular-cli を使い始めることを強くお勧めします。 angularチームが設計したのは、使いやすいコマンドラインインターフェイスで必要なすべてのことを実行するためです。したがって、私の答えは、angular-cliの使用に基づいています。

Ng2プロジェクトを本番用に最適化するためにできる一般的なことは次のとおりです。

1)Ahead of Time(AoT)Compilation-Bundling/Minification/Tree-shaking

これらのすべてを達成するために大量のgulpタスクを設定することの頭痛を忘れてください。 angle-cliは、1つの簡単なステップでバンドリング/縮小/ツリーシェーキング/ AOTコンパイルを処理します。

ng build -prod -aot

これにより、「dist」フォルダーに次のjsファイルが生成されます。

inline.d41d8cd98f00b204e980.bundle.js
vendor.d41d8cd98f00b204e980.bundle.js
main.d41d8cd98f00b204e980.bundle.js
styles.4cec2bc5d44c66b4929ab2bb9c4d8efa.bundle.css
inline.d41d8cd98f00b204e980.bundle.js.gz
vendor.d41d8cd98f00b204e980.bundle.js.gz
main.d41d8cd98f00b204e980.bundle.js.gz

AngularのAOTコンパイルは、コードに対して自動的に「ツリーシェーキング」を行い、未使用の参照を削除します。たとえば、プロジェクトでlodashを使用できますが、おそらく少数のlodash関数のみを使用します。ツリーを振ると、最終ビルドで不要なlodashの未使用部分がすべて削除されます。そして最も重要なことは、AOTコンパイルがすべてのコードとビューをプリコンパイルすることを意味します。つまり、ブラウザーがng2アプリを起動するのに必要な時間が短くなります。 ここをクリック アンギュラーのAOTコンパイルの詳細について。

2)アプリの遅延読み込み部分さらにアプリを別の部分に分割する場合、アプリを最初に読み込むときにすべてを読み込む必要はありません。 (angular-cli aotコンパイラーによって)さまざまなチャンクにバンドルできるアプリケーションのさまざまなモジュールを指定できます。 here を読んで、必要に応じてロードされるチャックにコンパイルできるモジュールにプロジェクトを編成する方法を学習してください。 Angular-cliは、これらのチャンクの作成を管理します。

3)Angular Universal本当にロード時間を非常に高速にしたい場合は、実装を検討する必要があります Angular Universal 。これは、サーバーで初期ビューをコンパイルするときです。手順1と2で高速なロード時間を達成できたため、Angular Universalを使用していませんが、ng2ツールセットのエキサイティングなオプションです。サーバーでng2アプリをコンパイルまたは実行せずに、初期ビューサーバーサイドをコンパイルして、ユーザーがhtmlの衝撃をすばやく受信するようにして、ユーザーが読み込み時間を非常に高速であると認識していることに注意してくださいまだ少し遅れます)。このステップは、他のステップの必要性を取り除くものではありません。ボーナスとして、Angular UniversalもSEOに役立つはずです。

4)二次バンドル

遅延読み込みを使用していない場合は、通常、AOTコンパイルから生成された配布ファイルをさらにバンドルします。したがって、inline.js、vendor.js、main.jsファイルを連結する1つのmain.bundle.jsファイルを作成します。これにはgulpを使用します。

6
brando

そのSPAとangular 2の初期化が遅すぎるためです。それでおしまい。さらに、RXjs、大量のポリフィルなど。AOTは役立ちますが、多くのangle2ライブラリはそれで動作しません。 angular Universal Realyは役立ちます

2
dimson d