SPA(single-page application),翻译过来就是单页应用SPA是一种网络应用程序或网站的模型
它通过动态重写当前页面来与用户交互,这种方法避免了页面之间切换打断用户体验在单页应用中,所有必要的代码(HTML、JavaScript和CSS)都通过单个页面的加载而检索,
或者根据需要(通常是为响应用户操作)动态装载适当的资源并添加到页面页面在任何时间点都不会重新加载,也不会将控制转移到其他页面
举个例子来讲就是你去公司上班老婆给你送饭,饭盒早上装的包子 豆浆 油条。饭盒中午装的米饭 面条 大鸡腿,饭盒晚上装的蔬菜沙拉 烤地瓜。我们发现变的始终是早中晚饭和饭盒里菜的样式,而饭盒始终是那个饭盒
我们熟知的JS框架如react,vue,angular都属于SPA
单页应用优缺点
优点:
具有桌面应用的即时性、网站的可移植性和可访问性
用户体验好、快,内容的改变不需要重新加载整个页面
缺点:
首次渲染速度相对较慢
不利于搜索引擎的抓取
解决首次加载慢的问题
1. 减少入口文件体积
2. 静态资源本地缓存
3. UI框架按需加载
4. 路由懒加载
MVC
M: model数据模型, V:view视图模型, C: controller控制器
是项目的一种分层架构思想,它把复杂的业务逻辑,抽离为职能单一的小模块,每个模块看似相互独立,其实又各自有相互依赖关系。
它的好处是:保证了模块的智能单一性,方便程序的开发、维护、耦合度低。
mvvm
M: model数据模型, V:view视图模型, VM: viewModel视图数据模型
它是一种双向数据绑定的模式,用viewModel来建立起model数据层和view视图层的连接,数据改变会影响视图,视图改变会影响数据
js的数据类型分为基本数据类型(string、number、boolean、null、undefined、symbol,BigInt)
复杂数据类型(object)
基本数据类型的特点:直接存储在栈中的数据
复杂数据类型的特点:存储的是该对象在栈中引用,真实的数据存放在堆内存里
symbol
符号是原始值,且符号实例是唯一、不可变的
符号的用途是确保对象属性使用唯一标识符,不会发生属性冲突的危险
BigInt 数据类型的目的是比Number数据类型支持的范围更大的整数值。在对大整数执行数学运算时,以任意精度表示整数的能力尤为重要。使用BigInt,整数溢出将不再是问题。
然后判断数据类型的方法一般可以通过:typeof、instanceof、constructor、Object.prototype.toString.call()四种常用方法
| 不同类型的优缺点 | typeof | instanceof | constructor | Object.prototype.toString.call |
|---|---|---|---|---|
| 优点 | 使用简单 | 能检测出引用类型 | 基本能检测所有的类型(除了null和undefined) | 检测出所有的类型 |
| 缺点 | 只能检测出基本类型 | 不能检测出基本类型,且不能跨iframe | constructor易被修改,也不能跨iframe | IE6下,undefined和null均为Object\ |
使用方法
typeof typeof 数据 返回值是数据类型
instanceof 数据 instanceof 引用数据类型 返回值是true/false
constructor 数据.constructor 返回值是数据类型
Object.prototype.toString.call 在call( 数据 ) 返回值是数据类型
首先创建一个新的空对象
将新对象的原型对象指向构造函数的原型对象
将新对象的this指向构造函数
判断如果当前的构造函数是否是对象,如果是对象则返回构造函数,如果不是则返回新创建的对象
浏览器获取到 html 资源后开始解析 html (dom tree) -> 构建 DOM 树
解析到 css 后根据 css 生成 css 规则树 (style rules) -> 产生 CSS 规则树
在 dom 树和 css 规则树都生成完后,
通过 dom 树和 css 规则树生成渲染树( render tree ) -> 构建 render 树
渲染树构建完成后,浏览器开始计算元素的大小和位置( layout ) -> 布局 render 树
根据计算好的节点信息将内容绘制到屏幕上( painting ) -> 绘制 render 树
详细过程
dom 树和 css 规则树的先后顺序
浏览器获取的 html 资源后自上而下开始解析,生成 dom 树;如果遇到 style 的内联样式和 link 会将 css 交由 css 渲染器构建 css 规则树; 其中加载 link 引入的外部样式文件是异步加载的,并且整个 css 规则树也是与 dom 树的构建是并行的;
Javascript脚本的加载
由于 js 可以操作 dom,所以在 html 解析到 Javascript 脚本时会停止对 dom 的解析;而 css 的解析会阻塞 js 的执行,所以在某些情况下 css 的解析会导致 dom 的解析;
script的defer 属性
给 script 标签添加 defer 属性,适用于 js 中涉及到 dom 的操作,或者与其他的 js 有相互引用的关系 添加 defer 属性会将 Javascript 脚本延迟执行,但是 html 解析过程中遇到 script 标签仍然会进行下载
defer 脚本会在 dom 解析完成后,DOMContentLoaded事件调用前执行,而且 defer 属性的 js 脚本会按照顺序执行,即在 dom 解析完成后会依次执行 script标签
script的async属性
给 script 标签添加 async 属性,适用于 js 与 dom 和其他 js 文件无关的情况
添加 defer 属性会将 Javascript 脚本异步执行,html 解析过程中遇到 script 标签会进行下载,且下载完成后立即进行异步执行
由于是异步执行,所以当有多个异步的 js 脚本时无法控制先后执行的顺序,所以有多个异步 js 时,这些 js 不要互相有引用
由于添加 async 属性,使 js 在下载完成后立即执行,所以为了在该 js 中不要进行 dom 的相关操作
渲染树( render tree )的构建过程
从 dom 树的根节点开始遍历每一个可见的节点;例如引用 css 文件的 link 标签、引入js 文件的 script 标签和 css 属性设置了 display: none; 的节点
从 css 规则树 (style rules) 中找到对应的节点,然后根据节点信息和样式组合成渲染树( render tree )