浏览器
介绍
现在浏览器种类繁多,但核心技术就那几个,好多浏览器都是套壳,所以只需要了解几大主流浏览器
- Chrome
- Firefox
- Opera
- Safari
- Edge
- IE(已经放弃)
工作原理
浏览器流程
URL --> http
(HTML) --> parse
(DOM) --> css computing
(DOM WITH CSS) --> layout
(DOM WITH POSITION) --> render
(Bitmap, 即内存中的一张图)
HTTP PARSE CSS COMPUTING LAYOUT RENDER
URL --------> HTML ---------> DOM -----------------> DOM WITH CSS -----------> DOM WITH POSITION ----------> BITMAP(内存中的一张图片)
ISO-OSI七层网络模型
(Open System Interconnection)
- 应用层
- 表示层
会话层
以上三层在五层模型中合并到了应用层 HTTP、FTP
require('http')
传输层
TCP
require(net)
网络层
TP、Internet
数据链路层
物理层
4G/5G/WIFI
TCP、IP
TCP:
- 流(可靠流,收不到要重发)
- 端口
- require('net')
IP:
- 包
- IP地址
- libnet/libpcap (C++中的两个库)
HTTP
- request
- response
有限状态机
状态是有限的,它与状态模式不是一回事; 例如正则的底层就是通过状态机实现的
- 每一个状态都是一个机器
- 在每一个机器里,可以计算、存储、输出
- 所有的这些机器接受的输入是一致的
- 状态机的每一个机器本身没有状态,如果我们用函数来表示,应该是一个纯函数(没有副作用)
- 每一个机器知道下一个状态
- 每个机器都有确定的下一个状态(Moore状态机)
- 每个机器根据输入决定下个一状态(Mealy状态机)
// 处理字符串,字符串中是否存在 'abcde'
function match(str) {
let foundA = false;
let foundB = false;
let foundC = false;
let foundD = false;
for (let c of str) {
if(c == 'a') {
foundA = true
} else if (foundA && c == 'b') {
foundB = true
} else if (foundB && c == 'c') {
foundC = true
} else if (foundC && c == 'd') {
foundD = true
} else if (foundD && c == 'e') {
return true
} else {
foundA = false
foundB = false
foundC = false
foundD = false
}
}
return false
}
match('hello llabcdefg')
// mealy
function state(input) {
// 在函数中可以自由地编写代码,处理每个状态地逻辑
return next;// 返回值作为下一个状态(函数)
}
// 调用
while(input) {
// 获取输入
state = state(input) // 把状态机地返回值作为下一个状态
}
// 假如pattern完全未知怎么办??? 使用状态机完成等效于 KMP 算法的方式, 时间复杂度不能高(不能用双循环)
// function match(pattern, string) {
//
// }
function match(str) {
let state = start
for (let c of str) {
state = state(c)
}
return state === end
}
function start(c) {
if (c === 'a') {
return foundA
} else {
return start
}
}
function end(c) {
return end
}
function foundA(c) {
if (c === 'b') {
return foundB
} else {
return start(c)
}
}
function foundB(c) {
if (c === 'c') {
return foundC
} else {
return start(c)
}
}
function foundC(c) {
if (c === 'd') {
return foundD
} else {
return start(c)
}
}
function foundD(c) {
if (c === 'e') {
return end
} else {
return start(c)
}
}
AST抽象语法树
多进程架构
一个程序常常被划分为几个相互独立又彼此配合的模块,浏览器也是由多个进程组成,每个进程有自己的职责,配合完成浏览器的整体功能。 每个进程(process)中又包含多个线程(thread),多个线程会协同工作。 当我们启动一个应用,计算机会创建一个进程,操作系统会为进程分配一部分内存,应用的所有状态都会保存在这块内存中,应用也许还会创建多个线程来辅助工作,这些线程可以共享这部分内存中的数据。如果应用关闭,进程会被终结,操作系统会释放相关内存。 两个进程之间可以使用 IPC(Inter Process Communication)进行通信。很多应用都会采用这样的设计,如果一个工作进程反应迟钝,重启这个进程不会影响应用其它进程的工作。
V8引擎内存
- 页面占用内存过大,会导致客户端卡顿,甚至无响应
- node也是V8,对后端服务的性能至关重要。因为服务的持久性,后端容易造成内存溢出
64位操作系统: 1.4G(够用了); 新生代(新产生的变量): 64MB,老生代(存在时间比较长的变量): 1400MB
32位为0.7G; 新生代: 16MB; 老生代: 700MB
新生代回收算法:复制 (牺牲时间换空间)
老生代回收算法:标记删除整理(牺牲空间换时间,类似磁盘碎片整理,如数组需要连续的内存空间,所以需要整理)
如何查看V8内存使用情况
优化内存
前端的特点:
- 不持久化
- 执行一遍全部回收(js回收内存时,会暂停执行)
- 每回收100MB时,约6毫秒,所以分配内存不宜过大,防止回收占用的时间比较长
V8引擎中的[array sort](https://github.com/v8/v8/blob/ad82a40509c5b5b4680d4299c8f08d6c6d31af3c/src/js/array.js)
插排、快排
方法:InsertionSort( < 10 ) QuickSort (> 10)
有限状态机
判断是否打开了开发者工具
防止浏览器后退
history.pushState(null, null, location.href);