febobo / web-interview

语音打卡社群维护的前端面试题库,包含不限于Vue面试题,React面试题,JS面试题,HTTP面试题,工程化面试题,CSS面试题,算法面试题,大厂面试题,高频面试题
https://vue3js.cn/interview
10.34k stars 1.63k forks source link

面试官:说说你对SPA(单页应用)的理解? #3

Open febobo opened 3 years ago

febobo commented 3 years ago

一、什么是SPA

SPA(single-page application),翻译过来就是单页应用SPA是一种网络应用程序或网站的模型,它通过动态重写当前页面来与用户交互,这种方法避免了页面之间切换打断用户体验在单页应用中,所有必要的代码(HTMLJavaScriptCSS)都通过单个页面的加载而检索,或者根据需要(通常是为响应用户操作)动态装载适当的资源并添加到页面页面在任何时间点都不会重新加载,也不会将控制转移到其他页面举个例子来讲就是一个杯子,早上装的牛奶,中午装的是开水,晚上装的是茶,我们发现,变的始终是杯子里的内容,而杯子始终是那个杯子结构如下图

我们熟知的JS框架如react,vue,angular,ember都属于SPA

二、SPA和MPA的区别

上面大家已经对单页面有所了解了,下面来讲讲多页应用MPA(MultiPage-page application),翻译过来就是多页应用在MPA中,每个页面都是一个主页面,都是独立的当我们在访问另一个页面的时候,都需要重新加载htmlcssjs文件,公共文件则根据需求按需加载如下图

单页应用与多页应用的区别

单页面应用(SPA) 多页面应用(MPA)
组成 一个主页面和多个页面片段 多个主页面
刷新方式 局部刷新 整页刷新
url模式 哈希模式 历史模式
SEO搜索引擎优化 难实现,可使用SSR方式改善 容易实现
数据传递 容易 通过url、cookie、localStorage等传递
页面切换 速度快,用户体验良好 切换加载资源,速度慢,用户体验差
维护成本 相对容易 相对复杂

单页应用优缺点

优点:

缺点:

三、实现一个SPA

原理

  1. 监听地址栏中hash变化驱动界面变化
  2. 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 apiapi 提供了丰富的 router 相关属性先了解一个几个相关的api

// 定义 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

下面给出基于VueSPA如何实现SEO的三种方式

  1. SSR服务端渲染

将组件或页面通过服务器生成html,再返回给浏览器,如nuxt.js

  1. 静态化

目前主流的静态化主要有两种:(1)一种是通过程序将动态页面抓取并保存为静态页面,这样的页面的实际存在于服务器的硬盘中(2)另外一种是通过WEB服务器的 URL Rewrite的方式,它的原理是通过web服务器内部模块按一定规则将外部的URL请求转化为内部的文件地址,一句话来说就是把外部请求的静态地址转化为实际的动态页面地址,而静态页面实际是不存在的。这两种方法都达到了实现URL静态化的效果

  1. 使用Phantomjs针对爬虫处理

原理是通过Nginx配置,判断访问来源是否为爬虫,如果是则搜索引擎的爬虫请求会转发到一个node server,再通过PhantomJS来解析完整的HTML,返回给爬虫。下面是大致流程图

参考文献

hhhpw commented 3 years ago

单页应用与多页应用的区别 md文档格式有问题。

jukrb0x commented 3 years ago

文中 markdown 表格语法存在错误导致没有正常渲染。

单页面应用(SPA) 多页面应用(MPA)
组成 一个主页面和多个页面片段 多个主页面
刷新方式 局部刷新 整页刷新
url模式 哈希模式 历史模式
SEO搜索引擎优化 难实现,可使用SSR方式改善 容易实现
数据传递 容易 通过url、cookie、localStorage等传递
页面切换 速度快,用户体验良好 切换加载资源,速度慢,用户体验差
维护成本 相对容易 相对复杂
ike-yu-byte commented 2 years ago

写的模拟单页面应用的路由貌似是那么回事,实则漏洞百出,能不能写一个能跑的通的代码?

guo897654050 commented 2 years ago

写的模拟单页面应用的路由貌似是那么回事,实则漏洞百出,能不能写一个能跑的通的代码?

https://github.com/guo897654050/simle-vue-router

festina-lente-z commented 1 year ago
单页应用与多页应用的区别 单页面应用(SPA) 多页面应用(MPA)
组成 一个主页面和多个页面片段 多个主页面
刷新方式 局部刷新 整页刷新
url模式 哈希模式 历史模式
SEO搜索引擎优化 难实现,可使用SSR方式改善 容易实现
数据传递 容易 通过url、cookie、localStorage等传递
页面切换 速度快,用户体验良好 切换加载资源,速度慢,用户体验差
维护成本 相对容易 相对复杂
fwqaaq commented 1 year ago

写的模拟单页面应用的路由貌似是那么回事,实则漏洞百出,能不能写一个能跑的通的代码?

https://github.com/fwqaaq/fwqaaq.github.io/blob/dev/public/JavaScript/index.js

原生写的

longhaolh commented 7 months ago
  1. 用户体验(User Experience) SPA能够提供流畅的用户体验,因为它减少了页面的重新加载。在SPA中,用户的大部分操作都会即时反馈,没有传统多页面应用(MPA)中的刷新等待时间。
  2. 前后端分离(Separation of Concerns) 在SPA中,通常会有一个明显的前后端分离。前端单独处理用户界面和用户交互,而后端通过API提供数据。这种模式方便了前后端团队的独立工作和开发,也使得应用更易于扩展。
  3. 数据交互(Data Interaction) 单页应用通常会使用AJAX或现代的Fetch API与服务端通信,这使得只有数据而不是整个页面需要在客户端和服务器间传输,减少了带宽的使用并提升了速度。
  4. 路由管理(Routing) 在SPA中,虽然只有一个物理页面,但是依然可以模拟出多页面导航的体验。这是通过前端路由来实现的,当URL发生变化时,前端路由会渲染对应的视图,而不是从服务器加载新页面。
  5. 性能优化(Performance Optimization) SPA需要特别注意到首屏加载性能,因为初始加载可能需要加载更多资源。使用代码分割(code splitting)、懒加载(lazy loading)等技术可以提升SPA的性能。
  6. 状态管理(State Management) 在复杂的SPA中,管理应用中的各种状态(用户输入、服务器响应等)可能会挑战。解决方案如Vuex、Redux等状态管理库能够帮助开发者以一种可预测的方式管理状态。
  7. SEO问题(Search Engine Optimization) 传统的SPA对搜索引擎优化不友好,因为内容是动态加载的,搜索引擎可能无法索引到全部内容。但是这可以通过服务器端渲染(SSR)或静态渲染(Static Generation),比如Next.js和Nuxt.js这类框架来解决。