前端性能优化措施
- 处理重复请求
- 思路:利用一个对象来记录正在进行的请求,当有新请求时,先检查该请求是否已存在。如果存在,取消当前请求并使用已有的请求结果。
- 关键代码片段:
// 创建一个对象来存储请求
const pendingRequests = {};
// 创建axios实例
import axios from 'axios';
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: 5000
});
// 添加请求拦截器
service.interceptors.request.use(config => {
const requestKey = `${config.method}:${config.url}`;
if (pendingRequests[requestKey]) {
// 取消重复请求
pendingRequests[requestKey].cancel('重复请求被取消');
}
// 创建取消令牌
const CancelToken = axios.CancelToken;
config.cancelToken = new CancelToken(c => {
pendingRequests[requestKey] = { cancel: c };
});
return config;
}, error => {
return Promise.reject(error);
});
// 添加响应拦截器
service.interceptors.response.use(response => {
const requestKey = `${response.config.method}:${response.config.url}`;
if (pendingRequests[requestKey]) {
delete pendingRequests[requestKey];
}
return response;
}, error => {
const requestKey = `${error.config.method}:${error.config.url}`;
if (pendingRequests[requestKey]) {
delete pendingRequests[requestKey];
}
if (axios.isCancel(error)) {
console.log('重复请求被取消:', error.message);
} else {
return Promise.reject(error);
}
});
- 请求合并
- 思路:在某些情况下,可以将多个小请求合并为一个大请求,减少网络请求次数。例如,对于一些数据获取请求,如果这些数据的接口逻辑允许,可以通过一次请求获取多个数据片段。
- 关键代码片段:假设后端有一个接口
/api/mergedata
可以同时获取用户信息和订单信息
// 原来可能是两个请求
// const userInfo = axios.get('/api/userinfo');
// const orderInfo = axios.get('/api/orderinfo');
// 合并为一个请求
axios.get('/api/mergedata').then(response => {
const userInfo = response.data.userInfo;
const orderInfo = response.data.orderInfo;
// 处理数据
});
- 设置合理的缓存策略
- 思路:对于不经常变化的数据,可以在前端设置缓存。当请求数据时,先检查缓存中是否有该数据,如果有则直接使用缓存数据,否则再发起网络请求。
- 关键代码片段:
const cache = {};
async function getData() {
if (cache['dataKey']) {
return cache['dataKey'];
}
const response = await axios.get('/api/data');
cache['dataKey'] = response.data;
return response.data;
}
安全角度措施
- 防止XSS攻击
- 思路:在接收后端返回的数据后,对数据进行严格的过滤和转义,避免恶意脚本注入。
- 关键代码片段:使用
DOMPurify
库来清理HTML字符串
npm install dompurify
import DOMPurify from 'dompurify';
service.interceptors.response.use(response => {
if (typeof response.data ==='string') {
response.data = DOMPurify.sanitize(response.data);
}
return response;
}, error => {
return Promise.reject(error);
});
- 防止CSRF攻击
- 思路:在每次请求时,带上CSRF令牌。一般后端会在用户登录时生成一个CSRF令牌,并通过Cookie或者其他方式传递给前端。前端在每次请求时,将该令牌添加到请求头或者请求参数中。
- 关键代码片段:假设后端将CSRF令牌放在Cookie中,使用
js - cookie
库获取Cookie
npm install js - cookie
import Cookies from 'js - cookie';
// 添加请求拦截器
service.interceptors.request.use(config => {
const csrfToken = Cookies.get('X - CSRF - Token');
if (csrfToken) {
config.headers['X - CSRF - Token'] = csrfToken;
}
return config;
}, error => {
return Promise.reject(error);
});