MST
星途 面试题库

面试题:Angular性能优化之虚拟滚动与服务端渲染

在大数据量展示场景下,如何通过Angular的虚拟滚动技术(如@angular/cdk/scrolling中的VirtualFor)提高性能?同时,阐述Angular服务端渲染(SSR)的工作原理和优势,在一个已有Angular项目中,怎样逐步引入SSR以提升整体性能?请结合具体代码示例说明。
10.6万 热度难度
前端开发Angular

知识考点

AI 面试

面试题答案

一键面试

通过Angular虚拟滚动技术提高大数据量展示性能

  1. 使用@angular/cdk/scrolling中的VirtualFor
    • 安装@angular/cdk:如果项目中未安装,通过npm install @angular/cdk进行安装。
    • 在组件模板中使用VirtualFor。例如,假设我们有一个大数据列表,数据为items数组:
<cdk - virtual - for #cdkVirtualFor [items]="items" let - item>
  <div>{{item}}</div>
</cdk - virtual - for>
  • 在组件类中定义items数组:
import { Component } from '@angular/core';

@Component({
  selector: 'app - big - data - list',
  templateUrl: './big - data - list.component.html',
  styleUrls: ['./big - data - list.component.css']
})
export class BigDataListComponent {
  items: string[] = [];
  constructor() {
    // 模拟大数据,生成10000个数据
    for (let i = 0; i < 10000; i++) {
      this.items.push(`Item ${i}`);
    }
  }
}
  • VirtualFor的原理是只渲染视口(viewport)内的项目,当用户滚动时,动态替换渲染的项目。这样避免了一次性渲染大量DOM元素,从而显著提高性能。

Angular服务端渲染(SSR)的工作原理和优势

  1. 工作原理
    • 服务器渲染阶段:当客户端请求一个启用SSR的Angular应用时,服务器会在服务器端执行Angular应用的启动过程。它会解析路由,根据请求的URL渲染出完整的HTML页面。服务器会创建Angular应用的实例,填充数据(如果需要从后端API获取数据,可以在服务器端进行调用),然后将渲染后的HTML返回给客户端。
    • 客户端激活阶段:客户端收到服务器返回的HTML页面后,Angular会检查页面上的静态内容,并将其与客户端的JavaScript代码进行“连接”(hydration)。这意味着客户端的JavaScript代码会重新接管应用,使应用可以进行交互,例如处理用户事件等。
  2. 优势
    • 更好的SEO:搜索引擎爬虫通常不会执行JavaScript代码。通过SSR,服务器返回的是已经渲染好的HTML,搜索引擎可以直接抓取到页面的内容,提高网站在搜索引擎中的排名。
    • 更快的首屏加载:由于服务器返回的是渲染好的HTML,用户不需要等待客户端JavaScript完全加载和执行就能看到页面内容,特别是在网络条件较差或设备性能较低的情况下,能显著提升用户体验。

在已有Angular项目中逐步引入SSR以提升整体性能

  1. 安装依赖
    • 运行npm install @angular - universal/express - engine @angular - universal/common express@angular - universal/express - engine用于将Angular应用集成到Express服务器中,@angular - universal/common包含一些通用的SSR工具,express是服务器框架。
  2. 创建服务器文件
    • 在项目根目录下创建server.ts文件。示例代码如下:
import { ngExpressEngine } from '@angular - universal/express - engine';
import { enableProdMode } from '@angular/core';
import { Express } from 'express';
import * as express from 'express';
import { join } from 'path';

// 生产模式下启用优化
enableProdMode();

// Express服务器实例
const app: Express = express();
const distFolder = join(process.cwd(), 'dist/<your - project - name>/browser');
const indexHtml = existsSync(join(distFolder, 'index.original.html'))? 'index.original.html' : 'index.html';

// 使用ngExpressEngine渲染Angular应用
app.engine('html', ngExpressEngine({
  bootstrap: () => import('./dist/<your - project - name>/server/main').then(m => m.AppServerModule)
}));

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

// 所有请求都渲染Angular应用
app.get('*.*', express.static(distFolder, { maxAge: '1y' }));
app.get('*', (req, res) => {
  res.render(indexHtml, { req, res });
});

// 启动服务器
const port = process.env.PORT || 4000;
app.listen(port, () => {
  console.log(`Node server listening on http://localhost:${port}`);
});
  1. 修改angular.json文件
    • architect下添加server部分:
"server": {
  "builder": "@angular - universal/express - engine:browser",
  "outputPath": "dist/<your - project - name>/server",
  "main": "./src/server.ts",
  "tsConfig": "./tsconfig.server.json"
}
  • architect.build中添加browserTarget指向server
"browserTarget": "<your - project - name>:server"
  1. 更新tsconfig.server.json
    • 确保tsconfig.server.json中的compilerOptions配置正确,例如:
{
  "extends": "./tsconfig.app.json",
  "compilerOptions": {
    "outDir": "../dist/<your - project - name>/server",
    "module": "commonjs",
    "types": ["node"]
  },
  "exclude": ["test.ts", "**/*.spec.ts"]
}
  1. 构建和运行
    • 运行ng build --configuration=productionng run <your - project - name>:server:production分别构建客户端和服务器端代码。
    • 运行node dist/<your - project - name>/server/main.js启动服务器,此时应用就启用了SSR。

逐步引入SSR时,可以先在开发环境中进行测试,确保应用在服务器渲染下正常工作,然后逐步在生产环境中部署。在引入过程中,可能需要处理一些与服务器环境相关的问题,如API调用的处理(可能需要在服务器端进行API代理等)。