面试题答案
一键面试HTTP请求发起优化
- 合并请求:将多个小请求合并为一个大请求,减少HTTP连接建立与销毁的开销。例如,在获取用户信息及其相关配置时,若原本需要分别请求用户基本信息接口、用户权限接口、用户偏好设置接口,可考虑设计一个综合接口一次性获取这些数据。
- 按需发起请求:在用户操作触发或页面真正需要数据时才发起请求,避免页面加载时无意义的请求。比如,对于一个表格展示页面,只有当用户点击“加载更多”按钮时,才发起获取更多数据的HTTP请求。
缓存策略设置
- 浏览器缓存:利用HTTP缓存头(如
Cache - Control
、Expires
等)来控制浏览器缓存。对于不经常变化的静态资源(如样式表、脚本、图片等),设置较长的缓存时间。例如,对于网站的logo图片,可设置Cache - Control: max - age = 31536000
(一年),告知浏览器在一年内如果再次请求该图片,直接从本地缓存获取。 - 应用级缓存:在Angular应用内部实现缓存机制。可以使用
RxJS
的shareReplay
操作符来缓存HTTP请求的结果。比如在获取商品列表数据时:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { shareReplay } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class ProductService {
private productList$: Observable<any>;
constructor(private http: HttpClient) {}
getProductList(): Observable<any> {
if (!this.productList$) {
this.productList$ = this.http.get('/api/products')
.pipe(
shareReplay(1)
);
}
return this.productList$;
}
}
这样,后续对getProductList
方法的调用会直接使用缓存的结果,避免重复请求。
3. 根据业务场景设计缓存:
- 实时性要求不高的场景:如新闻资讯列表,缓存时间可以设置相对较长,比如10 - 15分钟。在这段时间内,用户刷新页面直接从缓存获取数据,提高响应速度。
- 实时性要求高的场景:如股票价格,缓存时间应极短甚至不缓存,每次都从服务器获取最新数据。
请求队列管理
- 限制并发请求数量:使用
RxJS
的forkJoin
结合concatMap
等操作符来控制并发请求数量。例如,假设我们有一个需要同时请求多个API接口获取不同数据的场景,但为了避免网络资源过度占用,我们限制并发请求数量为3:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, forkJoin } from 'rxjs';
import { concatMap } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class DataService {
constructor(private http: HttpClient) {}
getData(): Observable<any[]> {
const requests = [
this.http.get('/api/data1'),
this.http.get('/api/data2'),
this.http.get('/api/data3'),
this.http.get('/api/data4'),
this.http.get('/api/data5')
];
const maxConcurrent = 3;
let results: any[] = [];
return requests.reduce((acc, req, i) => {
return acc.pipe(
concatMap(() => {
return req.pipe(
tap(result => results.push(result)),
map(() => results)
);
})
);
}, Observable.of(results));
}
}
- 优先级管理:对于不同的请求设置不同的优先级。比如,与用户登录状态相关的请求优先级高于一些广告数据请求。在请求队列中,优先处理高优先级的请求。
响应处理优化
- 数据处理优化:在接收到响应后,尽快处理数据,避免在主线程进行复杂且耗时的计算。例如,对于接收到的大量数据列表,可使用
Web Workers
在后台线程进行数据处理,如数据过滤、排序等操作,防止阻塞主线程导致页面卡顿。 - 响应缓存处理:如果使用了缓存机制,在接收到新的响应时,需要合理更新缓存。例如,当获取到新的商品信息时,要更新商品列表缓存,确保下次请求时返回最新且正确的数据。
可能遇到的性能瓶颈及解决方案
- 网络延迟:
- 解决方案:优化服务器端性能,如采用CDN(内容分发网络),将静态资源缓存到离用户更近的节点,减少数据传输距离,降低延迟。同时,在客户端可采用预加载技术,提前请求可能需要的数据,如在用户浏览当前页面时,提前请求下一个可能跳转页面所需的数据。
- 缓存不一致:
- 解决方案:在缓存更新时,采用合适的策略通知相关组件。例如,在服务端数据更新后,通过WebSocket推送消息给客户端,客户端接收到消息后,主动清除相关缓存并重新请求数据。或者在每次请求时,附带版本号等标识,服务器返回数据时也携带最新版本号,客户端对比版本号不一致时更新缓存。
- 请求队列堵塞:
- 解决方案:动态调整并发请求数量,根据网络状况和设备性能实时调整。例如,在网络较差时,降低并发请求数量,避免过多请求导致网络拥塞。同时,对于长时间处于等待状态的请求,给予一定的超时处理,及时释放资源并提示用户请求失败。