| SPA | MPA | |
|---|---|---|
| 结构 | 一个主页面 + 许多模块的组件 | 许多完整的页面 |
| 体验 | 页面切换快,体验佳;当初次加载文件过多时,需要做相关的调优。 | 页面切换慢,网速慢的时候,体验尤其不好 |
| url模式 | http://www.base.com/page1.html http://www.base.com/page2.html |
http://www.base.com/index.html/page1 http://www.base.com/index.html/page2 |
| 资源文件 | 组件公用的资源只需要加载一次 | 每个页面都要自己加载公用的资源 |
| 适用场景 | 对体验度和流畅度有较高要求的应用,不利于 SEO(可借助 SSR 优化 SEO) | 适用于对 SEO 要求较高的应用 |
| 过渡动画 | 容易实现 | 很难实现 |
| 内容更新 | 相关组件的切换,即局部更新 | 整体 HTML 的切换,费钱(重复 HTTP 请求) |
| 路由模式 | 可以使用 hash ,也可以使用 history | 普通链接跳转 |
| 数据传递 | 因为单页面,使用全局变量就好 | cookie 、localStorage 等缓存方案,URL 参数,调用接口保存等 |
| 相关成本 | 前期开发成本较高,后期维护较为容易 | 前期开发成本低,后期维护就比较麻烦,因为可能一个功能需要改很多地方 |
单页面应用(SPA)
随着React Vue前端框架的兴起,出现了Vue-router,react-router-dom等前端路由管理库,利用他们构建出来的单页面应用,
1、单页面应用(SPA)的概念
single-page application是一种特殊的Web应用。它将所有的活动局限于一个Web页面中,仅在该Web页面初始化时加载相应的HTML、JavaScript、CSS。指只有一个主页面的应用,一开始只需加载一次 js,css 等相关资源。所有的内容都包含在主页面,对每一个功能模块组件化。单页应用跳转,就是切换相关组件,仅刷新局部资源。
2.原理
hash值
1.“#”代表网页中的一个位置。其右面的字符,就是该位置的标识符**
<a href="target">go target</a>......<div id="target">i am target place</div>
点击a链接,文档会滚动到id为target的div的可视区域上面去。hash除了这个功能还有另一一种含义:指导浏览器的行为但不上传到服务器。大家都知道,改变url中的任何一个字符都会导致浏览器重新请求服务器,除了#号后面那段字符之外。所以,简而言之我们可以这样理解:改变#后面的值不触发网页重载,但会记录到浏览器history中去。
2.HTTP请求不包括’#’
‘#’是用来指导浏览器动作的,对服务器端完全无用。所以,HTTP请求中不包括#。
3.改变#不触发网页重载
单单改变#后的部分,浏览器只会滚动到相应位置,不会重新加载网页。
4.改变#会改变浏览器的访问历史
每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用”后退”按钮,就可以回到上一个位置。
5.window.location.hash读取#值
window.location.hash这个属性可读可写。读取时,可以用来判断网页状态是否改变;写入时,则会在不重载网页的前提下,创造一条访问历史记录。
6.onhashchange事件
这是一个HTML 5新增的事件,当#值发生变化时,就会触发这个事件。
window.onhashchange = func;<body onhashchange="func();">window.addEventListener("hashchange", func, false);
对于不支持onhashchange的浏览器,可以用setInterval监控location.hash的变化
3、作用(好处)
1.良好的交互体验
单页应用的内容的改变不需要重新加载整个页面,获取数据也是通过Ajax异步获取,没有页面之间的切换,就不会出现“白屏现象”,也不会出现假死并有“闪烁”现象,页面显示流畅,web应用更具响应性和更令人着迷。
2.良好的前后端工作分离模式
后端不再负责模板渲染、输出页面工作,后端API通用化,即同一套后端程序代码,不用修改就可以用于Web界面、手机、平板等多种客户端。
3.减轻服务器压力
单页应用相对服务器压力小,服务器只用出数据就可以,不用管展示逻辑和页面合成,吞吐能力会提高几倍。
4、缺点
1.首屏加载慢
- 如果不对路由进行处理,在加载首页的时候,就会将所有组件全部加载,并向服务器请求数据,这必将拖慢加载速度;
- 通过查看Network,发现整个网站加载试讲长达10几秒,加载时间最长的就是js、css文件和媒体文件及图片
解决方案:
- Vue-router懒加载【react-rrouter】
Vue-router懒加载就是按需加载组件,只有当路由被访问时才会加载对应的组件,而不是在加载首页的时候就加载,项目越大,对首屏加载的速度提升得越明显。
- 使用CDN加速
在做项目时,我们会用到很多库,采用cdn加载可以加快加载速度。
- 异步加载组件
-
2.不利于SEO
seo 本质是一个服务器向另一个服务器发起请求,解析请求内容。但一般来说搜索引擎是不会去执行请求到的js的。也就是说,搜索引擎的基础爬虫的原理就是抓取url,然后获取html源代码并解析。 如果一个单页应用,html在服务器端还没有渲染部分数据数据,在浏览器才渲染出数据,即搜索引擎请求到的html是模型页面而不是最终数据的渲染页面。 这样就很不利于内容被搜索引擎搜索到。
解决方案: 服务端渲染
服务器合成完整的 html 文件再输出到浏览器
