繁体   English   中英

如何提高 Angular2 应用程序的加载性能?

[英]How can I improve load performance of Angular2 apps?

Angular2 应用程序加载缓慢,如何提高加载性能?

我使用 Angular2,带有 html5 的打字稿。

目前我的应用程序需要 4 秒才能加载。 我使用 Firebase 托管并使用 cloudflare。

我正在做的事情/信息:

  • 我压缩了图片。
  • 我缩小了 css
  • 我缩小了js。
  • 我在我的脚本上使用异步。
  • 我的脚本在我的 .
  • 脚本大约 700kb
  • 我使用谷歌速度测试并获得 65%
  • 我使用了我使用的库的缩小版本,例如引导程序等。
  • 使用 systemjs。
  • 这是我使用的种子应用程序: https : //github.com/mgechev/angular-seed

流程:

当应用程序加载时,它显示一个蓝屏(这是引导 css),然后 4 秒后应用程序加载并运行得非常快。 但是加载需要4秒。 systemjs 缩小到的 app.js 文件似乎正在减慢整个应用程序,并且没有足够快地显示视图。

这是我的网站速度测试: https : //www.webpagetest.org/result/161206_F5_N87/

这是我的网站:

https://thepoolcover.co.uk/

如果您需要有关我的应用程序的更多信息以及我可以做的任何其他事情,请告诉我。

单页应用程序在加载时通​​常需要更多时间,因为它一次加载所有必需的东西。

我也遇到了同样的问题,我的团队使用以下方法将我们的项目从 8 秒加载到 2 秒进行了优化。

  1. 延迟加载模块:延迟加载模块有助于减少启动时间。 通过延迟加载,我们的应用程序不需要一次加载所有内容,它只需要加载用户希望在应用程序首次加载时看到的内容。 延迟加载的模块只会在用户导航到他们的路线时加载。 Angular2 在其最终版本 RC5 中引入了模块。 请参阅下面的分步指南。

  2. Aot 编译:使用 AoT,浏览器会下载应用程序的预编译版本。 浏览器加载可执行代码,以便它可以立即呈现应用程序,而无需先编译应用程序。

    它减少了有效负载大小:如果应用程序已经编译,则无需下载 Angular 编译器。 编译器大约是 Angular 本身的一半,因此省略它会大大减少应用程序的有效负载。 有关更多信息,请参阅

  3. Webpack : Webpack 是一种流行的模块打包器,一种用于将应用程序源代码打包成方便的块并将该代码从服务器加载到浏览器中的工具。 您可以使用 webpack 配置您的 Angular 2 Web 应用程序(请参阅本指南)。

  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. 使用浏览器缓存:当您使用浏览器缓存时,您的网页文件将存储在浏览器缓存中。 对于重复访问者,您的页面加载速度会快得多,共享相同资源的其他页面也将如此。 有关更多信息https://varvy.com/pagespeed/leverage-browser-caching.html

  2. 最小化 app.component.ts 中的代码:最小化app.component.ts 中的代码,这些代码总是在应用加载或重新加载时运行。

  3. 在应用程序初始化时设置数据:如果您在项目或组件中多次使用相同的 api 调用,或者您依赖多个组件中的相同数据,您可以做的是将数据保存为对象而不是多次调用 api在应用程序初始化服务中。 该服务将在整个项目中充当单例,您无需调用 api 即可访问该数据。


逐步延迟加载模块

  1. 模块化结构:我们必须将我们的应用程序划分为单独的模块。 例如,一个应用程序可能有一个用户端和一个管理端,每个端都有自己不同的组件和路由,所以我们将这两个端分成模块 admin.module.ts 和 user.module.ts。

  2. 根模块:每个 Angular 应用程序都有一个根模块类。 按照惯例,它是一个名为 app.module.ts 的文件中名为 AppModule 的类,该模块将导入上述两个模块以及用于引导的 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. 嵌套模块:就像 app.module 每个模块都有自己的一组组件和路由。 随着您的项目变大,模块内部的模块嵌套是优化的最佳方式,因为我们可以在需要时延迟加载这些模块。

请注意

以上代码仅供说明,完整示例请参考https://angular-2-training-book.rangle.io/handout/modules/lazy-loading-module.html

“代码拆分”怎么样。

来自 Webpack 站点:

“对于大型 Web 应用程序,将所有代码放入一个文件中效率不高,特别是如果某些代码块仅在某些情况下才需要。Webpack 具有将代码库拆分为按需加载的“块”的功能。其他一些打包器将它们称为“层”、“汇总”或“片段”。此功能称为“代码拆分”。

