.NET MAUI+Vue.js应用Azure部署数据加载过慢求助
数据加载耗时过长的优化方案
我开发了基于.NET MAUI的移动端应用和Vue.js的Web端应用,两者均对接C#编写的API,数据库(SSMS)与API都部署在Azure平台。当前获取数据进行展示时耗时过长(约2-3分钟),求优化方案,相关代码如下:
Vue.js 前端代码
async fetchActivities() { try { const response = await fetch('/api/v1/Activities/all'); if (!response.ok) { throw new Error(`Network response was not ok, status: ${response.status}`); } // 省略后续处理逻辑 } catch (error) { console.error(error); } }
.NET MAUI 客户端代码
httpclient.BaseAddress = new Uri(AppSettings.UrlApi); httpclient.Timeout = TimeSpan.FromMinutes(2); string oauthToken = await SecureStorage.Default.GetAsync(AppSettings.AuthToken); httpclient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", oauthToken); int loginUserId = Convert.ToInt32(await SecureStorage.Default.GetAsync(AppSettings.UserId)); var requestUri = "api/v1/Activities/all"; var response = await httpclient.GetAsync(requestUri); var content = await response.Content.ReadAsStringAsync();
API 后端代码
Controller 部分
//[Authorize] [ApiController] [Route("api/v1/[controller]")] public class ActivitiesController : ControllerBase { private readonly IActivitiesRepository _activitiesRepository; private readonly IMessagesRepository _messagesRepository; private readonly IUsersRepository _usersRepository; private readonly IMapper _mapper; private readonly IImagesRepository _imagesRepository; public ActivitiesController(IActivitiesRepository activitiesRepository, IMapper mapper, IUsersRepository usersRepository, IMessagesRepository messagesRepository, IImagesRepository imagesRepository) { _activitiesRepository = activitiesRepository; _usersRepository = usersRepository; _mapper = mapper; _messagesRepository = messagesRepository; _imagesRepository = imagesRepository; } [HttpGet("{id}")] public async Task<ActionResult<ActivitiesEntity>> GetActivitiesbyIdAsync(int id) { ActivitiesEntity activitiesEntity = await _activitiesRepository.FindByIdAsync(id); return Ok(activitiesEntity); } [HttpGet] [Route("all")] public async Task<ActionResult<IEnumerable<ActivitiesModel>>> GetActivities() { IEnumerable<ActivitiesEntity>? activities = await _activitiesRepository.FindAllIncludingAsync(x => x.Images); var response = _mapper.Map<IEnumerable<ActivitiesModel>>(activities); return Ok(response); } }
Repository 通用方法
public virtual async Task<IEnumerable<TEntity>> FindAllIncludingAsync(params Expression<Func<TEntity, object>>[] includeProperties) { IQueryable<TEntity> query = _entities.AsNoTracking(); foreach (var includeProperty in includeProperties) { query = query.Include(includeProperty); } return await query.ToListAsync(); }
具体优化建议
1. 数据库层优化
- 添加索引:检查
Activities表的主键、常用查询字段,以及Images表中关联Activities的外键字段,添加非聚集索引,提升关联查询速度。 - 分页查询:如果
Activities数据量较大,API端新增分页参数(page、pageSize),修改Repository方法实现分页:
前端请求时传递分页参数,实现分段加载数据。public async Task<IEnumerable<TEntity>> FindAllIncludingPagedAsync(int page, int pageSize, params Expression<Func<TEntity, object>>[] includeProperties) { IQueryable<TEntity> query = _entities.AsNoTracking(); foreach (var includeProperty in includeProperties) { query = query.Include(includeProperty); } return await query.Skip((page - 1) * pageSize).Take(pageSize).ToListAsync(); } - 减少不必要关联:如果前端不需要展示所有
Images数据,可移除Include(x => x.Images),改为按需加载(比如点击活动详情时再请求对应图片)。
2. API层优化
- 投影查询减少数据传输:直接通过
Select返回前端需要的字段,避免序列化整个实体,减少数据包大小:[HttpGet("all")] public async Task<ActionResult<IEnumerable<ActivitiesModel>>> GetActivities() { var activities = await _activitiesRepository.FindAllIncludingAsync(x => x.Images) .Select(a => new ActivitiesModel { Id = a.Id, Title = a.Title, // 只映射前端需要的属性,省略不必要字段 Images = a.Images.Select(img => new ImageModel { Id = img.Id, ThumbnailUrl = img.ThumbnailUrl }) }) .ToListAsync(); return Ok(activities); } - 启用响应压缩:在API项目中配置Gzip或Brotli压缩,减少网络传输的数据量。
- 监控性能瓶颈:通过Azure Application Insights跟踪API请求的耗时,明确是数据库查询慢还是网络传输慢。
3. 客户端优化
- 缩短超时时间:将HttpClient的超时时间调整为更合理的值(比如30秒),避免无意义的长时间等待。
- 数据缓存:前端将获取到的活动数据缓存到
localStorage(Web端)或SecureStorage/内存(移动端)中,短时间内重复请求直接读取缓存。 - 优化网络环境:确认Azure API和数据库的部署区域是否与目标用户区域接近,选择就近区域部署可降低网络延迟。
内容的提问来源于stack exchange,提问作者Chris Curt
相关产品推荐
相关产品推荐

