1.webpack 怎么编译less和sass的
2.为什么要使用微前端
3.微前端使用场景
- 多个系统想合成一个大系统,保持交互的一致性,都保持SPA交互
- 多个团队开发的系统,想让用户感觉想一个系统
- 每一个子系统独立部署互不影响
- 跨框架Vue,React
腾讯云都没用,都是部署域名ng代理
4.cookie,sessionStorage ,locaStorage
5.前端的八股文
- HTML/CSS基础:包括HTML标签的使用、CSS样式的设置等基本内容。
- JavaScript基础:包括变量、数据类型、运算符、流程控制语句等JavaScript基础知识。
- DOM操作:了解DOM树结构、元素选取、属性操作、事件处理等相关知识。
- Ajax/异步请求:掌握Ajax技术,实现异步数据交互。
- 前端框架:例如Vue.js、React.js、Angular等主流前端框架的基本原理和使用方法。
- 响应式布局:利用CSS媒体查询等技术实现页面在不同设备上的自适应布局。
- 性能优化:了解前端性能优化的方法,如减少HTTP请求、压缩资源、懒加载等。
- 跨域问题:了解浏览器同源策略、跨域请求的方式和解决方法。
6.Vite比Webpack快主要是因为:
- Vite使用ES模块,无需复杂的打包过程。
- Vite按需编译,只编译需要的部分,减少冗余代码。
- Vite有高效的缓存机制,加快热更新速度。
- Vite插件系统更轻量级,处理文件更有效率。
预构建
7.VUE依赖收集过程
【前端高薪面试题】你是如何在Vue中进行依赖收集的?_哔哩哔哩_bilibili
-
每一个属性都有一个Dep,存放我们所依赖的watcher,当属性变化后通知自己对应的watcher去更新
-
默认在渲染的时候(获取这个响应式数据),此时就会触发属性收集依赖dep.depend()
-
当属性发生改变时除非watcher通过dep.notify ()
let dep = new Dep()
Object.defineProperty(data,key,{
get(){
dep.depend()//收集数据
}
set(){
dep.notify()//触发依赖更新数据
}
})
dep.depend()是get()里面的方法
dep.notify()是set()里面的方法
8.$nextTick()在那使用
dom渲染是异步
使用nextTick中的回调函数,在下一次DOM更新循环结束之后,执行回调
使用:用于获取更新后的DOM
vue中的数据跟新是异步的,使用nextTick方法可以保证用户定义的逻辑在更新之后执行
9.为什么使用虚拟DOM
直接操作真实dom,性能低
vnode就是 一个js对象,也可以理解为真实dom的抽象
也就是将component变成一个render函数在变成一个虚拟DOM
10.dfff算法原理
vue2:递归+双指针
- 判断是不是同一个元素,不是同一个元素直接替换
- 是同一个元素:比对属性=》比儿子,=====也就是取新的,都有儿子情况下=》双指针:头头,头尾,尾头比对=》对比查找以后继续复用
vue3:采用最长递增子序列,下面原理都一样
11.你对vue2和vue3响应式的理解
响应式:就是数据改变,视图也会改变
vue2:是通过Object.defineProperty(),但是只能劫持一个,数据多层次需要递归
vue3:采用Proxy,如层次数据,用户不使用就不会递归(懒递归)==》用户不使用,就不递归
defneReactive
12.use-immer
https://www.bilibili.com/video/BV1JB4y1s7kb/?spm_id_from=333.788&vd_source=08a6a0bf43adbb7912a115fee81c2025
npm install use-immer
import { useContext } from "react";
import { useImmerReducer } from "use-immer";
import { InfoContext } from "../MyContextPrevider";
const initialState = {
score: 0,
};
// user-immer 简化代码
const reducer = (state, action) => {
console.log(state, state.score, action);
switch (action.type) {
case "add":
// return { ...state, score: state.score + action.payload };
// user-immer 简化代码
state.score += action.payload;
break;
case "jian":
// return { ...state, score: state.score -action.payload };
// user-immer 简化代码
state.score -= action.payload;
break;
default:
// return state;
break;
}
};
export const ComponentB = () => {
const { age, setAge } = useContext(InfoContext);
// const [state, dispatch] = useReducer(reducer, initialState);
const [state, dispatch] = useImmerReducer(reducer, initialState);
return (
<>
{age}
<br />
<button
onClick={() => {
setAge((a) => a + 1);
}}
>
点击
</button>
<br />
{state.score}
<br />
<button onClick={() => dispatch({ type: "add", payload: 2 })}>
佳佳加急
</button>
<button onClick={() => dispatch({ type: "jian", payload: 2 })}>
佳佳加急
</button>
</>
);
};
12.react router 路由
useParams()获取动态的值
useLocation() 获取url的一些信息
useHref() 拿到路由
在当前路由里面渲染子页面
13.useMemo
组件缓存:消耗非常大的计算
PS:就是监听一个值,变了就进行计算,有点类似于Hooks 里面的useEffect() 里面的
useEffect(()=>{
console.log('监听某值')
},[某种])
用法:
const result = useMemo(()=>{
return 返回值
},[监听值])
14.React.memo
react 父组件改变重新渲染,子组件也跟着重新渲染,使用memo跳过子组件重新渲染
—自有props改变时候才会重新渲染
const Son = memo(() => {
console.log(111111);
return <div>22222222222</div>;
});
15.v-for 里面key
key是独一无二的便于,diff算法进行优化
vue2优先级:V-for >V-if
不要讲两个写在同一个元素上,带来性能的浪费(每次渲染都会先循环在进行判断)
16.v-show和v-if的区别
v-show
为该元素添加:display:none,dom依旧存在
v-if
将dom 元素整个添加或删除
编译过程:
v-show:由 false 变为 true 的时候不会触发组件的生命周期
v-if:由 false 变为 true 的时候,触发组件的 beforeCreate、create、beforeMount、mounted 钩子,由true 变为 false 的时候触发组件的 beforeDestory、destoryed
性能消耗:
v-if 有更高的切换消耗;
v-show 有更高的初始渲染消耗;
17.Vue里面的key
key是给每一个vnode的唯一id,也是diff的一种优化策略,可以根据key,更准确, 更快的找到对应的vnode节点
18.怪异盒模型和标准盒模型的区别
盒子模型:margin+padding+border+content
怪异盒模型:盒子宽度固定死的,add内容只会压缩content
19.BFC(块级格式化上下文)
方法:
- float:left
- overflow:hidden
- display:table
- display:inline-block
- 清除浮动触发 BFC
- positon:absolute
…等
20.解决跨域常用5中
1.jq的ajax自带解决跨域的方法(推荐JQuery项目中使用)
2.script标签解决跨域(远古Web项目中使用)
3.前端代理解决跨域(每一个框架的代理配置都不太一样)
Umi.js框架会有 config.ts / config.js 文件,文件中会有proxy字段、字段按图中配置方法。即可完成跨域
4.服务端代理(Nginx代理)
#如果监听到请求接口地址是 www.xxx.com/api/page ,nginx就向http://www.yyy.com:9999/api/page这个地址发送请求
server {
listen 80;
server_name www.xxx.com;
#判过滤出含有api的请求
location /api/ {
proxy_pass http://www.yyy.com:9999; #真实服务器的地址
}
}
5.后台(逻辑层)添加响应头解决
Access-Control-Allow-Origin响应头的意思是,安全同行的请求
总:
//1.jsonp,代表:jquery的$.ajax。(仅限JQuery项目使用)
//2.script标签解决跨域(远古web使用的方案,已不建议使用)
//3.前端代理
//4.nginx代理
//5.设置响应头(不建议使用,安全性不高,小练习可以用用,方便)
其实是三种跨域方式。
第一种和第二种是同一种解决方案,即 JSONP 跨域,第一种是对第二种方式的封装。
第三种和第四种也是同一种解决方案,称为服务器代理跨域。你所说的前端框架配置,就是通过 node 插件启动的服务器实现的代理,本质上跟第四种方案是同理的。
第五种是需要浏览器支持的,只有支持第二代 XMLHttpRequest 技术的浏览器才可使用,比如IE9以下浏览器就不支持,如果网站的访问群体需要考虑旧版浏览器用户,则不适合使用
21.bind,call,apply区别
bind
方法可以将参数绑定到函数,但不会立即执行函数。call
方法逐个传递参数,并立即执行函数。apply
方法通过数组传递参数,并立即执行函数。
22.后台管理系统中的权限管理是怎么实现的
登录:获取token,token存到Cookies里面,根据 token 再去拉取一个 user_info 的接口来获取用户的详细信息(如用户权限,用户名等等信息)
23.ES6新特性
- const,let,
- Promise解决了回调地域的问题
- import 、export 来实现导入、导出
- 结构赋值
- class 类
24.组件中的 data 为什么要定义成一个函数而不是一个对象
每个组件都是 Vue 的实例。组件共享 data 属性,当 data 的值是同一个引用类型的值时,改变其中一 个会影响其他
25.常见的盒子垂直居中的方法有哪些请举例
- margin:auto
- absolute+margin-top–盒子高度一般+margin-left–盒子宽度一般
- flex
- transform +absolute
26.cookie 、localstorage 、 sessionstrorage 之间有什么区别
大小:
- cookie数据根据不同浏览器限制,大小一般不能超过 4k
- sessionStorage 和 localStorage 虽然也有存储大小的限制,但比 cookie 大得多,可以达到 5M 或更大
有期时间:
- cookie在有限时间内一直有效
- sessionStorage 数据在当前浏览器窗口关闭后自动删除
- localStorage存储持久数据,浏览器关闭后数据不丢失除非主动删除数据
27.this指向
普通函数:window
定时器:window
箭头函数:上一级
构造函数:实例对象
class类:构造器
28.什么是递归,递归有哪些优点或缺点
递归:函数内部函数调用自己
优点:结构清晰、可读性强
缺点:效率低、调用栈可能会溢出,其实每一次函数调用会在内存栈中分配空间,而每个进程的栈的容 量是有限的,当调用的层次太多时,就会超出栈的容量,从而导致栈溢出
29.谈谈你平时都用了哪些方法进行性能优化
减少 http 请求次数、
打包压缩上线代码、
使用懒加载、
使用雪碧图、
动态渲染组件、
CDN 加载
gzip
30.数组去重
- new Set() + Array.form
- .filter()
- map()
- .reduce
- .indexOf
31.数组排序
- sort()
array.sort((a, b) => a - b)
- 冒泡排序
32.lodash,它有哪些常见的 API
Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库
- _.cloneDeep 深度拷贝
33.webpack
WebPack 是一个模块打包工具你可以使用 WebPack 管理你的模块依赖,并编绎输出模块们所需的静 态文件。它能够很好地管理、打包 Web 开发中所用到的 HTML、Javascript、CSS 以及各种静态文件(图 片、字体等),让开发过程更加高效。对于不同类型的资源,webpack 有对应的模块加载器
33.什么是set,map
ES6新的数据结构,用于存储一组唯一的值
set 是 es6 提供的一种新的数据结构,它类似于数组,但是成员的值都是唯一的
map 是 es6 提供的一种新的数据结构,它类似于对象,也是键值对的集合,但是键的范围不仅限于字符 串,各种类型的值都可以当做键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供 了“值—值”的对应,是一种更完善的 Hash 结构实现。如果你需要“键值对”的数据结构,Map 比 Object 更合适。
适用对象:
set:数组(去重,add()、
delete()、
has()和
clear())
map:对象(set()、
get()、
has()、
delete()和
clear())
34.常用的布局
flex布局:
(CSS3 中出现的) 优点:解决上面两个方法的不足,flex 布局比较完美。移动端基本用 flex 布局
网格布局(grid):
CSS3 中引入的布局,很好用。代码量简化了很多
浮动:
优点:兼容性好。 缺点:浮动会脱离标准文档流,因此要清除浮动。
栅格布局:
可以适用于多端设备
绝对定位:
优点:快捷。 缺点:导致子元素也脱离了标准文档流,可实用性差。
35.父向子、子向父、兄弟之间的传值的?
父子:
使用props,子组件声明对应属性
子父:
$emit
兄弟:
EventBus.$emit()
EventBus.$on()
// EventBus.js
import Vue from 'vue';
export const EventBus = new Vue();
// ParentComponent.vue
<template>
<button @click="sendData">Send Data</button>
</template>
<script>
import { EventBus } from './EventBus';
export default {
methods: {
sendData() {
const data = 'Hello from Parent';
EventBus.$emit('dataReceived', data);//声明
}
}
}
</script>
// ChildComponentA.vue
<template>
<div>Data from Parent: {{ data }}</div>
</template>
<script>
import { EventBus } from './EventBus';
export default {
data() {
return {
data: ''
};
},
created() {
EventBus.$on('dataReceived', (data) => {
this.data = data; //调用
});
}
}
</script>
// ChildComponentB.vue
<template>
<div>Data from Parent: {{ data }}</div>
</template>
<script>
import { EventBus } from './EventBus';
export default {
data() {
return {
data: ''
};
},
created() {
EventBus.$on('dataReceived', (data) => {
this.data = data;//调用
});
}
}
</script>
36.什么 vuex ,谈谈你对它的理解
- 首先 vuex 的出现是为了解决 web 组件化开发的过程中,各组件之间传值的复杂和混乱的问题
- 将我们在多个组件中需要共享的数据放到 store 中
- 要获取或格式化数据需要使用 getters
- 改变 store 中的数据,使用 mutation,但是只能包含同步的操作,在具体组件里面调用的方式 this.$store.commit(‘xxxx’)
- Action 也是改变 store 中的数据,不过是提交的 mutation,并且可以包含异步操作, 在组件中的调 用方式 this.$store.dispatch(‘xxx’) ; 在 actions 里面使用的 commit(‘调用 mutation’)
37.symbol
ES6 引入新的原始数据类型 Symbol,表示独一无二的值
38.promise 是什么?它有哪些作用?
Promise 是异步编程的一种解决方案
39.vue-cli 2.0 和 3.0 有什么区别
3.0 把配置 webpack 的文件隐藏了,如果需要配置它需要创建一个 vue.config.js 文件,3.0 是 2018.10 月 出来的
40.post 和 get 请求有哪些区别
GET:一般用于信息获取,使用 URL 传递参数,对所发送信息的数量也有限制,一般在 2000 个字符
POST:一般用于修改服务器上的资源,对所发送的信息没有限制
41.什么是同源策略?
所谓同源策略是浏览器的一种安全机制,来限制不同源的网站不能通信。同源就是域名、协议、端口一 致
端口,协议,域名
42.http 状态码分别代表什么意思?
1xx 表示 HTTP 请求已经接受,继续处理请求
2xx 表示 HTTP 请求已经处理完成(200)
3xx 表示把请求访 问的 URL 重定向到其他目录(304 资源没有发生变化,会重定向到本地资源)
4xx 表示客户端出现错误 (403 禁止访问、404 资源不存在)
5xx 表示服务端出现错误
43.token 是什么?(加密)
- token 也可以称做令牌,一般由 uid+time+sign(签名)+[固定参数] 组成
uid: 用户唯一身份标识
time: 当前时间的时间戳
sign: 签名, 使用 hash/encrypt 压缩成定长的十六进制字符串,以防止第三方恶意拼接
固定参数(可选): 将一些常用的固定参数加入到 token 中是为了避免重复查库
- token 在客户端一般存放于 localStorage,cookie,或 sessionStorage 中。在服务器一般存于数据 库中
- token 的认证流程
- token 可以抵抗 csrf,cookie+session 不行
44.js 的数据类型有哪些
基本:
- String
- number
- boolean
- null
- undefined
- symbol
直接存储在栈中的数据
复杂:
- 引用 :
-
- Object
- Array
- Function
- Date
- Map
- Set
- Symbol
- RegExp
- 特殊:
-
- BIgint
- Symbol
存储的是该对象在栈中引用,真实的数据存放在堆内存里
45.一个页面从输入 URL 到页面加载显示完成,这个过程中都发生了什么
01.浏览器查找域名对应的 IP 地址(DNS 查询:浏览器缓存->系统缓存->路由器缓存->ISP DNS 缓存->根 域名服务器)
02.浏览器向 Web 服务器发送一个 HTTP 请求(TCP 三次握手)
03.服务器 301 重定向(从 example.com 重定向到 www.example.com)
04.浏览器跟踪重定向地址,请求另一个带 www 的网址
05.服务器处理请求(通过路由读取资源)
06.服务器返回一个 HTTP 响应(报头中把 Content-type 设置为 ‘text/html’)
07.浏览器进 DOM 树构建
08.浏览器发送请求获取嵌在 HTML 中的资源(如图片、音频、视频、CSS、JS 等)
09.浏览器显示完成页面
10.浏览器发送异步请求
46.安全问题 :CSRF 和 XSS 攻击
CSRF ( Cross-site request forgery )
:跨站请求伪造。
47.CSRF 和 XSS 的区别
区别一:
- CSRF :需要用户先登录网站 A ,获取 cookie
- XSS :不需要登录。
区别二:(原理的区别)
- CSRF :是利用网站 A 本身的漏洞,去请求网站 A 的 api 。
- XSS :是向网站 A 注入 JS 代码,然后执行 JS 里的代码,篡改网站 A 的内容。
48.cookie 和 session 的区别
1、cookie 数据存放在客户的浏览器上,session 数据放在服务器上。
2、cookie 不是很安全,别人可以分析存放在本地的 COOKIE 并进行 COOKIE 欺骗
3、session 会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用 COOKIE。
4、单个 cookie 保存的数据不能超过 4K,很多浏览器都限制一个站点最多保存 20 个 cookie。
5、所以个人建议:
将登陆信息等重要信息存放为 SESSION ;其他信息如果需要保留,可以放在 COOKIE 中
49.call、apply、bind 三者的异同
不同:
- call 和 apply 会调用函数,call 传递参数使用逗号隔开,apply 使用数组传递
- bind不会立即调用
50.slot是什么
在HTML中 slot元素,作为WebComponents 技术套件的一部分,是Web组件内的一个占位符该占位符可以在后期使用自己的标记语言填充举个栗子
也就是一个占位符,后期自己去补充
<template>
<slot name="name"></slot>
<template/>
<div slot="name">
</div>
分类:
- 默认插槽
- 具名插槽
- 作用域插槽
51.什么是axios
axios
是一个轻量的http
客户端,基于XMLHttpRequest
服务来执行http
请求
特征:
- 从浏览器中创建XMLHttpRequests
- 从 node.js创建 http 请求支持 PromiseAPI
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 数据自动转换 JSON
- 客户端支持防御 XSRF
封装:
- 请求头:有时候需带些参数(会员业务)
- 状态码:返回的
status
, - 请求方式:
get
,set
- 请求拦截器:根据请求的请求头设定,来决定哪些请求可以访问
- 响应拦截器:这块就是根据 后端`返回来的状态码判定执行不同业务
52.你对SPA单页面的理解,它的优缺点分别是什么,如何实现SPA应用
单页面引用,所有逻辑都在一个页面里面完成,例子:一个杯子,早上装牛奶,中午装水,下午装咖啡
优点:
- 具有桌面应用的即时性、网站的可移植性和可访问性
- 用户体验好、快,内容的改变不需要重新加载整个页面
- 良好的前后端分离,分工更明确
缺点:
- 不利于搜索引擎的抓取
- 首次渲染速度相对较慢
SPA和MPA的区别
SPA | MAP | |
---|---|---|
组成 | 单个组页面 | 多个主页面 |
刷新方式 | 局部刷新 | 整页刷新 |
url模式 | hash哈希模式 | history历史模式 |
SEO搜索引擎优化 | 难实现,可使用SSR方式改善 | 容易实现 |
数据传递 | 容易 | 通过url,cookie,localStorage等传递 |
页面切换 | 速度快,用户体验良好 | 切换加载资源,速度慢,用户体验差 |
维护成本 | 相对容易 | 相对复杂 |
53.如何给SPA做SEO
- SSR服务端渲染
将组件或者页面通过服务器生成html,在返回给浏览器,如next.js
- 静态化
- 使用PhantomJS针对爬虫处理
原理是通过 Nginx
配置,判断访问来源是否为爬虫,如果是则搜索引擎的爬虫请求会转发到一个 node server
,再通过PhantomJS
来解析完整的 HTML
,返回给爬虫。下面是大致流程图
54.什么是首屏加载
第一次加载应用的时间
PS:
-
SPA
的的首屏是,每次打开需要重新拉取资源文件,更具JavaScript动态加载,显示内容(资源大那就很慢) -
MPA
的首屏是服务器已经加载好了的直接返回一个完整的HTML文件页面
- 页面结构:
- MPA:每个页面都是独立的HTML文件,用户请求特定页面时,服务器会发送该页面的HTML内容给用户。
- SPA:整个应用通常只有一个HTML文件,页面内容是通过JavaScript动态加载的,用户在浏览时不会刷新整个页面,而是根据用户的操作动态加载不同的内容。
- 加载方式:
- MPA:每次用户请求一个新页面时,服务器会返回该页面的完整HTML内容,包括首屏内容。
- SPA:在用户第一次访问应用时,服务器会发送一个初始的HTML文件和一些必要的JavaScript和CSS文件。当用户浏览不同的页面或执行操作时,SPA会通过JavaScript动态加载新的内容,而不会刷新整个页面。
- 性能优化:
- MPA:由于每个页面都是独立的HTML文件,可以针对每个页面进行特定的性能优化,包括对首屏内容的优化。
- SPA:由于整个应用通常只有一个HTML文件,需要特别关注首屏加载和性能优化,可以通过预渲染、代码分割、懒加载等技术来提高首屏加载速度和性能。
加载慢的原因:
- 网慢
- 资源文件体积过大
- 资源是否重复请求
- 加载脚本时候,渲染内容堵塞了
解决方式:
常见的几种SPA首屏优化方式
-
减少入口文件体积(路由懒加载配置vue-router时候配置)
-
静态资源本地缓存(
- 采用
HPPT
缓存,设置Cache-Control,Last-Modified,Etag等响应头 - 采用Service Worker离线缓存
- 前端合理利用localStorage)
- 采用
-
UI框架按需加载
-
图片资源压缩
-
组件重复打包
-
开启GZIP压缩
- 安装compression-webpack-plugin
cnmp i compression-webpack-plugin -D
在vue.config.js中修改
webpack
配置const CompressionPlugin = require('compression-webpack-plugin') configureWebpack:(config)=>{ if(process.env.NODE_ENV === 'prodution'){ //为生成环境修改配置。。。 config.mode = 'prodution' return { plugins:[new CompressionPlugin({ test:/\.js$|\.html$|\.css //,匹配文件名 threshold:10240,//对超过10k的数据进行压缩 deleteOriginaLAsset:false//是否删除原文件 })] } } }
express里面
const compression = require('compression') app.use(compression)
- 安装compression-webpack-plugin
-
使用SSR(Vue应用建议使用Nuxt.js来实现服务端渲染)
55.404问题
vue本地是好的,部署到服务器,刷新页面出现404
一般出现出现在history模式下
解决方式:
对 nginx
配置文件.conf
修改,添加 try_files $uri $uri/ /index.html
;
56.Vue2和3的区别
vue3
简要概况:
- 利用新的语言特效(es6)
- 解决框架问题
哪些变化:
- 速度更快(
- 重写了虚拟DOM
- 编译模版优化
- 更高效的组件初始化
undate
性能提高1.3-2倍SSR
提高2-3)
- 体积更小\
- 使用
了webpack
的tree-shaking
功能,仅打包需要的
- 使用
- 容易维护
- 使用了compositionAPi
- 更接近原生
- 容易使用
57.什么是Hooks
Hooks是一个新的React特性提案,组件尽量写成纯函数,如果需要外部React特性(比如状态管理,生命周期),就用钩子把外部特性"钩"进来,通常函数名字都是以use开头。首次在v16.7.0-alpha版本中添加,在v16.8.0中正式发布
58.单页面应用和多页面应用区别及优缺点
单页面应用(SPA),通俗一点说就是指只有一个主页面的应用,浏览器一开始要加载所有必须的 html, js, css。所有的页面内容都包含在这个所谓的主页面中。但在写的时候,还是会分开写(页面片段),然后在交互的时候由路由程序动态载入,单页面的页面跳转,仅刷新局部资源。多应用于pc端。
多页面(MPA),就是指一个应用中有多个页面,页面跳转时是整页刷新
-
单页面的优点:
用户体验好,快,内容的改变不需要重新加载整个页面,基于这一点spa对服务器压力较小
前后端分离
页面效果会比较炫酷(比如切换页面内容时的专场动画) -
单页面缺点:
不利于seo
导航不可用,如果一定要导航需要自行实现前进、后退。(由于是单页面不能用浏览器的前进后退功能,所以需要自己建立堆栈管理)
初次加载时耗时多
页面复杂度提高很多- 姓名
单页面应用(SinglePage Web Application,SPA)
多页面应用(MultiPage Application,MPA) - 组成
一个外壳页面和多个页面片段组成
多个完整页面构成 - 资源共用(css,js)
共用,只需在外壳部分加载
不共用,每个页面都需要加载 - 刷新方式
页面局部刷新或更改
整页刷新 - url 模式
a.com/#/pageone
a.com/pageone.html - 用户体验
页面片段间的切换快,用户体验良好
页面切换加载缓慢,流畅度不够,用户体验比较差 - 转场动画
容易实现
无法实现 - 数据传递
容易
依赖 url传参、或者cookie 、localStorage等 - 搜索引擎优化(SEO)
需要单独方案、实现较为困难、不利于SEO检索 可利用服务器端渲染(SSR)优化
实现方法简易 - 试用范围
高要求的体验度、追求界面流畅的应用
适用于追求高度支持搜索引擎的应用 - 开发成本
较高,常需借助专业的框架
较低 ,但页面重复代码多 - 维护成本
相对容易
相对复杂
- 姓名