RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 924837
Accepted
Даниил Соловьев
Даниил Соловьев
Asked:2020-12-24 18:55:49 +0000 UTC2020-12-24 18:55:49 +0000 UTC 2020-12-24 18:55:49 +0000 UTC

有什么方法可以加快 Angular2+ ssr 的速度吗?

  • 772

大家好。一般来说,我用 Angular 7 编写。我附加了 Universal,所有程序集都已配置并且可以正常工作。当然,在ssr下做生产的时候解决所有冲突对我来说是一件悲哀的事……项目里有相当多的插件……googlemap、swiper、paperjs、textmask、perfectscroll、tweenmax……好吧,总的来说,它们已经足够了。当我开始在网络中查找生产版本提供给我的数量时,我的指标是 domContentLoaded 1.7s Load 2.2s。我想知道如果我完全删除所有页面并只留下主页并在其上滑动(之前此页面上有 paper.js + 2 个画布)会发生什么... domContentLoaded 1.5s 加载 1.9s。

dist 文件夹结构

距离
  /浏览器
  /服务器
  服务器.js

文件大小已显着减少,假设 dist/server/main.js 为 900kb ?删除所有内容后变成200kb。但这并没有给出任何结果,虽然我爬进去了,但我看到(当它重达 900kb 时)一切都在那里,一切都在项目中:)。这里又出现了一个问题,但是否有可能根据路由请求一个库?然后不知何故,事实证明有lazyModules,它们根据路由加载,但所有库本身都是一次加载的......

请告诉我。该指标通常取决于什么以及我如何影响它。当然,我对 Anular Universal Starter 进行了干净构建,并且在第二次重新启动 domContentLoaded 0.4s 后指示器变为

angular2
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    overthesanity
    2020-12-24T19:22:49Z2020-12-24T19:22:49Z

    Angular 中 SSR 的性能取决于许多因素。例如,从您在服务器上使用的内容,如果@nguniversal/express-engine是,请立即将其丢弃。该方法renderModuleFactory返回,它非常Promise适合使用,所以我建议你切换到这个框架,或者更好的是,它是一个没有框架的服务器,通过一个包原生地做所有事情,也可以将它用于静态。Promisekoahttpnginx

    如果您有很多第三方插件,那么您需要将这些插件分块到不同的文件中,而不是将它们塞进一个包中,分块是指动态导入:

    // Плохо
    import 'paper';
    
    // Хорошо
    import('paper').then(() => {
    });
    

    任何使用插件的工作都必须在 Angular 区域之外完成,服务器上的区域 ( zone-node) 也会影响性能,任何第三方插件的工作都必须包含在runOutsideAngular:

    class Component implements AfterViewInit {
        constructor(private zone: NgZone) {}
    
        public ngAfterViewInit(): void {
            this.zone.runOutsideAngular(() => {
                import('swiper').then((Swiper) => {
                    new Swiper('.some-class');
                });
            });
        }
    }
    

    然后使用缓存和解析器,解析器(定义器)是允许您在组件初始化之前在路由生命周期的某个阶段加载数据的服务。用于缓存使用TransferState。例如,我们在数据库某处有事件(会议、集会等),我们需要下载 1 次并缓存它,以免在客户端多次加载:

    import { Injectable, Inject, PLATFORM_ID } from '@angular/core';
    import { Resolve } from '@angular/router';
    import { isPlatformServer } from '@angular/common';
    import { TransferState, makeStateKey } from '@angular/platform-browser';
    
    import { Observable } from 'rxjs';
    import { tap } from 'rxjs/operators';
    
    @Injectable()
    export class EventsResolver implements Resolve<Event[]> {
        constructor(
            @Inject(PLATFORM_ID) private platformId: Object,
            private state: TransferState,
            private eventsService: EventsService
        ) {}
    
        public resolve(): Observable<Event[]> | Event[] {
            const key = makeStateKey<Event[]>('events');
    
            if (isPlatformServer(this.platformId)) {
                return this.eventsService.getEvents().pipe(
                    tap((events) => this.state.set(key, events))
                );
            }
    
            return this.state.get(key, []);
        }
    }
    

    TransferState将创建一个script将innerHTML填充的元素JSON.stringify({ [key]: events })。需要将解析器添加到模块的提供程序中:

    @NgModule({
        imports: [EventsRouterModule],
        providers: [EventsResolver]
    })
    export class EventsModule {}
    

    resolve而且在type属性中Route:

    import { ModuleWithProviders } from '@angular/core';
    import { Routes, RouterModule } from '@angular/router';
    
    import { EventsComponent } from './events.component';
    
    import { EventsResolver } from './events.resolver';
    
    const routes: Routes = [{
        path: '',
        component: EventsComponent,
        resolve: {
            events: EventsResolver
        }
    }];
    
    export const EventsRouterModule: ModuleWithProviders<RouterModule> = RouterModule.forChild(routes);
    

    现在,感谢解析器,我们已经可以在构造函数中获取事件列表:

    class EventsComponent {
        constructor(route: ActivatedRoute) {
            console.log(route.snapshot.data.events);
        }
    }
    

    另外,不要忘记通过webpack. webpack 4在生产模式下将进行更多优化并删除未使用的代码。

    • 0

相关问题

  • 在独立的 Angular2 组件之间传递数据

  • Angular 2 EventEmitter 事件被调用但数据未更新

  • Angular2 应用程序缩小。加载时间优化

  • 如何摆脱错误“类型‘订阅者[]’上不存在属性‘数据’”?角度 2

  • 根据角色删除页面元素?

  • 如何将多个订阅者订阅到一个观察者

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5