上月面试海康威视的一道面试题。
单页应用,即常说的SPA,Single Page Application,从名称上就可以看出它最大的特点,就是单页面,即只有一个页面;相对的就是多页面,即MPA,Multi-Page Application。
在多页面的情况下,我们在切换不同页面时,需要向服务器发送多次请求来获取不同页面内容,在获取到内容后,整个浏览器视口需要被重新渲染,而等待服务器的响应需要一定的时间,这个时间受网络状况影响很大,如果网络出现波动,就需要长时间地等待响应,页面也会处于空白的状态,有时用户也不知道是网速慢还是请求内容过多,没有给用户一个反馈。
SPA就相对上述MPA的的缺点有一些优势:
- 单页面切换内容时,利用了前端路由技术,在视觉上切换页面的过程中,不需要向服务器发起请求,也就不用等待响应结果,使得交互体验更流畅;
- 得益于前端路由技术和ajax技术,在切换页面内容的过程中,只需要局部刷新页面,大大提升了交互效率;
- 前端可以有更多空间提升用户体验,比如用户等待页面加载的过程中,可以设计一些交互,比如loading或者进度条,向用户反馈加载状态;
- 可以承担部分的数据处理工作,减轻服务器压力;
- 总体来说就是,快速渲染、及时反馈;
- 另外还可以模拟近似客户端应用的体验,应用体积却小得多,对内存偏小的手机较友好,同时也可以减少跨平台开发的成本。
虽然SPA有诸多优点,但也存在一些明显缺点:
- 由于承担起了页面切换的工作,即增加了前端路由功能,首先前端代码量就不可避免的增加,这往往就会导致前端项目打包体积变大,影响应用首次加载的用户体验,可能会出现白屏
- 不利于SEO(搜索引擎优化),因为网络爬虫更擅长静态资源的抓取和分析,而单页应用中大部分内容都是根据路由动态生成的,或者根据ajax获取的
- 在模拟客户端应用的时候,会相对而言耗费更多的网络资源,比如客户端的静态资源(图片)就在本地,而前端需要这些资源时需要另外去请求
针对上述缺点的一些解决方案:
- 在包体积过大的情况下
首先是尽可能压缩资源,其次可以采取拆分的技术,比如在webpack中普通的构建会把样式代码也插入js文件中,可以使用插件把样式代码输出到一个单独的文件中;再比如构建代码时将不同模块输出到不同文件,运用懒加载,使得首次加载时只加载首屏部分的内容,而不是将整个应用的内容都请求过来,这虽然会引起像前面所说的MPA同样的问题,切换路由时要向服务器发起请求,但是前端可以设计适当的交互,使得用户在等待的过程中有更好的体验;当然如果项目实在过于庞大,可以考虑将项目进行拆分,运用微前端之类的技术。 - 针对SEO的优化,可以使用预渲染,使构建生成的HMTL文件包含所需的网站信息;或者使用SSR服务端渲染,在用户请求时将动态生成的完整的HTML返回给客户端浏览器,这还可以加快首屏加载速度,但这会牺牲一部分交互体验
- 针对模拟客户端应用时需要另外请求静态资源,这难以避免,可以尽量去压缩资源体积以加快响应速度;或者利用CDN,以加速请求
当然很多时候并没有完美的解决方案,只有更适用的场景。
偏展示性的网站,比如公司官网,因为主要向用户展示公司信息,需要用户等待的操作较少,更推荐使用SSR,也利于SEO,利于搜索引擎收录;而用户后台这类,大多是需要登录操作的,信息往往是不公开的,也就不需要收录,所以不需要SEO的优化,就可以放心的使用客户端渲染;移动端因为存在网速限制,对包体积过大的情况比较敏感,所以有必要做好处理。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。