3.4 单页面架构
3.4.1 单页面应用的定义
单页Web应用(single page web application,SPA)就是只有单个Web页面的应用,广泛应用了AJAX技术,通过页面局部刷新,而不是通过从远程服务器渲染页面使全部页面重写。当前主流JS框架都将SPA作为主要开发模式。与SPA相对的是多页面应用(MPA),典型代表是早期以JSP为模板的传统应用结构。
在SPA中,第一次加载时要加载绝大多数的静态资源,包括HTML、CSS、JS、Image等。页面加载完成后,SPA不会因为用户的操作而进行页面的重新加载或跳转。取而代之的是通过异步获取JSON数据局部刷新页面,利用JS动态地变换HTML的内容。SPA是前端面向接口(或面向API)编程的一个具体实现方式。
3.4.2 SPA的优缺点
(1)SPA的优点
■ 良好的交互体验,在SPA中用户不需要刷新页面,页面切换流畅,更加类似于本地应用,更具响应性。
■ 后端与前端解耦,后端不再负责页面渲染,后端吞吐能力提高。后端面向接口编程,一套后端可以面向不同终端。
(2)SPA的缺点
■ SEO难度较高,由于内容都在一个页面中动态替换显示,很多搜索引擎不能通过JS获取动态页面,SPA模式在SEO上有着天然的弱势。
■ 初次加载耗时多,SPA在初始加载页面时需要将大量JavaScript、CSS统一加载,会导致第一次访问时速度较慢。
■ 前进、后退功能缺失,由于AJAX请求不需要整页面的刷新动作,不会导致浏览器的URL地址变化,因此页面的变化无法记录到浏览器的历史记录堆栈中,从而使得用户无法通过浏览器的前进/后退按钮在不同状态页面间进行切换。
3.4.3 服务端渲染
为了解决SPA应用的SEO问题,单独提供一套静态页面是最好的解决办法,可以使用服务端渲染技术(Server Side Rendering,SSR),即由后端服务器将数据与模板结合,返回HTML的过程。服务端渲染包括非同构渲染和同构渲染。
(1)非同构渲染模式下前后端不是同一种技术栈,如后端采用经典的Spring MVC渲染输出。此种模式的主要问题是编写两套代码导致工作量较大。
(2)同构渲染是指前后端采用相同的技术栈进行渲染输出。当前各大前端框架基本都提供自身相对应的同构的服务端渲染技术。如在Vue的官网上有Vue SSR指南,见https://ssr.vuejs.org/zh/。其他主要的SSR技术包括PrerenderJS,NRect服务器渲染框架Next.js,Vue服务器渲染框架Nuxt.js。
采用PrerenderJS进行渲染,首先通过反向代理或者Prerender应用程序中间件判断访问端是否来自爬虫,针对爬虫程序会先使用Google-Chrome加载网站资源,并返回静态HTML给爬虫程序,若非爬虫程序可以直接回溯到源站。PrerenderJS不区分前端开发语言,能统一做预加载。对爬虫进行判断时,PrerenderJS提供在应用层判断或代理层判断等多种模式,但在应用层判断会加重应用层负担,推荐在代理层进行判断。
3.4.4 初始页面优化
为了解决SPA初始页面加载慢的问题,要尽可能地减少初始页面文件的大小,主要方法如下:
(1)懒加载,例如,结合webpack的代码分割功能,配合使用Vue的路由与组件懒加载办法。
(2)在业务上优先显示功能按钮,延时显示可见区域外内容。
(3)不阻塞预加载,使用<link rel="preload">属性进行预加载,将加载和执行分离开,不阻塞渲染和document的onload事件。
(4)内容压缩,启用gzip功能,在服务端压缩资源,浏览器解压缩。
(5)使用正确的图片文件格式,小图片使用Base64传输。
(6)精简JS与CSS代码。
(7)减少get请求数,合并文件。
(8)使用CDN加速。
3.4.5 地址堆栈管理
一般情况下缺失浏览器前进后退功能对用户影响不大,在业务上也可以通过“面包屑”进行替代。有特殊要求的,解决办法是用JS修改location.hash值(URL中“#”符号后的字符串),另外也可在页面中嵌入隐藏Iframe,浏览器可以对Iframe节点的src属性建立堆栈,通过建立页面状态与URL hash或Iframe的对应关系解决问题。