一、引言

大家在做网站开发的时候,肯定遇到过两个让人头疼的问题:SEO(搜索引擎优化)和首屏加载速度。SEO 做不好,搜索引擎就很难找到咱们的网站,流量自然就上不去;首屏加载慢,用户等得不耐烦,直接就走了。不过别担心,Angular 服务端渲染(SSR)就能帮咱们解决这些问题。下面咱们就一起来看看怎么用 Angular SSR 实战解决这些问题。

二、什么是 Angular 服务端渲染(SSR)

简单来说,Angular 服务端渲染就是在服务器端把 Angular 应用渲染成 HTML,然后把渲染好的 HTML 发送给浏览器。传统的 Angular 应用是在浏览器端进行渲染的,也就是先把代码下载到浏览器,然后再由浏览器来渲染页面。而 SSR 是在服务器端就把页面渲染好了,这样浏览器拿到的就是已经渲染好的 HTML,能大大提高首屏加载速度,也有利于 SEO。

举个例子,咱们有一个简单的 Angular 组件:

// Angular 技术栈
// app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: '<h1>{{ title }}</h1>',
})
export class AppComponent {
  title = 'Angular SSR Example';
}

在传统的客户端渲染中,浏览器要先下载 app.component.ts 以及相关的代码,然后再把 title 绑定到模板上,最后渲染出页面。而在 SSR 中,服务器会在发送 HTML 之前就把 title 绑定好,浏览器直接显示渲染好的 <h1>Angular SSR Example</h1>

三、应用场景

3.1 SEO 需求高的网站

像电商网站、新闻网站等,需要在搜索引擎上有好的排名,就特别适合用 Angular SSR。因为搜索引擎爬虫更容易抓取到服务器端渲染好的 HTML 内容,从而提高网站在搜索结果中的排名。

3.2 首屏加载速度要求高的网站

对于一些对用户体验要求很高的网站,比如游戏官网、在线教育平台等,首屏加载速度直接影响用户的留存率。使用 Angular SSR 可以让用户更快地看到页面内容,提高用户体验。

3.3 社交类网站

社交类网站通常需要实时展示大量的内容,使用 SSR 可以快速渲染页面,让用户更快地看到最新的动态。

四、技术优缺点

4.1 优点

4.1.1 更好的 SEO

搜索引擎爬虫可以直接抓取服务器端渲染好的 HTML 内容,提高网站的搜索排名。

4.1.2 更快的首屏加载速度

用户可以更快地看到页面内容,减少等待时间,提高用户体验。

4.1.3 支持不支持 JavaScript 的浏览器

有些浏览器可能不支持 JavaScript,使用 SSR 可以确保这些浏览器也能正常显示页面。

4.2 缺点

4.2.1 服务器压力大

服务器需要承担渲染页面的任务,会增加服务器的负载。

4.2.2 开发和维护成本高

SSR 需要在服务器端和客户端都进行开发和维护,增加了开发的复杂度。

4.2.3 部署复杂

需要配置服务器环境,部署过程相对复杂。

五、搭建 Angular SSR 项目

5.1 创建 Angular 项目

首先,我们要确保已经安装了 Angular CLI。如果没有安装,可以使用以下命令进行安装:

npm install -g @angular/cli

然后创建一个新的 Angular 项目:

ng new angular-ssr-example
cd angular-ssr-example

5.2 添加 SSR 支持

使用 Angular CLI 为项目添加 SSR 支持:

ng add @nguniversal/express-engine

这个命令会自动为项目添加必要的文件和配置,包括服务器端渲染的入口文件 server.tsmain.server.ts

5.3 配置服务器端渲染

打开 server.ts 文件,我们可以看到一些基本的配置:

// Angular 技术栈
// server.ts
import 'zone.js/dist/zone-node';

import { ngExpressEngine } from '@nguniversal/express-engine';
import * as express from 'express';
import { join } from 'path';

import { AppServerModule } from './src/main.server';
import { APP_BASE_HREF } from '@angular/common';
import { existsSync } from 'fs';

// The Express app is exported so that it can be used by serverless Functions.
export function app() {
  const server = express();
  const distFolder = join(process.cwd(), 'dist/angular-ssr-example/browser');
  const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';

  // Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
  server.engine('html', ngExpressEngine({
    bootstrap: AppServerModule,
  }));

  server.set('view engine', 'html');
  server.set('views', distFolder);

  // Example Express Rest API endpoints
  // server.get('/api/**', (req, res) => { });
  // Serve static files from /browser
  server.get('*.*', express.static(distFolder, {
    maxAge: '1y'
  }));

  // All regular routes use the Universal engine
  server.get('*', (req, res) => {
    res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
  });

  return server;
}

function run() {
  const port = process.env.PORT || 4000;

  // Start up the Node server
  const server = app();
  server.listen(port, () => {
    console.log(`Node Express server listening on http://localhost:${port}`);
  });
}

// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = mainModule && mainModule.filename || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
  run();
}

export * from './src/main.server';

这个文件配置了一个 Express 服务器,使用 ngExpressEngine 来渲染 Angular 应用。

5.4 构建和运行项目

使用以下命令构建项目:

npm run build:ssr

然后启动服务器:

npm run serve:ssr

现在,打开浏览器访问 http://localhost:4000,就可以看到渲染好的页面了。

六、注意事项

6.1 服务器性能

由于 SSR 需要服务器进行页面渲染,会增加服务器的负载。因此,需要确保服务器有足够的性能来处理请求。可以考虑使用云服务器或者进行服务器集群。

6.2 缓存策略

为了减少服务器的压力,可以使用缓存策略。比如,对一些不经常变化的页面进行缓存,当有新的请求时,直接返回缓存的内容。

6.3 错误处理

在服务器端渲染过程中,可能会出现各种错误。需要在代码中进行错误处理,确保服务器不会因为某个错误而崩溃。

七、总结

Angular 服务端渲染(SSR)是解决 SEO 和首屏加载问题的有效方法。通过在服务器端渲染页面,可以提高网站在搜索引擎中的排名,同时让用户更快地看到页面内容。不过,使用 SSR 也有一些缺点,比如服务器压力大、开发和维护成本高、部署复杂等。在实际应用中,需要根据项目的需求和特点来决定是否使用 Angular SSR。