- 博客(45)
- 收藏
- 关注
原创 填坑 | React Context原理
本文深入解析了React中Context的实现原理。通过分析DOM结构和对应的Fiber结构,揭示了Context值传递的栈式工作原理:在深度优先遍历过程中,Provider将当前值推入栈并更新_currentValue,子组件通过_currentValue获取上下文值。文章详细介绍了createContext创建上下文对象的过程,以及updateContextProvider、pushContext/popContext等关键实现。同时重点探讨了Context与bailout策略的兼容性问题,通过维护de
2025-07-18 20:03:00
934
1
原创 简单聊一下浏览器缓存
本文介绍了浏览器缓存的两种策略:强制缓存和协商缓存。强制缓存通过响应头中的max-age或Expires设置资源过期时间,在有效期内直接使用缓存;协商缓存则每次请求都会询问服务器资源是否更新(通过Last-Modified或ETag验证)。文章还区分了no-cache(可缓存但需验证)和no-store(完全禁用缓存)的差异,并指出实际开发中常见做法:入口HTML不缓存,静态资源使用长期强制缓存(如max-age=1年),通过内容hash实现资源更新。正确使用缓存策略能显著提升页面性能。
2025-07-08 17:19:38
814
原创 简单聊一下 TCP 协议
TCP协议是传输层核心协议,提供可靠的数据传输服务。文章分析了TCP的工作原理,包括三次握手建立连接、四次挥手断开连接、分段传输机制和可靠传输保障。通过序列号确认、校验和、重传机制等技术,TCP确保数据有序完整到达。相比UDP,TCP具有流量控制、拥塞控制等功能,但效率较低。理解TCP协议对网络开发具有重要意义,能帮助开发者优化应用性能,处理网络异常情况。文章还详细介绍了TCP头部结构、滑动窗口、RTO等关键技术细节。
2025-07-04 18:09:12
716
原创 接上篇 聊一下大文件切片上传,下载,秒传的解决方案
大文件处理方案核心总结: 上传优化:采用分片上传(5MB/片)、WebWorker多线程计算文件hash、秒传和断点续传机制,通过抽样hash提升性能 服务端实现:临时目录存储分片,合并时按序拼接,检查请求实现秒传和续传功能 下载方案:基于HTTP Range协议实现断点续传,206状态码返回分片内容 关键技术:文件切片(Blob.slice)、SparkMD5计算hash、FormData传输、WebWorker多线程处理 注意事项:前端需处理分片排序和唯一标识,服务端需保证分片合并顺序正确 (字数:14
2025-06-30 16:54:40
796
原创 简单说一下文件的上传&下载
本文简要介绍了浏览器中的File和Blob对象。File继承自Blob,两者都是存储二进制数据的不可修改对象。要读取内容需使用FileReader,它提供readAsText、readAsArrayBuffer等方法将二进制数据转换为不同格式。文章还演示了如何封装FileReader为Promise形式,并对比了各种读取方式的差异。File对象可通过new File()创建或通过input文件选择框获取。由于浏览器安全限制,JavaScript需要通过用户授权才能访问文件系统。
2025-06-27 11:50:41
682
原创 简单总结一下 cookie
Cookie是HTTP协议中用于保持客户端状态的关键技术。它解决了HTTP无状态特性带来的问题,允许服务器在客户端保存非敏感信息(如SessionID、JWT Token)。Cookie可通过服务器Set-Cookie响应头或JS的document.cookie设置,包含key/value及domain/path/expires等元数据。浏览器自动管理Cookie的发送匹配规则:domain匹配当前域或子域,path匹配当前路径或子路径。安全方面需注意:1) 避免存储敏感信息;2) 防范CSRF攻击(通过S
2025-06-16 17:09:04
993
原创 简单说一下 Webpack分包
最近在看有关webpack分包的知识,搜索了很多资料,感觉这一块很是迷惑,网上的资料讲的也迷迷糊糊,这里简单总结分享一下,也当个笔记。如有错误请指出。
2025-05-16 17:53:36
985
原创 redux | saga 中间件使用
本文的源代码可以在我的git仓库找到我自己实现的Saga Middleware 接近官方实现原理上一篇浅谈了一下Redux的实现原理,可以发现其本质上就是封装了一套对State的修改监听流程,原理上很简单。redux的中间件设计给其带来了很大的可拓展性和丰富的生态,这篇就来简单聊聊比较常用的异步中间件saga的使用和原理。saga的核心原理基于Javascript的迭代器&生成器,如果你对这一块还不了解,可以看一下我之前的文章。
2025-04-28 19:21:59
975
原创 Redux 容器 | 原理解析
Redux是一个Javascript的状态管理容器。提到Redux,往往会想到结合React做应用全局的状态管理,但是Redux本质上是一个独立的库,你可以将其用在任何需要集中管理的框架(甚至是nodejs)中,只是结合React是我们最常用的开发方式罢了。
2025-04-27 14:23:57
853
原创 前端路由 ( 1 ) | history 原理
当前主流前端路由的实现基于history库,今天就来简单说说其原理。项目具体实现可以访问我的git仓库查看:前端路由出现之前,多页面应用在切换页面时通常需要浏览器重新向服务器发送Get请求重新获取html文档。单页面应用全局只有一个index.html 文档,我们需要在路由切换的时候,动态修改其内容,并且保证其不反复向服务器发送请求。所以,前端路由需要解决以下两个问题:1. 如何修改浏览器URL栏的内容并且不让浏览器重新请求页面2. 如何监听到路径的变化以切换页面内容。
2025-04-22 17:59:48
1168
原创 CSS 相对复杂但实用的margin
margin 可以理解为盒子的外边距,决定了盒子与盒子之间的距离。margin包围的盒子尺寸一般称为盒子的"外部尺寸"。外部尺寸和内部尺寸(可视尺寸)和 偏移尺寸 不同,其值可以为负,这就给margin带来了很多有意思的现象和应用,我们常用的左右布局,双飞翼布局,圣杯布局,等高布局,都可以采用负的margin盒子完成!复习一下: 外部尺寸 内部尺寸 偏移尺寸 (滚动尺寸)
2025-03-21 18:20:10
839
原创 你不知道的 CSS Padding
padding 可以简单的理解为 填充在内容盒外层的“海绵”, 当box-sizing为默认的content-box时,增加padding时会导致整个盒子变大。如果你设置box-sizing为border-box, 并且设置width,此时width是整个border-box的宽度,如果此时padding超出这个尺寸,那么width会失效,盒子被撑开!
2025-03-20 16:39:43
876
原创 聊一下CSS层叠
层叠,即页面各个元素在Z轴方向上的先后顺序,谁压着谁,谁覆盖着谁。其中z轴定义如下,也就是垂直于显示器的方向,定位元素flex子元素这里需要注意,浮动元素可以理解为漂在文档流上面,仅仅贴着文档流的,类似于水面上的救生圈,所以浮动元素的zIndex也不起作用!
2025-03-13 17:35:14
934
原创 React 源码揭秘 | bailout策略&Memo
前面的文章介绍了React 更新 render + commit的完整流程,下面来说一下一些优化策略。bailout 即 熔断策略,即在BeginWork阶段,如果递到某个节点的子树, 如果该节点的子树已经不需要更新了,即和current保持一致了,那么可以直接熔断(bailout)当前Beginwork过程,复用current的子树即可。如何确定子树不用更新了?这个取决于四要素,即current节点和新Fiber节点的我们主要看前三条,如何判断这三条是否满足bailout条件。
2025-03-03 14:29:27
1111
原创 React 源码揭秘 | Ref更新原理
Ref主要作用于HostComponent组件,用来获取其真实的DOM节点。除此以外,我们也通常用useRef等hooks来维护一个稳定的值,并且在该值改变的时候不触发更新。
2025-02-27 14:30:58
987
原创 React 源码揭秘 | Effect更新流程
前面的文章介绍了 hooks和commit流程,算是前置知识,这篇来讨论一下useEffect的原理。useEffect用来处理副作用,比如网络请求,dom操作等等, 其本质也是个hooks,包含hooks的memorizedState, updateQueue, next。
2025-02-26 19:42:32
869
原创 React 源码揭秘 | commit流程
前面文章所描述的都发生在render过程中。React包含两个过程,即render和commit过程,其中render过程是可以打断的,而commit阶段是不可打断的。commit阶段可以理解是真正的操作DOM的阶段,其消费render阶段打到Fiber节点上的Flag,并且根据Flag对真实DOM元素进行更新,删除,插入等操作。先来复习一下Flag,我们知道,commit包含两个子阶段,即:Mutation阶段: 此阶段主要进行DOM的更新操作,包含DOM的增删改,以及Ref的更新阶段。
2025-02-26 16:53:37
1120
原创 React 源码揭秘 | hooks原理
上篇我们说了updateQueue的实现原理,这篇我们说一下hooks,fiberHooks实现可以在找到。老生常谈的问题,为什么hooks有顺序,hook函数怎么知道你在哪运行的hooks?下面我们逐一讨论。
2025-02-25 18:46:25
815
原创 React 源码揭秘 | 更新队列
前面几篇遇到updateQueue的时候,我们把它先简单的当成了一个队列处理,这篇我们来详细讨论一下这个更新队列。有关updateQueue中的部分,可以见源码。
2025-02-24 19:06:30
961
原创 React 源码揭秘 | lane模型
lane即车道的意思,其本质是个二进制的数字类型,其定义如下: (fiberLanes.ts)/** 单车道 *//** 多车道 (优先级合集) */可以看到,单个lane只能有一位是1,其余都是0,每个lane优先级1的位置都不同,互相没有重叠,数字越小,即1越靠前,优先级越高。多个lane的或运算代表批的概念 即lanes,如表示所有的Transition优先级所占用的lane的合集。
2025-02-20 19:14:20
617
原创 React 源码揭秘 | CompleteWork “归“的过程
上篇说了BeginWork的流程,我们继续看workLoop.ts/performUnitOfWork函数当一个Fiber节点的beginwork流程结束后,当前节点的pendingProps以及使用完成,将其保存在memorizedProps。
2025-02-20 15:59:59
872
原创 React源码揭秘 | 不同类型Fiber的BeginWork流程
上篇以BeginWork阶段处理HostRoot根Fiber节点为例介绍了的child reconcile协调过程,这篇主要看一下各种类型的Fiber节点在BeginWork中的处理流程。
2025-02-20 11:24:11
1244
原创 React 源码解析 | Reconcile协调过程
上篇讲了React的工作流程,这篇详细的讲一下render过程中的beginWork函数,也就是深度优先创建Fiber树中"递"的过程。beginWork函数传入当前已经创建好的Fiber节点,返回创建/复用的第一个子FIber节点,也就是wip.child在renderRoot中,在开始创建整棵FIber树之前,会先调用prepareRefreshStack创建/复用一个新的HostRootFiber。
2025-02-17 23:45:54
1001
原创 React 源码揭秘 | 工作流程
上一篇介绍了React启动的入口,以及一些前置知识,这篇来说一下整个React的工作循环。render函数做了两件事,1. 是初始化合成事件,React通过对Container进行事件代理的方式管理事件,对事件进行一层封装,后面会详细讲。2. 调用updateContianer函数,此函数调用scheduler.runWithPriority传入一个立刻执行优先级的同步执行回调(runWithPriority具体细节见。
2025-02-17 17:55:34
1115
原创 React源码揭秘 | 启动入口
本文主要介绍React18版本的初始化启动过程,包含ReactElement元素的创建,createRoot如何创建根节点,以及Fiber树的基本结构,算是揭秘React核心原理的前置知识总结。
2025-02-17 15:52:22
1171
原创 React源码揭秘 | scheduler 并发更新原理
React 18增加了并发更新特性,开发者可以通过useTransition等hooks延迟执行优先级较低的更新任务,以达到页面平滑切换,不阻塞用户时间的目的。其实现正是依靠scheduler库。scheduler是一个依赖时间片分片的任务调度器,React团队将其单独发包,你可以通过以下指令来单独使用。在CPU密集操作中(如大量echarts数据补点等)可以借助scheduler将大的任务拆分成子任务运行,并且不阻塞渲染引擎以及用户事件。
2025-02-12 17:10:24
1289
原创 Proxy vs DefineProperty
几年前校招面试的时候被问过一个问题,Vue3/Vue2 如何实现数据和UI的同步,其区别是什么,Vue3的方式优势是什么?当时背了八股,默写了一通不知所云的代码,面试没过,再也没写过Vue。今天拿出点时间来写一下这个问题的前因后果,也算是做个笔记吧。
2025-02-10 18:07:55
871
原创 关于手写promise的一点补充
这样看上去没问题,但是我们需要注意,这里的then方法是在MyPromise对象上的,对于其他非MyPromise类型的thenable,是没有实现这个then方法的,其then方法可能没有循环调用的功能,所以只能实现单层的then调用,所以我们需要做的就是,在鸭子检测后判断。2. 如果是 非MyPromise类型的thenable,则调用其then方法,在成功的回调中再次调用_handleThenable 递归处理。1. 如果thenable是MyPromise类型,直接调用then方法。
2024-09-30 10:50:07
960
原创 填坑,从零带你手写Promise (typescript)
手撸promise之前,我们先用ts对我们自己的promise进行简单的类型定义观察一下浏览器提供的Promise对象:在Promise对象本身上,包含了记录promise对象状态的 state 以及记录结果的Result。其中state包含了 pending fulfilled rejected 三个状态。/** Promise状态枚举 *//** 未决策状态 *//** 成功状态 *//** 拒绝状态 */
2024-09-29 14:12:57
879
原创 从异步传染浅谈代数效应
如果你经常使用并且关注React,你一定会在不少地方见过"代数效应"(algebra effect) 这个抽象概念。可能是翻译和过度学术的缘故,我看了很多文章才大致理解,在这里简单记录一下。
2024-09-26 14:55:14
1030
原创 简单聊聊宏任务和微任务
也就是说,如果你的任务代码中,包含同步阻塞代码,比如 while(true);当一帧的渲染完成后,事件循环会调度js引擎来执行宏任务队列中的任务,(这里需要强调,我们写的同步js代码,也会被封装成任务放到宏任务队列中)如果宏任务队列中存在任务,则将其加入到执行栈中执行,执行之后出栈,继续拿出来队列中的下一个任务执行!此时,第一个宏任务执行完成,弹出执行栈,执行栈为空,此时不会去取下一个宏任务,而是去检查微任务队列,执行微任务输出MicroTask1,执行后,微任务队列空,此时再去取下一个宏任务。
2024-07-04 18:13:05
980
原创 聊一下浮动
我们在排版文字的时候,通常会把开头第一个文字/字母放大处理以达到美观的效果。这样做确实能实现效果,但是如下图所示,第一行的排版受到第一个字母的内容区影响会变得很奇怪,上下行间距都会变得很宽, 解决的办法可以是设置vertical-align: text-bottom 但是上半行距也会变得很奇怪。更好的解决办法是将::first-letter 伪元素设置为浮动元素,这样就可以让文字环绕在其周围,并且不影响行间距。
2024-05-24 18:27:45
956
1
原创 简单总结一下Flex布局
flex 布局在日常开发的过程中是非常常用的了,相较于传统的流式布局,flex可以更加灵活的设置布局内元素的排布和大小。
2024-05-23 01:28:45
1617
原创 数据结构 树结构简单总结
树(Tree): 是由n(>=0)个节点组成的有限集合n = 0 时,为空树树的根Root用r表示,其余的节点可以分为m(m>=0)个不相交的有限子集T1,T2...Tm,每个子集本身又是一棵树。
2024-05-08 16:50:16
538
原创 浅谈line-height&vertical-align
在使用css调整一个行内元素对齐的时候,不知道你是不是和我一样有类似的疑问:1️⃣ 我想使用vertical-align: middle 这样的方式让行内元素水平垂直居中于容器,但是发现完全不起作用2️⃣ 我引入了一张图片,但是发现图片永远无法和背景下边缘对齐很多时候因为影响很小,我可能会忽略这些问题,或者换其他我更熟悉的方式来实现预期效果,但是当我想更深入的了解css时,这些就是绕不开的难点,下面做个简单的笔记分享一下。
2024-04-29 18:36:54
1046
原创 Typescript 基本使用
你可能会想到使用 object,但是object的检查太宽泛了,你甚至可以给object类型的变量传递一个函数, 通常,我们使用以下的方法1. 使用类型索引} = {a:1,B:2,c:3,[P :string] 为类型索引,表示属性值可以是任何字符串类型,value为any,表示值可以是任何类型2. 使用Recorda:1,B:2,c:3,Record 如上方式也可以定义一个任意类型的对象如果想要求obj中必须包含一些属性,可以使用} = {
2024-02-06 17:47:39
996
原创 JavaScript 操作符总结
这篇主要说三类操作符的使用,分别是 判等操作符 比较操作符 运算符,建议先看一下我的上一篇保证你对js中类型的转换有充分的了解。开篇先说一下在学习操作符和类型转换中get到的一些体会 "请不要 相信直觉!" 了解清楚每个操作符的运算比较流程,而不要凭借"语感"来作出判断!
2024-01-23 23:44:11
1148
1
原创 JavaScript 类型转换全面总结
Js中的类型转换一般分为 显示类型转换 和 隐式类型转换显式类型转换: 使用包装函数如 Number String Boolean 等对类型进行转换 如Number('3') = 3隐式类型转换: 不实用包装函数,动态转换。在运算符两侧类型不同的时候,会先进行隐式转换,再进行运算。如 '1'+0 = '10' [0 转换成字符串'0' 再做运算] false+10=10 [false转换成数字0 再做运算]下面具体来看类型之间的相互转换规则!
2024-01-23 18:01:20
1649
1
原创 Javascript执行&作用域全面总结
只要在当前作用域的var都收集 如下,由于没有块作用域这个概念,所以if块中的var a也属于全局作用域。
2024-01-11 19:12:40
1038
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人