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