前言
随着 web 技术的发展,越来越多的 web 应用选择了采用 SPA (Single Page Application) 的架构模式。SPA 应用通常是通过 AJAX 对后端 API 发起请求并获取数据,然后通过 JavaScript 动态更新渲染页面。然而,SPA 应用中的数据加载往往会带来一些问题,比如卡顿、加载速度过慢等。本文将会介绍一些改进 SPA 应用数据加载方式的技巧,帮助我们更好地优化前端用户体验。
问题分析
首先,我们需要分析 SPA 应用中数据加载过慢的原因。可能的原因有以下几个:
请求过多:SPA 应用通常是通过 API 请求获取数据,并将数据渲染到页面上。如果一个页面中需要请求过多的 API,就会导致页面加载过慢。
数据缓存不当:由于 SPA 应用通常是单页面与多个接口交互,如果没有考虑到数据的缓存,每次进入页面都需要重新获取数据,浪费无谓的流量。
数据加载过程中缺乏提示:SPA 应用中如果没有给用户明示数据正在加载的提示,用户会感到页面卡顿、无反应,从而影响用户体验。
改进策略
合并/缓存请求
SPA 应用发生加载慢的原因之一是请求过多,但不是所有请求都是必要的。我们可以通过合并或缓存请求,达到减少请求数目的目的。
合并请求:如果一个页面上需要请求多个 API 接口,那么我们可以将这些请求合并成一个请求发送给后端,可以用 gulp、webpack 等自动化打包工具实现。后端用一个 API 接口返回多个数据结构即可。
缓存数据:对于一些不经常变动的数据,我们可以将其缓存至本地,比如通过 localStorage 或是 sessionStorage 进行缓存。这样,下次请求该数据时我们可以先从缓存中获取数据,而不是重新发生请求。
数据加载提示
在 SPA 应用中,特别是异步请求数据时需要给用户一个加载提示,防止用户产生卡顿无反应的误解以及凸显数据加载的进度,这里我们可以用顶部进度条,像 npm 安装时的进度条一样,在数据加载的过程中逐渐加载及展示。
虚拟滚动
虚拟化滚动是提高大数据展示性能的一种技术。实现原理大致为:当用户滚动到一定位置时,只渲染这个位置前后数个元素,对于其他元素进行回收和复用,从而减少了浏览器渲染的工作量。我们可以使用类似 vue-virtual-scroller 或 react-window 等库来实现虚拟化滚动。这样可以实现大数据量展示的同时保证良好的性能。
示例代码
1.合并请求
CURL 示例:
curl -X POST -H "Content-Type: application/json" -d '{ "api1": "/path/to/api1", "api2": "/path/to/api2" }' https://www.sample.com/api/group
Server 示例:
const app = require('express')(); const bodyParser = require('body-parser'); app.use(bodyParser.json()); app.post('/api/group', (req, res) => { let api1Data = fetch(req.body.api1); let api2Data = fetch(req.body.api2); Promise.all([api1Data, api2Data]).then(([data1, data2]) => { res.send({data1, data2}); }).catch(error => { res.status(500).send(error); }); });
2.缓存数据
使用方式:
function getApiData(apiUrl) { let storageKey = `api-data-${apiUrl}`; let storage = JSON.parse(localStorage.getItem(storageKey)); if (storage && (+new Date() - storage.timestamp > 3600*24*1000)) { // 超时 localStorage.removeItem(storageKey); storage = null; } if (storage) { return Promise.resolve(storage.data); } return fetch(apiUrl).then(response => { let result = response.json(); localStorage.setItem(storageKey, JSON.stringify({ data: result, timestamp: +new Date() })); return result; }); }
3. 数据加载提示
使用 nprogress.js 库提示进度提示:
HTML:
<!-- CDN 引入 nprogress.js 资源文件 --> ... <link href="https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.js"></script> ...
JS:
import NProgress from 'nprogress'; // Ajax 请求前加入如下代码 NProgress.start(); // Ajax 请求结束时加入如下代码 NProgress.done();
4. 虚拟滚动
使用 react-window 库:
import { FixedSizeList } from 'react-window'; function VirtualList(props) { const { items, itemWidth, itemHeight } = props; function renderRow(props) { const { index, style } = props; return ( <div style={style}>items[index]</div> ); } return ( <FixedSizeList height={400} itemCount={items.length} itemSize={itemHeight} width={300} > {renderRow} </FixedSizeList> ); }
结论
通过实践和经验总结,我们可以发现这几种技巧非常适合改进 SPA 应用中的数据加载方式,其中涉及到的技术覆盖了请求合并、数据缓存、数据加载提示和虚拟滚动。尤其是在大数据量展示优化时,虚拟滚动技术的应用效果更为明显,能有效地提高前端性能,进一步提高产品竞争力。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65b7090dadd4f0e0fffa3c87