diff --git a/.DS_Store b/.DS_Store
index a2ab6f0..78497b9 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/code/findPath.js b/code/findPath.js
new file mode 100644
index 0000000..10422a8
--- /dev/null
+++ b/code/findPath.js
@@ -0,0 +1,48 @@
+const arr = [
+ {
+ id: 1,
+ child: [
+ { id: 3 },
+ {
+ id: 4,
+ child: [
+ {
+ id: 5,
+ child: [{ id: 6 }],
+ },
+ ],
+ },
+ ],
+ },
+ {
+ id: 2,
+ child: [
+ {
+ id: 7,
+ },
+ ],
+ },
+];
+
+function findPathById(arr, id) {
+ let resPath;
+ function fn(arr, path = []) {
+ for (const item of arr) {
+ if (item.id === id) {
+ path.push(id);
+ resPath = path;
+ return;
+ }
+ if (item.child) {
+ path.push(item.id);
+ fn(item.child, [...path]);
+ }
+ }
+ }
+ fn(arr);
+ return resPath;
+}
+
+// findPathById(arr, 6);
+console.log("findPathById(arr, 6)", findPathById(arr, 6));
+console.log("findPathById(arr, 7)", findPathById(arr, 7));
diff --git a/code/limit-fetch.js b/code/limit-fetch.js
new file mode 100644
index 0000000..2dc41ed
--- /dev/null
+++ b/code/limit-fetch.js
@@ -0,0 +1,44 @@
+// 2 为并发最大数
+const limit = pLimit(2);
+const inputs = [
+ limit(() => fetchSomething(1000), "param1"),
+ limit(() => fetchSomething(2000), "param2"),
+ limit(() => fetchSomething(3000), "param3"),
+];
+function fetchSomething(time) {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ resolve();
+ }, time);
+ });
+}
+const time = Date.now();
+Promise.all(inputs).then((results) => {
+ console.log(results);
+ console.log(Date.now() - time); // 需要打印为 4s。(解释:因为并发数限制为2,第一个和第二个请求并发进行,第三个等待,第一个结束后开始第三个请求。总体时间为4s)
+});
+
+// 实现 pLimit 函数?
+function pLimit(limit) {
+ let count = 0;
+ const list = [];
+ function schedule() {
+ if (count < limit && list.length > 0) {
+ const { cb, resolve, reject, args } = list.shift();
+ count++;
+ cb(...args)
+ .then(resolve)
+ .catch(reject)
+ .finally(() => {
+ count--;
+ schedule();
+ });
+ }
+ }
+ return function (cb, ...args) {
+ return new Promise((resolve, reject) => {
+ list.push({ cb, args, resolve, reject });
+ schedule();
+ });
+ };
+}
diff --git a/code/timu.js b/code/timu.js
new file mode 100644
index 0000000..aefc59b
--- /dev/null
+++ b/code/timu.js
@@ -0,0 +1,8 @@
+Object.prototype[Symbol.iterator] = function () {
+ return Object.values(this)[Symbol.iterator]();
+};
+
+// 面试题:如何结构?
+const [a, b] = { a: 1, b: 2 };
+
+console.log(a, b); // 1,2
diff --git "a/pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\345\216\237\347\220\206.md" "b/pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/1.\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\345\216\237\347\220\206.md"
similarity index 100%
rename from "pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\345\216\237\347\220\206.md"
rename to "pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/1.\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\345\216\237\347\220\206.md"
diff --git "a/pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/HTTP\350\257\267\346\261\202.md" "b/pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/2.HTTP\350\257\267\346\261\202.md"
similarity index 65%
rename from "pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/HTTP\350\257\267\346\261\202.md"
rename to "pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/2.HTTP\350\257\267\346\261\202.md"
index 03a22ef..b530a61 100644
--- "a/pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/HTTP\350\257\267\346\261\202.md"
+++ "b/pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/2.HTTP\350\257\267\346\261\202.md"
@@ -99,3 +99,33 @@ HTTP 协议的请求流程:
在 HTTP/1.1 及更高版本中,可以通过 Keep-Alive 复用连接,减少 TCP 连接的建立和断开。
+## HTTP2
+
+
+在 HTTP 1.1 中,虽然支持 Keep-Alive 复用 TCP,但是每个域名有 6 个 TCP 的限制,所以并发需要比较多的 hack 操作,比如申请多个不同的域名以支持开启更多的 TCP 链接,然后通过服务端的反向代理这些域名到真正的服务器;之后 HTTP2 解决了 HTTP1 的单个 TCP 只能同时处理一个HTTP 请求的问题,HTTP2 使用二进制帧的概念,多个 Frame 组合成 Stream,Stream是TCP上的逻辑传输单元,能做到一个 TCP 多路复用,减少 TCP 的连接,并且支持头部压缩,相比之下做了不小的优化。
+
+但是 HTTP2 也有 TCP 的致命缺点,假设第一个 Stream 上丢失了 Frame,后面 N 个 Stream 即使到达了服务器,也是不能被处理的,TCP 需要等待前面发出的包有回应才能处理后序的包,所以这个是 TCP 本身的头部阻塞问题,没有办法根本解决,并且在弱网环境下,HTTP2 性能比 HTTP1 还要低。
+
+移动时代,如果用户的 IP 时刻变化,就需要频繁的进行 TCP 连接和反复握手。
+
+
+
+## HTTP3
+
+我们先来了解一下 TCP 的拥塞控制:
+
+引用自:[HTTP/3正式发布,深入理解HTTP/3协议](https://www.51cto.com/article/713935.html)
+- 慢启动: 发送方像接收方发送一个单位的数据, 收到确认后发送2个单位, 然后是4个, 8个依次指数增长, 这个过程中不断试探网络的拥塞程度.
+- 避免拥塞: 指数增长到某个限制之后, 指数增长变为线性增长。
+- 快速重传: 发送方每一次发送都会设置一个超时计时器, 超时后认为丢失, 需要重发。
+- 快速恢复: 在上面快速重传的基础上, 发送方重新发送数据时, 也会启动一个超时定时器, 如果收到确认消息则进入拥塞避免阶段, 如果仍然超时, 则回到慢启动阶段。
+
+HTTP3 做了相当多的根本升级:
+- 放弃了 TCP,使用自己内部开发的 QUIC 协议,底层是 UDP
+- QIUCK通过递增的 Packet Number,精准计算 RTT(Round Trip Time)
+- QUIC 不需要像 TCP 那样,每个三个数据包就要返回ACK,QUIC 最多可以带 256 个 ACK Block,减少数据包重传问题
+- 通过 connectId 来保持连接,即使用户切换了 IP,也能继续复用连接
+
+# 参考连接
+
+1. [HTTP/3正式发布,深入理解HTTP/3协议](https://www.51cto.com/article/713935.html)
\ No newline at end of file
diff --git "a/pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/3.\347\247\273\345\212\250\347\253\257\351\200\202\351\205\215.md" "b/pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/3.\347\247\273\345\212\250\347\253\257\351\200\202\351\205\215.md"
new file mode 100644
index 0000000..346aefd
--- /dev/null
+++ "b/pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/3.\347\247\273\345\212\250\347\253\257\351\200\202\351\205\215.md"
@@ -0,0 +1,123 @@
+# 移动端适配
+
+## 1. 移动端适配方案
+
+- 方案一:使用viewport
+- 方案二:使用rem
+- 方案三:使用flexible.js
+- 方案四:使用postcss-pxtorem
+
+
+## 2. viewport
+
+viewport是指浏览器的可视区域,它决定了网页的最终显示效果。
+
+viewport的设置方式有两种:
+
+1. meta标签:
+
+```html
+
+```
+
+2. CSS:
+
+```css
+html {
+ width: device-width;
+ height: 100%;
+}
+```
+
+
+- width: device-width:设置viewport宽度为设备宽度,这样可以保证页面的宽度适应不同设备的屏幕大小。
+- initial-scale=1.0:设置初始缩放比例为1.0,这样可以保证页面的初始显示效果。
+
+我们布局时,能使用 vw,vh 去作为单位,这样就可以完美适配不同设备的屏幕大小。
+
+
+## 3. rem
+
+rem是相对于根元素html的font-size的单位,它可以实现不同设备的适配。
+
+使用rem的步骤:
+
+1. 设置根元素html的font-size:
+
+```js
+const $html = document.querySelector('html');
+$html.style.fontSize = $html.clientWidth / 10 + 'px';
+```
+
+
+2. 利用rem单位来设置元素的font-size:
+
+```css
+.item {
+ font-size: 1.6rem;
+}
+```
+
+## 4. flexible 方案
+
+flexible 方案的原理是指定设计稿的宽度,然后根据 dpr 进行缩放,以达到适配不同屏幕的效果。
+
+假设设计稿宽度为 750px,我们可以设置如下代码:
+
+
+在 HTML 的 head 标签里配置 meta 如下: ` `。
+
+```js
+const width = 750;
+const dpr = window.devicePixelRatio || 1;
+const scale = window.innerWidth / width;
+
+let meta = document.querySelector('meta[name="viewport"]');
+const content = `width=${width}, initial-scale=${scale} user-scalable=no`
+if (!meta) {
+ meta = document.createElement('meta');
+ meta.setAttribute('name', 'viewport')
+ document.head.appendChild(meta);
+}
+meta.setAttribute('content', content);
+
+
+```
+那么我们就可以在项目里面愉快的使用 px 啦,并且不需要任何的单位转换。
+
+## 5. postcss-pxtorem
+
+postcss-pxtorem是一个PostCSS插件,它可以将px单位转换为rem单位,实现不同设备的适配。
+
+使用postcss-pxtorem的步骤:
+
+1. 安装postcss-pxtorem:
+
+```
+npm install postcss-pxtorem --save-dev
+```
+
+2. 在postcss.config.js中配置postcss-pxtorem:
+
+```js
+module.exports = {
+ plugins: [
+ require('postcss-pxtorem')({
+ rootValue: 16, // 1rem = 16px
+ propList: ['*']
+ })
+ ]
+}
+```
+
+3. 在需要适配的元素的样式中使用rem单位:
+
+```css
+.container {
+ font-size: 1.6rem;
+}
+```
+
+## 6. 总结
+
+移动端适配方案有很多,每种方案都有其优缺点,根据项目的实际情况选择适合的方案即可。
\ No newline at end of file
diff --git "a/pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/4.\345\211\215\347\253\257\346\200\247\350\203\275\344\274\230\345\214\226.md" "b/pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/4.\345\211\215\347\253\257\346\200\247\350\203\275\344\274\230\345\214\226.md"
new file mode 100644
index 0000000..2dff335
--- /dev/null
+++ "b/pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/4.\345\211\215\347\253\257\346\200\247\350\203\275\344\274\230\345\214\226.md"
@@ -0,0 +1,144 @@
+# 4.前端性能优化
+
+前端性能优化无非是优化服务器加载 HTML 到 生成页面的过程,当然我们说的是传统的 web 页面,小程序,APP 的方向不太一样,可以单独开一个话题,这里主要介绍一下 web 前端性能优化的一些常用方法。
+
+我们先来看一张浏览器渲染页面的流程图:
+
+![浏览器渲染流水线](./images/浏览器渲染架构图.drawio.png)
+
+
+## Chrome 性能指标
+
+- FP First Paint 首次绘制,标记页面第一次绘制像素的时间,比如页面的背景色
+- FCP First Contentful Paint 首次内容绘制,如最大文本块或者图片显示到页面的时间,2s 内完成算优秀
+- LCP Largest Contentful Paint 最大内容绘制,记录视窗内最大元素的绘制时间,并随着时间变化而变化(因为最大元素会随着页面变化而改变),另外会在用户第一次交互后停止记录,2.5s内算优秀
+- TTI Time to Interactive 可交互时间,记录页面的可交互时间
+- FID First Input Delay 首次输入延迟,记录用户第一次输入响应的时间,记录在 FCP 到 TTI 之间,交互相应延迟
+- CLS Cumulative Layout Shift 累积布局偏移,记录页面布局变化的累积量,布局偏移越大,页面加载速度越慢,CLS 指标越高
+
+在这些指标里面,有比较核心的几个指标用于判断页面性能:
+
+LCP、FID、CLS,最大内容绘制影响用户的第一感知,用户输入延迟影响用户的交互体验,累积布局偏移影响用户的阅读体验。
+
+### LCP (最大内容绘制)性能指标
+
+最大内容绘制,那些元素会影响 LCP 呢?
+
+- img 标签
+- svg 内的 image 标签
+- video 标签
+- css 的 background-image
+- 包含文本节点或者其他内嵌文本子元素的块级元素
+
+如果要在 JS 中触发 LCP,可以用以下方式:
+
+```javascript
+const observer = new PerformanceObserver((list) => {
+ const entries = list.getEntries();
+ entries.forEach((entry) => {
+ if (entry.entryType === 'largest-contentful-paint') {
+ console.log('LCP', entry.startTime, entry);
+ }
+ });
+});
+observer.observe({ type: 'largest-contentful-paint', buffered: true });
+```
+
+如何优化 LCP ?
+
+参考渲染流水线图,我们的 FCP 是在图层绘制阶段,这个阶段之前我们都有优化的机会:
+
+- 压缩 css 的体积,推迟非关键 css
+- 内联样式,减少请求
+- 推迟脚本加载和执行
+- SSR 服务端渲染
+
+### FID (用户输入延迟)性能指标
+衡量用户首次与网页互动(输入,点击,滚动等)浏览器的响应时间,FID 越低,用户体验越好。
+
+```javascript
+const observer = new PerformanceObserver((list) => {
+ const entries = list.getEntries();
+ entries.forEach((entry) => {
+ if (entry.entryType === 'first-input') {
+ console.log('FID', entry.processingStart - entry.startTime, entry);
+ }
+ });
+});
+observer.observe({ type: 'first-input', buffered: true });
+```
+
+如何优化 FID ?
+
+- 减少脚本执行时间,优化脚本执行效率
+- 减少收评请求数和文件大小
+- 防止回流
+
+### CLS (累积布局偏移)性能指标
+
+CLS 衡量页面布局的连续性,CLS 越低,页面的加载速度越快。
+
+为了计算布局偏移得分,浏览器会考虑视口大小,以及视口中不稳定元素在两个渲染帧之间的移动。布局偏移分数是该移动的两种度量的乘积:影响分数和距离分数。
+
+比如首帧渲染图片在顶部,下一帧图片移动到了底部,那么布局偏移分数就是影响分数(图片移动了位置)乘以距离分数(图片移动了整个视口)。
+
+```javascript
+const observer = new PerformanceObserver((list) => {
+ const entries = list.getEntries();
+ entries.forEach((entry) => {
+ if (entry.entryType === 'layout-shift') {
+ console.log('CLS', entry.value, entry);
+ }
+ });
+});
+observer.observe({ type: 'layout-shift', buffered: true });
+```
+
+
+如何优化 CLS ?
+
+- 避免布局抖动,减少布局复杂度
+- 初始化的位移,可以使用 transform 添加,不会触发布局偏移
+
+总结:
+
+- 做性能优化之前,优先使用 LightHouse 等工具进行测试,找出瓶颈点
+- 使用 PageSpeed Insights 分析网站性能,找出优化的方向
+- 使用Chrome User Experience Report API 获取网站用户的真实体验数据
+- 也可以使用 Performance 面板查看页面的性能指标,分析出哪些地方需要优化
+
+
+## 前端性能优化方案
+
+**我们回顾下面这张图:**
+
+![浏览器渲染流水线](./images/浏览器渲染架构图.drawio.png)
+
+
+### 1. 减少 HTTP 请求
+
+在从服务器请求 HTML 到生成页面的过程中,HTTP 请求是影响性能的主要因素。
+
+- CDN 加速,减少不同地区的链路延迟
+- 请求协议升级 http2 ,http2优势:二进制传输,多路复用,减少 TCP 连接,首部压缩,服务器推送(请求 HTML 的时候可以把 CSS,JS,图片等资源一起请求)
+- 代码压缩(webpack 压缩插件,terser),gzip压缩
+- 图片懒加载 lazy-load,使用 IntersectionObserver API 实现图片懒加载
+- 图片使用 webp,并使用回退模式(浏览器请求头)
+- 启用 http 缓存(no-cache 是重新验证缓存,no-store 表示永远不使用缓存)
+
+### 2. JS 优化
+
+- 使用模块化开发,避免全局污染,并能做到按需加载和 tree-shaking
+- 懒加载路由,动态导入组件
+- 开启层叠上下文分层渲染,如 transform,z-index 等属性,避免重绘和回流
+- iconfont 字体图标,使用字体文件压缩,减少请求数
+
+
+## 总结
+
+前端性能优化是一个长期的过程,需要不断的学习和实践,才能提升用户的体验。
+
+我们可以从流水线图中去获取优化方案,比如获取 html,可以从网络(CDN),缓存,压缩去做优化,并且在请求的时候去除未用到 的资源,做懒加载,如路由懒加载,图片懒加载等,在新技术方面,http2,webp 图片也是不错的方案。
+渲染的时候尽量减少 js 对渲染主进程的阻塞,如使用 web worker,异步加载,懒加载组件等。
+
+加载完整后,可以从浏览器的渲染着手优化,如分层,减少重绘,回流,使用 webgl,css 动画,使用 IntersectionObserver API 实现图片懒加载等。
\ No newline at end of file
diff --git "a/pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/WebAssembly.md" "b/pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/5.WebAssembly.md"
similarity index 100%
rename from "pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/WebAssembly.md"
rename to "pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/5.WebAssembly.md"
diff --git "a/pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/images/\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\236\266\346\236\204\345\233\276.drawio.png" "b/pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/images/\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\236\266\346\236\204\345\233\276.drawio.png"
index e69de29..fada4c8 100644
Binary files "a/pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/images/\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\236\266\346\236\204\345\233\276.drawio.png" and "b/pages/6-\345\211\215\347\253\257\347\237\245\350\257\206\347\202\271/images/\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\346\236\266\346\236\204\345\233\276.drawio.png" differ