链接在这里:

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

请注意,Angular CLI 使用 Webpack。

此外,请确保如果您的应用程序通过数据调用进行引导,则您不会阻止组件的渲染等待这些调用返回。 承诺,异步等。

如果不亲自操作整个代码库和后端,就很难诊断出您遇到的确切问题(正如其他人所建议的,问题可能根本不是角度问题)。

话虽如此,我强烈建议您开始使用angular-cli 它由 angular 团队设计,旨在通过易于使用的命令行界面完成您需要执行的所有操作。 所以我的答案是基于 angular-cli 的使用。

以下是为生产优化 ng2 项目可以执行的一般操作:

1) 提前 (AoT) 编译 - 捆绑/缩小/摇树

看,忘记配置一堆 gulp 任务来完成所有这些事情的头痛。 angular-cli 通过一个简单的步骤处理捆绑/缩小/摇树/AOT 编译:

ng build -prod -aot

这将在“dist”文件夹中生成以下 js 文件:

 inline.d41d8cd98f00b204e980.bundle.js vendor.d41d8cd98f00b204e980.bundle.js main.d41d8cd98f00b204e980.bundle.js styles.4cec2bc5d44c66b4929ab2bb9c4d8efa.bundle.css
您还将获得这些文件的 gzip 版本以进行更多优化:

 inline.d41d8cd98f00b204e980.bundle.js.gz vendor.d41d8cd98f00b204e980.bundle.js.gz main.d41d8cd98f00b204e980.bundle.js.gz

Angular 的 AOT 编译会自动对您的代码进行“摇树”并删除任何未使用的引用。 例如,你可能在你的项目中使用了 lodash,但你可能只使用了几个 lodash 函数; 摇树将修剪掉最终构建中不需要的 lodash 的所有未使用部分。 最重要的是,AOT 编译将预编译您所有的代码和视图,这意味着浏览器需要更少的时间来启动 ng2 应用程序。单击此处了解有关 angular 的 AOT 编译的更多信息。

2)延迟加载应用程序的部分如果您进一步将应用程序划分为不同的部分,则无需在应用程序首次加载时加载每个部分。 您可以为您的应用程序指定不同的模块,然后可以将这些模块(由 angular-cli aot 编译器)捆绑到不同的块中。 这里阅读以了解如何将您的项目组织成模块,您可以将这些模块编译成仅根据需要加载的夹头。 Angular-cli 将为您管理这些块的创建。

3) Angular Universal现在如果你真的想让你的加载时间非常快,那么你需要考虑实现Angular Universal ,这是你在服务器上编译你的初始视图时。 我没有使用 Angular Universal,因为我已经能够通过第 1 步和第 2 步实现快速加载。但它是 ng2 工具集中的一个令人兴奋的选项。 请记住,您不是在服务器上编译或运行 ng2 应用程序,而是编译服务器端的初始视图,因此用户很快就会收到 html 的震动,因此用户认为加载时间非常快(即使完全加载还是会落后一点)。 此步骤并不排除其他步骤的需要。 作为奖励,Angular Universal 还应该帮助 SEO。

4) 二次捆绑

如果我不使用延迟加载,我通常会继续并进一步捆绑从 AOT 编译生成的分发文件。 因此,我创建了一个main.bundle.js文件,用于连接 inline.js、vendor.js 和 main.js 文件。 为此,我使用了 gulp。

因为它的 SPA 和 angular 2 init 太慢了。 就是这样。 加上 RXjs、大量的 polifills 等。AOT 可以提供帮助,但很多 angular2 库不能使用它。 角度通用真的有帮助

使用以下命令构建您的 angular 应用程序以获得最大的优化优势。

ng build --prod --aot --optimization --build-optimizer --vendor-chunk --common-chunk --extract-licenses --extract-css --source-map=false

基本上,您将在 aot 模式下构建并使用带有一些优化的 treeshaking。

  • 优化:启用构建输出的优化。

  • vendor-chunk:使用仅包含供应商库的单独包。

  • common-chunk:使用包含跨多个包使用的代码的单独包。
  • extract-css:从全局样式中提取 css 到 css 文件而不是 js 文件。
  • build-optimizer:在使用 'aot' 选项时启用 @angular-devkit/build-optimizer 优化。
  • source-map=false:删除源映射也将减少包大小

尝试通过运行ng serve --sourcemap=false禁用源映射

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM