angular运行_在生产中运行Angular Universal的要点

angular运行

Toying around with Angular Universal (server-side rendering or SSR for short) with the latest projects at IMPACT-Developers taught us a lot of things. This article focuses mainly on Angular 8+, and has been tested with versions 8 through 10, but the techniques used should work for other versions as well.

IMPACT-Developers上的最新项目使Angular Universal(简称服务器端渲染或SSR )玩弄了很多事情。 本文主要关注Angular 8+,并已通过版本8至10进行了测试,但所使用的技术也应适用于其他版本。

首先,为什么要使用Angular Universal? (First things first: Why Angular Universal?)

All right, so you have come this far and figured out that you might benefit from Angular Universal, or maybe you are trying to figure out the same. In Angulars own words you should use SSR for three reasons:

好的,所以您已经走了很远,发现您可能会从Angular Universal中受益,或者您正试图找出相同的方法。 用Angulars的话来说,您应该使用SSR的原因有三个:

1. Facilitate web crawlers through search engine optimization (SEO)

1.通过搜索引擎优化(SEO)便利网络爬虫

2. Improve performance on mobile and low-powered devices

2.提高移动和低功耗设备的性能

3. Show the first page quickly with a first-contentful paint (FCP)

3.使用内容优先的涂料(FCP)快速显示首页

Those are three really great reasons. First of all, you want to make your SEO guys happy with pre-rendered metadata, and second, you want to simulate a fast first-contentful paint, which also works really well for those pesky slow smartphones on slow networks.

这是三个非常重要的原因。 首先,您想让SEO成员对预渲染的元数据感到满意,其次,您想模拟一种快速的,内容丰富的绘画,它对于慢速网络上那些讨厌的慢速智能手机也非常有效。

Another point, that we have learned, is that bootstrapping your app through the server allows you to share server variables with your app. This might be credentials, like the Application Insights key set as an environment variable in an Azure Web App, which you then do not have to commit to your code repository.

我们了解到的另一点是,通过服务器引导应用程序可以使您与应用程序共享服务器变量。 这可能是凭据,例如将Application Insights密钥设置为Azure Web App中的环境变量,然后您不必将其提交到代码存储库。

Angular Universal入门 (Getting started with Angular Universal)

The Angular team has published a pretty extensive guide on how to install Angular Universal. This was something not available in the early days of Angular Universal, when it was still a 3rd party tool. I am very pleased, that the Angular team is making an extraordinary effort to support Angular Universal.

Angular团队已发布了有关如何安装Angular Universal的详尽指南。 在Angular Universal的早期,它仍然是第三者工具,这是无法获得的。 我非常高兴,Angular团队正在做出巨大的努力来支持Angular Universal。

My article will lean itself up against that guide and provide information in addition to the guide in relation to real world use cases.

我的文章将使该指南更具针对性,并在有关实际使用案例的指南之外提供其他信息。

From this point on, I will assume that you have a working project with the base Angular Universal up and running. Make sure to test the full build of your project before proceeding, because by default Angular Universal will build a production bundle.

从这一点开始,我将假设您有一个正常的Angular Universal正常运行的项目。 请确保在继续之前测试项目的完整版本,因为默认情况下Angular Universal会生成产品包。

Hint: From Angular 9 you get a script in package.json called “dev:ssr”, which is eminent to test your build

提示 :从Angular 9中,您会在package.json中获得一个名为“ dev:ssr”的脚本,该脚本可用于测试构建

让我们喘口气,谈谈API /后端 (Let us take a breather and talk about the API/backend)

I want to make a special mention of the API/backend, while your Angular app of course has one of those, but what happens in an SSR build is that Node.js is used to render the app, and that also means that the built-in HttpModule is running on Node.

我想特别提及一下API /后端,虽然您的Angular应用程序当然有其中一种,但是在SSR构建中发生的事情是使用Node.js来呈现应用程序,这也意味着-in HttpModule在Node上运行。

Hint: If you have a fully qualified URL to your backend (with https:// and all that), then you do not have to change anything and may move on.

提示:如果您有一个到后端的完全合格的URL(带有https://等),那么您不必进行任何更改,并且可以继续进行。

If you, like me, have a relative URL to your api (/api for instance) you will soon discover, that none of your API calls are working.

如果像我一样,如果您有一个相对于您的api的相对URL(例如/api ),您很快就会发现,您的API调用均无效。

Many headaches were had over this problem, but it turns out to be a simple fix, and Angular has also introduced a solution in the aforementioned guide on Universal: You need to provide the http origin to the HttpModule, but only when running on the server before the browser takes over.

这个问题让很多人头疼,但是事实证明这是一个简单的解决方法,并且Angular在前述的Universal指南中还引入了一个解决方案:您需要为HttpModule 提供 HTTP起源,但仅当在服务器上运行时才需要在浏览器接管之前。

Simple as that you create an interceptor which intercepts all http requests and prepends the server URL to the URL property.

您只需创建一个拦截器即可拦截所有http请求,并将服务器URL附加到URL属性之前就很简单。

Universal Interceptor setup (author: Google)
通用拦截器设置(作者:Google)

Notice how the interceptor is only provided in the AppServerModule?

注意,拦截器仅在AppServerModule中提供吗?

All done, you should now have a production grade setup, that proxies backend requests through /api and makes a fast first-contentful paint.

完成所有操作后,您现在应该具有生产级别的设置,该代理可以通过/api代理后端请求,并进行快速的第一个满足要求的绘画。

保留服务器到浏览器的状态 (Preserve state from server to browser)

Moving back to the browser again. The TransferHttpCacheModule utilises Angular’s BrowserTransferStateModule and that module provides a service called TransferState, which you use to rehydrate the application once the browser module is bootstrapped.

再次移回浏览器。 TransferHttpCacheModule利用Angular的BrowserTransferStateModule,该模块提供了一个名为TransferState的服务,一旦启动了浏览器模块,就可以使用该服务为应用程序重新补充水分。

提示:缓存HTTP请求 (Tip: Caching HTTP requests)

The Angular team has seen fit to provide a small interceptor, that caches all http requests made on the server and uses that cache to rehydrate the application again once the browser takes over, so the browser does not have to make all the same requests over again.

Angular团队认为合适的方法是提供一个小型拦截器,该拦截器可缓存服务器上发出的所有http请求,并在浏览器接管后使用该缓存再次为应用程序补水,因此浏览器不必再次发出相同的请求。

import { TransferHttpCacheModule } from '@nguniversal/common';@NgModule({
imports: [
BrowserModule.withServerTransition({ appId: 'my-app' }),
BrowserTransferStateModule,
TransferHttpCacheModule
]
})
export class AppModule {}

Simply import the module on the browser module (and remember to include the BrowserModule andBrowserTransferStateModule on the browser bundle as well as the ServerTransferStateModule on the server module.

只需在浏览器模块上导入模块(并记住在浏览器包中包括BrowserModule和BrowserTransferStateModule,以及服务器模块上的ServerTransferStateModule即可。

Angular will now cache all http requests on the server with the full URL as cache key and rehydrate again on the browser.

Angular现在将使用完整的URL作为缓存键在服​​务器上缓存所有http请求,并再次在浏览器上重新补水。

提示:几乎缓存所有内容 (Tip: Cache just about everything)

You can use this service to transfer just all sorts of stuff: lists of data, flags, and other cached resources from the server that was provided in server.ts.

您可以使用此服务来传输各种内容:server.ts中提供的服务器中的数据,标志和其他缓存资源的列表。

See example here for a list:

请参阅此处的示例以获取列表:

提示:生命周期 (Tip: Lifecycles)

We quickly learned that all components run their lifecycle again in the browser module, so make sure to consider what should be transferred from the server, and also please remember to use trackBy in your *ngFor loops, so elements are not rendered again.

我们很快了解到,所有组件都在浏览器模块中再次运行其生命周期,因此请确保考虑应从服务器传输的内容,并且还请记住在*ngFor循环中使用trackBy ,这样就不会再次呈现元素。

提示:isPlatformBrowser和Window (Tip: isPlatformBrowser and Window)

Check the Angular example from before on StackBlitz to see how we use isPlatformServer to only perform certain logic on the server module. There is also the equivalent isPlatformBrowser that you can use to run logic only on the browser. This is especially useful when having to use the Window object, which does not exist on the server in a Node.js context:

从之前的StackBlitz上查看Angular示例,以了解我们如何使用isPlatformServer仅在服务器模块上执行某些逻辑。 还有一个等效的isPlatformBrowser ,可用于仅在浏览器上运行逻辑。 当必须使用Window对象(在Node.js上下文中的服务器上不存在)时,这特别有用:

I cannot stress this point enough: Check all usages for window and encapsulate them in isPlatformBrowser !

我对此没有足够强调:检查window所有用法并将它们封装在isPlatformBrowser

结论 (Conclusion)

Angular Universal is a great tool, but it has a lot of pitfalls, especially considering that you are responsible for thinking “what is running on the server” and “what is running on the browser”.

Angular Universal是一个很棒的工具,但它有很多陷阱,尤其是考虑到您有责任思考“服务器上正在运行的内容”和“浏览器上正在运行的内容”的责任。

On a side note I found, that hosting an Angular Universal app in Azure requires quite a big server for a moderately visited site. In our case we had to run our web app (Docker container) on a P2v2 App Service Plan for the CPU and memory to stay stable.

从侧面看,我发现在Azure中托管Angular Universal应用程序需要相当大的服务器才能访问受中等程度访问的网站。 在我们的案例中,我们必须在P2v2 App Service Plan上运行Web应用程序(Docker容器),以使CPU和内存保持稳定。

We now serve a full HTML response to each visitor, which is SEO friendly and fast.

现在,我们为每个访问者提供完整HTML响应,这是SEO友好且快速的。

Is it worth the trouble? Yes!

值得麻烦吗? 是!

翻译自: https://medium.com/impact-developers/takeaways-from-running-angular-universal-in-production-175bb1b913a7

angular运行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值