一、什么是SPA
SPA(single-page application),翻译过来就是单页应用SPA
是一种网络应用程序或网站的模型,它通过动态重写当前页面来与用户交互,这种方法避免了页面之间切换打断用户体验在单页应用中,所有必要的代码(HTML
、JavaScript
和CSS
)都通过单个页面的加载而检索,或者根据需要(通常是为响应用户操作)动态装载适当的资源并添加到页面页面在任何时间点都不会重新加载。
以下是对SPA的一些主要特点和理解:
-
单页面加载: SPA只在用户访问应用程序时加载一次,之后的页面切换和内容更新通过Ajax或WebSockets来实现,避免了每次请求都重新加载整个页面。
-
前端路由: SPA使用前端路由来管理不同页面的状态和URL,而不是依赖服务器端路由。这允许用户在应用程序内部进行导航,同时保持页面URL的变化。
-
异步加载: SPA使用异步加载技术,通常是AJAX(Asynchronous JavaScript and XML)来从服务器获取数据,然后通过JavaScript更新页面的部分内容,而不是重新加载整个页面。
-
更流畅的用户体验: 由于只加载一次页面并通过前端路由进行导航,SPA通常能够提供更快的页面加载速度和更流畅的用户体验。
-
前后端分离: SPA通常采用前后端分离的架构,前端负责用户界面和用户交互,后端负责数据处理和业务逻辑。这使得团队能够更容易地独立开发和维护前后端代码。
-
框架和库的使用: SPA通常使用JavaScript框架或库来简化开发过程,如Angular、React、Vue等。这些工具提供了一些有用的功能,如组件化、状态管理等,使得开发更加高效。
二、SPA和MPA的区别
上面大家已经对单页面有所了解了,下面来讲讲多页应用MPA(MultiPage-page application),翻译过来就是多页应用在MPA
中,每个页面都是一个主页面,都是独立的当我们在访问另一个页面的时候,都需要重新加载html
、css
、js
文件。
单页应用(SPA)和多页应用(MPA)是两种不同的Web应用程序架构模式,它们在页面加载、用户体验、开发模式等方面存在一些显著的区别。
-
页面加载方式:
- SPA: 整个应用程序在用户第一次访问时加载一次,之后的页面切换和内容更新通过异步加载和前端路由来完成,无需每次页面切换都重新加载整个页面。
- MPA: 每次用户请求新的页面时,服务器都会发送一个完整的HTML页面作为响应,整个页面都被重新加载。
-
用户体验:
- SPA: 提供更流畅的用户体验,因为页面切换时只更新必要的部分,无需重新加载整个页面。
- MPA: 在页面切换时需要重新加载整个页面,可能导致相对较慢的加载时间和较差的用户体验。
-
前端路由:
- SPA: 使用前端路由进行页面导航,URL的变化不一定会触发页面的重新加载。
- MPA: 依赖服务器端路由,每次页面切换都需要向服务器请求新的HTML页面。
-
开发和维护:
- SPA: 通常采用前后端分离的架构,前端负责用户界面和用户交互,后端负责数据处理和业务逻辑。这使得开发和维护更容易独立进行。
- MPA: 前后端更紧密集成,可能需要更多的协调和沟通。
-
性能:
- SPA: 由于减少了服务器请求和页面加载次数,通常能够提供更快的页面加载速度。
- MPA: 页面切换时需要重新加载整个页面,可能导致相对较慢的性能。
-
框架和库的使用:
- SPA: 通常使用现代JavaScript框架或库,如Angular、React、Vue等,以简化开发过程。
- MPA: 可能使用传统的后端模板引擎(如JSP、Thymeleaf等)生成HTML页面。
三、实现一个SPA
原理
- 监听地址栏中
hash
变化驱动界面变化 - 用
pushsate
记录浏览器的历史,驱动界面发送变化
hash
模式
核心通过监听url
中的hash
来进行路由跳转
// 定义 Router
class Router {
constructor () {
this.routes = {}; // 存放路由path及callback
this.currentUrl = '';
// 监听路由change调用相对应的路由回调
window.addEventListener('load', this.refresh, false);
window.addEventListener('hashchange', this.refresh, false);
}
route(path, callback){
this.routes[path] = callback;
}
push(path) {
this.routes[path] && this.routes[path]()
}
}
// 使用 router
window.miniRouter = new Router();
miniRouter.route('/', () => console.log('page1'))
miniRouter.route('/page2', () => console.log('page2'))
miniRouter.push('/') // page1
miniRouter.push('/page2') // page2
history模式
history
模式核心借用 HTML5 history api
,api
提供了丰富的 router
相关属性先了解一个几个相关的api
history.pushState
浏览器历史纪录添加记录history.replaceState
修改浏览器历史纪录中当前纪录history.popState
当history
发生变化时触发
// 定义 Router
class Router {
constructor () {
this.routes = {};
this.listerPopState()
}
init(path) {
history.replaceState({path: path}, null, path);
this.routes[path] && this.routes[path]();
}
route(path, callback){
this.routes[path] = callback;
}
push(path) {
history.pushState({path: path}, null, path);
this.routes[path] && this.routes[path]();
}
listerPopState () {
window.addEventListener('popstate' , e => {
const path = e.state && e.state.path;
this.routers[path] && this.routers[path]()
})
}
}
// 使用 Router
window.miniRouter = new Router();
miniRouter.route('/', ()=> console.log('page1'))
miniRouter.route('/page2', ()=> console.log('page2'))
// 跳转
miniRouter.push('/page2') // page2
四、如何给SPA做SEO
1.预渲染(Prerendering)或服务器端渲染(Server-Side Rendering,SSR):这是将SPA的页面内容在服务器端渲染成静态HTML并提供给搜索引擎的一种方式。预渲染或SSR可以使搜索引擎能够直接看到页面的内容,从而更好地索引和排名你的网站。
服务器端渲染:将组件或页面通过服务器生成html,再返回给浏览器,如nuxt.js
静态化:
目前主流的静态化主要有两种:(1)一种是通过程序将动态页面抓取并保存为静态页面,这样的页面的实际存在于服务器的硬盘中(2)另外一种是通过WEB服务器的 URL Rewrite
的方式,它的原理是通过web服务器内部模块按一定规则将外部的URL请求转化为内部的文件地址,一句话来说就是把外部请求的静态地址转化为实际的动态页面地址,而静态页面实际是不存在的。这两种方法都达到了实现URL静态化的效果
使用Phantomjs
针对爬虫处理:原理是通过Nginx
配置,判断访问来源是否为爬虫,如果是则搜索引擎的爬虫请求会转发到一个node server
,再通过PhantomJS
来解析完整的HTML
,
2.使用合适的元数据(Metadata):确保每个页面都有适当的标题(title)、描述(description)、关键字(keywords)等元数据。这些元数据能够帮助搜索引擎理解页面的内容和意图,提高页面的可索引性。
3使用语义化的HTML:尽可能地使用语义化的HTML标记,这有助于搜索引擎更好地理解页面的结构和内容。例如,使用合适的标题标签(h1、h2、h3等)、段落标签(p)等。
4.配置Sitemap:创建并提交一个XML站点地图(Sitemap)给搜索引擎,其中包含你的网站的所有页面。这可以帮助搜索引擎更好地了解你的网站结构,并索引其中的页面。