File tree 5 files changed +31
-38
lines changed
5 files changed +31
-38
lines changed Original file line number Diff line number Diff line change @@ -12,7 +12,7 @@ outline: deep
12
12
幸运的是,这里有两个特性可以为我们解决这个问题:defer 和 async。(仅用于外部脚本)
13
13
:::
14
14
## defer
15
- 脚本将在后台下载,不阻塞页面 。等待dom解析完毕,但在 ` DOMContentLoaded ` 事件之前执行
15
+ 脚本将在后台下载,不阻塞html解析 。等待dom解析完毕,但在 ` DOMContentLoaded ` 事件之前执行
16
16
::: tip DOMContentLoaded
17
17
::: raw
18
18
当 HTML 文档已完全解析且所有延迟脚本(` <script defer src="…" />和<script type="module" /> ` )已下载并执行时,将触发此事件
@@ -21,4 +21,4 @@ outline: deep
21
21
具有defer特性的脚本按照其相对顺序执行
22
22
23
23
## async
24
- 也不会阻塞页面 ,async脚本不会等待其他脚本,async脚本可能在 ` DOMContentLoaded ` 之前或之后执行
24
+ 也不阻塞html解析 ,async脚本不会等待其他脚本,async脚本可能在 ` DOMContentLoaded ` 之前或之后执行
Original file line number Diff line number Diff line change @@ -34,5 +34,20 @@ console.log("5"); // 同步任务
34
34
* 建立tcp连接
35
35
* 发送http请求
36
36
37
+ 处理资源
38
+ * 解析html生成dom树
39
+ * 遇到css生成cssom树
40
+ * 遇到普通js会阻塞html解析,需要下载再执行,加了defer或者async不会阻塞
41
+ * 将dom树和cssom树合成渲染树
42
+ * 计算布局,交给合成器线程和GPU渲染页面
37
43
## tree-shaking
38
- 基于静态分析,只适用于esm,因为esm是静态的,在编译时就可以确定导入导出,据此去除未使用的代码
44
+ 基于静态分析,只适用于esm,因为esm是静态的,在编译时就可以确定导入导出,据此去除未使用的代码
45
+ ## 性能优化
46
+ * 打包,使用webpack-bundle-analyse分析插件打包产物,对比较大的文件进行拆包,目的是保证不要太小或者太大,因为太大稍微修改之后整个文件就过期了,太小的话http请求会多发送,尽可能利用浏览器的缓存策略,使用gzip或者brotile压缩
47
+ * 代码上要写成支持tree-shaking的格式
48
+ * 图片使用webp格式,进行图片懒加载和组件的懒加载
49
+ * 将cpu密集型任务迁移到webworker上,防抖和节流
50
+ * 使用proload提高关键资源优先级,支持的话尽可能使用HTTP2,使用cdn
51
+ * 框架上,都支持路由懒加载,react有useMemo,useCallback进行缓存,vue支持组件的懒加载,shallowReactive等api
52
+ * 渲染层上,降低cls,例如图片尽可能设置高度。减少重排和重绘,虚拟列表。动画使用transition,Gpu加速
53
+ * 大文件切片上传
Original file line number Diff line number Diff line change 2
2
outline : deep
3
3
layout : doc
4
4
---
5
- ## ref
6
- 通过ref注册的响应式数据,有一个访问器属性value,当getter时收集依赖,setter时派发更新
7
-
8
- 而对于set的value,使用toReactive进行处理,首先判断数据类型是不是object,如果不是原样返回,反之使用reactive使value也变成响应式数据
9
- ## reactive
10
- :::tip :rocket : 代理
11
- 允许我们拦截并重新定义对一个对象的基本操作
12
- :::
13
- 基于proxy进行代理,他接受两个参数,第一个参数是被代理对象,第二个参数是一组traps,例如get set,通过这些trap可以控制被代理对象的基本操作
14
-
15
-
16
- 对于reactive来说,有get set deleteProperty has ownKeys这些traps
17
-
18
- 在get中进行track依赖收集,如果value是一个对象,会递归调用reactive实现深度监听。如果value是一个ref类型,会进行自动解包
19
-
20
- 在set中处理新增和修改属性,进行trigger派发更新
21
-
22
- 在deleteProperty处理删除属性,触发trigger
23
-
24
- 在has拦截in操作符,触发track
25
-
26
- 在ownKeys拦截forin,触发track
27
-
28
- 通过配置这些traps可以进一步实现shallowreactive,readonly等api
29
5
30
6
## computed
31
- 使用computed会返回一个对象,它也有一个访问器属性value,初始化时会执行一遍里面的回调函数,搜集依赖。
7
+ 使用computed会返回一个对象,它也有一个访问器属性value.
32
8
33
9
并且还有两个属性dirty和value,dirty初始化设置为true,代表需要重新执行回调,value则是回调return的值。
34
10
Original file line number Diff line number Diff line change @@ -160,6 +160,8 @@ Vue的响应式系统在运行时跟踪属性的访问,它通过结合proxy包
160
160
161
161
proxy第一个参数是被代理对象,第二个参数是一组traps,通过这些traps可以控制被代理对象的基本操作。
162
162
163
+ vue的响应式一般通过两个api实现,reactive和ref
164
+
163
165
对于reactive来说,有get、set、deleteProperty、has、ownKeys这些traps,在get中触发track依赖收集。
164
166
165
167
在track内部我们会检查当前是否有正在运行的副作用。如果有,我们会查找到一个存储了所有追踪了该属性的订阅者的Set,然后将当前这个副作用作为新订阅者添加到该Set中。
@@ -173,6 +175,10 @@ proxy第一个参数是被代理对象,第二个参数是一组traps,通过
173
175
最常见的响应式副作用就是更新dom。每个组件实例创建一个响应式副作用来渲染和更新dom。
174
176
175
177
而对于ref,返回一个对象,里面有一个响应式属性value,执行getter时,进行track,执行setter时触发trigger,对于setter的参数value则会使用reactive处理。
178
+
179
+ shallowReactive和readonly这些api都是在此基础上修改traps来实现的
180
+
181
+ 当然vue的响应式是单向的,也就是从数据到dom的映射
176
182
## 双向绑定v-model
177
183
响应式系统是一种单向行为,是从数据到dom的映射,而双向绑定,则是双向行为,当数据改变,dom会更新,而操作dom也会影响数据的变化
178
184
@@ -184,6 +190,12 @@ proxy第一个参数是被代理对象,第二个参数是一组traps,通过
184
190
185
191
而对于组件,实际上是一个语法糖,相当于传入一个名为modelValue 的prop,和一个名为 update: modelValue 自定义事件,事件的回调函数接受一个参数,执行时会更新modelvalue
186
192
193
+ ## vue2与vue3区别
194
+ * 重构了响应式系统,vue3使用了基于proxy的响应式系统,vue2"
195
+ * 引入了Composition api,使逻辑复用更加方便,
196
+ * 新增了fragment,teleport,suspense这样的内置组件,
197
+ * 使用ts进行重写,在idea中的代码提示效果更好,
198
+ * 在性能方面,优化了模板编译和diff算法,并且支持树摇,打包体积进一步缩小,基于monorepo的架构,使用pnpm进行管理。各个模块之间耦合低,并且可以拆开来单独使用
187
199
## 编译优化
188
200
* 静态提升,后续更新直接复用,减少了对比的花销
189
201
* 标记虚拟dom节点上的动态属性,在更新时只对比标记的部分
Original file line number Diff line number Diff line change @@ -228,16 +228,6 @@ function throttle(func, duration) {
228
228
];
229
229
consoleInfo (list2, " 难点" );
230
230
},
231
- 优化: () => {
232
- const list = [
233
- " 图片使用webp格式,进行图片/组件的懒加载,将第三方库上传到cdn" ,
234
- " 通过树摇删除无用代码,使用gzip压缩,合理控制打包文件大小,充分利用浏览器缓存策略" ,
235
- " 将长任务移动到web worker,防止阻塞页面" ,
236
- " 防抖和节流,避免内存泄露" ,
237
- " 使用虚拟列表,大文件上传技术" ,
238
- ];
239
- consoleInfo (list, " 性能优化" );
240
- },
241
231
scoped : () => {
242
232
const list = [
243
233
" scoped会为组件生成唯一标识,并在dom上添加这个属性,选择器也会在末尾加上这个属性选择器" ,
You can’t perform that action at this time.
0 commit comments