自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(284)
  • 收藏
  • 关注

原创 react源码debugger-各种fiber的completeWork阶段

原生div p标签等的bieginWorkclass DD extends Component { render() { return <div>123</div>; }}上面调式了DD类组件的fiber,接着看类组件返回的子fiber,div标签的fiber是怎样的。对于原生html的fiber,fiber.tag是5export const HostComponent = 5; //原生标签hostComponent的fiber{altern

2022-04-10 23:16:59 291

原创 从零实现XMLhttpRequest

HTTP/IPHTTP/IP协议被称为传输控制协议/互联网协议,又称为网络通讯协议创建服务器const http = require("http");const fs = require("fs");const path = require("path");const { Buffer } = require("buffer");const url = require("url");const server = http.createServer((req, res) => {

2022-04-10 16:22:43 3433 2

原创 Reflect,IOC,DI

ReflectReflect对象与proxy对象一样,也是ES6为了操作对象而提供的新的API。JS的装饰器更多的是存在于对函数或者属性进行一些操作,比如修改他们的值,代理变量,自动绑定this等功能。但是却无法实现通过反射来获取究竟有哪些装饰器添加到这个类/方法上,Reflect Metadata就是做这个事情的。Reflect Metadata可以通过装饰器给类添加一些自定义的信息然后通过反射将这些信息提取出来。import "reflect-metadata";const

2022-04-07 10:37:02 400

原创 react源码解析-debugger阶段-类组件mount阶段的beginWork

类组件的beginWork。Appfiber执行完递阶段之后,轮到DDfiber执行递解端。对于类组件,在beginWork的时候,会调用updateClassComponent方法。类组件的fiber如:{alternate: nullchild: nullelementType: ƒ DD()key: nulllanes: 16mode: 1pendingProps: {}ref: nullreturn: FiberNode {tag: 0, key: null, stateN

2022-04-05 20:15:00 1130

原创 编译原理2-语法分析-支持减除小括号

语法分析-支持减法除法小括号语法规则 加上减法除法规则就变了add -> minus | minus + add // 加法被 减法 | 减法+加法替换minus -> multiple | mulitple +|- add 减法被 乘法 或者 乘法加减加法multiple -> primary | primary *|/ multiple 乘法 被 Number 或者 Number 乘除 乘法primary -> NUMBER | (add) primar

2022-04-01 23:11:32 414

原创 ast编译原理-2-语法分析-简单的加乘分析

经过上一篇,通过有限状态机的概念编写了tokenzier,实现了简单的jsx语法分词。接着需要进行语法分析阶段。语法分析了解语法分析的原理和递归下降算法递归下降算法

2022-03-31 23:52:05 814

原创 react18初识

react18以于2020年3月29日发布正式版本。变更日志看看怎么使用react18。启动react18只支持并发模式,也就是不支持ReactDOM.render启动项目需要这样启动ReactDOM.createRoot( document.getElementById('root')).render(<App/>)批量更新在Councurrent模式中,更新是以优先级为依据进行合并的。18之前的批量更新,setTimeout或者Promise.then的更新,react无

2022-03-30 23:51:36 1809

原创 ast编译原理-1-词法分析

编译原理实现jsx语法转成js语法的编译器。如将<h1 id=“title”><span>hello</span>world</h1>转成React.createElement("h1", {id: title}, React.createElement("span", null, hello),"world")步骤差不多就是,jsx代码->ast -> 处理转换ast -> ast生成js代码 -> js代码

2022-03-29 23:43:56 2353

原创 vite实战

Pnpm很好的文章pnpm相对比npm和yarn有很大速度的提升。因为:对于每个项目的依赖,yanr和npm会根据package.json每次都去下载依赖,导致项目越多,依赖就代码就越多。而对于pnpm,他会通过hard link的模式,在计算机的虚拟硬盘目录下创建一个store目录,将依赖存放到里面去,下次另一个项目需要某些依赖的时候,pnpm会直接来这store目录获取到代码,就不用重复下载。对于版本不同的依赖,版本之间不同的文件会被存储起来。例子:在项目中安装express依赖。在项

2022-03-28 22:00:14 742

原创 浏览器渲染原理

进程当启动一个程序时,操作系统会为该程序分配内存,用来存放代码,运行过程中的数据,这样的环境叫做进程。一个进程可以启动和管理多个线程,线程之间可以共享进行数据,任何一个线程出错,都可能导致进程崩溃。Chrome的进程架构浏览器进程: 负责界面显示,用户交互,子进程管理,提供存储等渲染进程:排版引擎和V8引擎主要运行在该进程中,负责把html, css, js转变成网页等等。网络进程:主要处理网络资源加载(HTML, CSS ,JS等)GPU进程:3d绘制,提高性能。插件进程:chrom

2022-03-28 19:37:47 1563 3

原创 react源码解析-debugger阶段-函数组件App的beginWork阶段

各种类型fiber的beginWork函数组件的beginWork接第一章,我们走完了createRoot到rootFiber执行完beginWork阶段,workInprogress.child也就是App函数的fiber被创建完毕之后的阶段。rootFiber执行完递阶段之后,返回了App fiber,将App fiber赋值给workINprogress.当performUnitOfWork执行完毕之后,当前浏览器无多余时间,等待下次调度执行performConcurrentWorkOnRo

2022-03-27 18:00:37 1460

原创 rollup打包工具

Rollupwebpack的打包比较繁琐,打包体积比较大。rollup主要是用来打包js库的。vue/react等都在用rollup作为打包工具。使用安装依赖yarn add @babel/core @babel/preset-env @rollup/plugin-commonjs @rollup/plugin-node-resolve @rollup/plugin-typescript loadsh rollup rollup-plugin-babel postcss rollup-plu

2022-03-27 14:16:13 3217

原创 webpack模块联邦

模块联邦weback的模块联邦原理和import()相似,也是promise的原理。,通过webpackjsonp加载异步代码,只不过,获取异步代码变成发请求去其他项目获取代码而已。动机模块联邦得动机是为了不同开发小组间开发一个或者多个应用。应用将被划分为更小的应用快,一个应用快,可以是比如头部导航或者侧边栏得前端组件。也可以是数据获取逻辑得逻辑组件每隔应用块由不同得组开发应用或应用块共享其他应用块或库。过程每个应用亏块都是一个独立得构建,这些构建都将编译成容器。容器可以被其他应用或

2022-03-26 23:01:32 2558

原创 前端可视化游戏基础

初识canvas绘制三角形useEffect(()=>{ if(canvasRef.current){ const ctx = canvasRef.current.getContext('2d') // 定位开始点 ctx?.moveTo(30, 30) //拖动,从第一个点移动到第二个点,只是描绘路径,(保存内存当中),还没上色。 ctx?.lineTo(30, 90) ctx?.lineTo(

2022-03-15 08:44:27 218

原创 react源码-debuger解析- createRoot阶段1

看懂这个之后https://react.iamkasong.com开始debugger源码CreateRootReactDOM.createRoot(document.getElementById(''))craeteRoot主要调用了createContainer创建rootFiber和FiberRoot,并且将它们联系起来。createContainer```调用了```createFiberRootconst root: FiberRoot = new FiberRootNode(...)

2022-03-13 22:14:55 2047

原创 react性能优化-懒加载原理

编译阶段的优化开发阶段构建更快loader的include和exclude属性 { test: /.(j|t)sx?$/, use: [ { loader: "thread-loader", }, { loader: "babel-loader", options: { presets: [

2022-03-11 08:39:23 2462

原创 react-debugger-1

整体流程图概览从ReactDOM.createRoot到beginWorkcreateRoot会创建FiberRoot和rootFiber,并且初始化fiber.updateQueue然后到了render从render开始,创建update,插入updateQueue,开始调度,判断是否同步,执行对应的performSyncWorkOnRoot/performConcurrentWorkOnRoot开启render阶段。ReactDOM.render到render阶段的流程同样的场景Fi

2022-03-06 17:52:23 471

原创 react源码学习-实现篇-优先级

优先级什么是优先级生命周期方法:同步执行。受控的用户输入:比如输入框内输入文字,同步执行。交互事件:比如动画,高优先级执行。其他:比如数据请求,低优先级执行。如何调度优先级Schedule提供了runWithPriority方法,接受一个优先级常量和一个回调函数作为参数。回调函数会以优先级高低为顺序排列在一个定时器中并在合适的时间触发。Schedule对优先级的定义,值越低优先级越高。下面可以通过一个demo来了解Schedule的流程。[一文搞懂调度Schedule][

2022-03-06 11:07:07 504

原创 react源码学习-实习篇-状态更新

实现篇-状态更新状态更新的流程-几个关键节点先了解几个关键函数的调用,看看常见触发状态更新的方法是如何工作的。render阶段的开始之前就了解归,render阶段开始于performSyncWorkOnRoot/performConcurrentWorkOnRoot,他们会执行对应的performUnitOfWork方法。commit阶段的开始commit阶段开始于commitRoot方法的调用,rootFiber作为传参。render阶段完成后会进入commit阶段。那么从触发状态更新,到r

2022-03-06 11:05:39 1556

原创 react源码学习-实现篇-useEffect

useEffect在commit阶段的before-mutation阶段之前,会使用scheduleCallback调度useEffect。可以看到useEffect的优先级是普通优先级。flushPassiveEffectsImpl主要做三件事,1 调用改useEffect在上一次render时的销毁函数; 2 调用该useEffect在本次render的回调函数。 3 存在同步任务的话,就执行他,不需要等到下次事件循环的宏任务。1 调用useEffect的销毁函数。commitPassi

2022-03-06 11:00:36 1124

原创 react源码学习-实现篇-hooks

极简hooks实现通过下面demo可以知道react中hooks的执行流程。极简hooks实现通过demo我们知道,mount的时候,每个hooks会创建一个hooks对象,而hooks的状态就存放在hooks对象上,多个hooks对象以链表形式存放在fiber节点上,每次hooks状态更新,会生成update。update会放在hooks.queue.pending上,形成环状链表。重新执行函数组件,即重新执行如useState函数,这时候是update,从fiber上获取hooks对象,会获取ho

2022-03-06 10:56:58 830

原创 react源码学习-基类篇

基础篇createElememntjsx会被babel编译成React.createElement最终返回一个虚拟dom,$$typeof用来标识是一个react元素。ComponentComponent是React的基类,来看怎么实现的。如图,简单的几句代码而已,因为主要的实现在不同的平台自己实现,Component只是作为一个基础的类。这里需要注意有一个每个Component实例上有一个updater,不同的平台实现有不同的实现。类组件通过在prototype上标明isReact

2022-03-06 10:51:32 265

原创 react源码学习-架构篇-commit阶段

commit阶段在rootFiber.firstEffect上保存了一条需要执行副作用的Fiber节点的单向链表effectList,这些Fiber节点的updateQueue中保存了变化的props。这些副作用对应的dom操作在commit阶段执行,除此之外,一些生命周期钩子如componentDidXXX,useEffect需要在commit阶段执行。commie阶段开始于commitRoot函数commit阶段的工作主要分为三个部分:before mutation阶段(执行DOM操作前)

2022-03-06 10:48:35 986 3

原创 react源码学习-架构篇-render阶段

架构Reconciler工作的阶段属于render阶段,Renderer工作的阶段属于commit阶段。render与commit阶段统称为work,即React在工作中。相对应的,如果任务正在Scheduler内调度,就不属于work。render阶段分为递归两个阶段。render阶段的开始render阶段开始于performSyncWorkOnRoot/performConcurrentWorkOnRoot,主要区别是本次是同步(ReactDOM.render)还是异步更新(ReactDOM.

2022-03-06 10:43:11 366

原创 react源码学习之-理念篇

theme: nico理念篇快速响应的瓶颈之一就是cpu限制,浏览器的js线程与gui渲染线程互斥,一旦js执行过长,就会导致卡顿。解决这个问题的关键就是:在浏览器每一帧的时间中,预留一些时间给JS线程,React利用这部分时间更新组件解决CPU瓶颈的关键是实现时间切片,而时间切片的关键是:将同步的更新变为可中断的异步更新。瓶颈之二就是IO的瓶颈: React实现了[Suspense ]功能及配套的hook——useDeferredValue为了支持这些特性,同样需要将同步的更新变为可中断.

2022-03-06 10:34:50 148

原创 axios实现

类型定义 import { AxopsInterceptroManager } from './AxiosINterceptoManager' interface AxiosInstace<T = any> { // request方法 (config: AxiosRequestConfig):Promise<AxiosResponse<T>> //T是resolve(v)的v值的定义, interceptors: { re

2022-03-05 21:16:31 679

原创 前端自动化测试-BDD-集成测试

何为BDD(Behavior Driven Development)行为驱动的开发,是一种敏捷软件开发的技术,他鼓励软件项目中的开发者,QA和非技术人员或商业参与者之间的协作。以上节TDD的代码为例子,将测试文件全部删除。从BDD的角度出发,开发人员不需要先写测试用例,直接编写代码即可。编写完代码之后,第二步就是需要站在用户的角度,怎么去测试,测试的重点是什么?从用户的行为角度出发,编写我们的测试用例。因为用户行为是连续的,比如toDOList案例,用户希望在输入框输入内容按下回车后,l

2022-03-05 14:07:13 1275

原创 前端-自动化测试react项目-TDD

TDD何为tdd (测试驱动的开发)流程: 1 编写测试用例 2 运行测试,测试用力无法通过测试 3 编写代码,使测试用例通过测试 4 优化代码,完成开发。 5 新增功能,重复以上步骤。以测试为驱动流程的开发好处: 1 长期减少回归bug 2 代码指令更好(组织,可维护性) 3 测试覆盖率高 4 错误测试代码不高基本环境配置脚手架create-react-app已经内置了jest。自己搭配的项目需要安装,yarn add jest ts-jest babel-jest @type

2022-03-05 10:03:36 924

原创 前端二进制-实战

二进制对象ArrayBufferTypedArrayDataViewBlobObject UrlArrayBufferArrayBuffer对象用来表示通用的,固定长度的原始二进制缓冲区。他是一个字节数组,通常在其它语言中称为byte array不能直接操作ArrayBuffer的内容,而是要通过类型数组对象(TypedArray)或者DataView对象来操作。他们会将缓区中的数据表示为特定的格式,并通过这些格式来读取内容。const buffer = new ArrayBuffe

2022-03-04 21:38:50 417

原创 前端二进制

计算机中的数值表示进位计数值:基数R+位权w基数RR代表基本数码的个数,二进制就是0和1这2个数。R进制的主要特点是逢R进1.

2022-03-03 22:59:59 414

原创 xss,csrf,xsrf

Xss跨站脚本攻击(Cross Site Scripting)原理: HTML是一种超文本标记语言,通过将一些字符特殊地对待来区别文本和标记,例如,小于符号(<)被看作是HTML标签的开始,与之间的字符是页面的标题等等。当动态页面中插入的内容含有这些特殊字符(如<)时,用户浏览器会将其误认为是插入了HTML标签,当这些HTML标签引入了一段JavaScript脚本时,这些脚本程序就将会在用户浏览器中执行所以,当这些特殊字符不能被动态页面检查或检查出现失误时,就将会产生XSS漏洞。案例

2022-03-03 08:48:54 462

原创 V8引擎学习

计算机模型寄存器中央处理器的组成部分寄存器是有限存储容量额高速存储部件可以用来暂存指令,数据和地址存储器内的数据可以用来执行算术和逻辑运算。寄存器内的地址可用于指向内存的某个位置内存随机存取存储器也叫内存,英文缩写RAMRAM是与CPU直接交换数据的内部存储器RAM工作时可以从任何一个指定地址写入或者读出信息RAM在计算机中用来暂时存储程序,数据和中间结果。32位操作系统支持的内存最多为2的32次方,也就是4g。0x00000001 => … => 0xF

2022-03-03 08:41:03 1736

原创 前端优化策略

网络优化策略减少http请求,合并js,css,合理内嵌css,js。合理设置服务端缓存,提高服务器处理速度// 强缓存 Cache-Control/Expires 协商缓存 服务器设置Etag/Last-Modified,请求携带验证体:if-none-match/if-modified-since(304)避免重定向,重定向会降低响应速度(301, 302)使用dns-prefetch,进行dns预解析采用域名分片技术,将资源放到不同的域名之中,解决同一个域名最多处

2022-02-24 09:20:43 796

原创 浏览器渲染原理 1

进程与线程进程是操作系统资源分配的基本单位,进程种包含线程。线程是由进程所管理的,为了提升浏览器的稳定性和安全性,浏览器采用了多进程模型。浏览器进程: 负责界面显示,用户交互,子进程管理,提供存储等渲染进程:每个页面都有单独的渲染进程,核心用于渲染页面网络进程:主要处理网络资源加载(HTML, CSS ,JS等)GPU进程:3d绘制,提高性能。插件进程:chrome种安装的一些插件。从输入url到浏览器显示,发生了什么?从浏览器进程看:输入url或者关键字。如果是关键字,根据

2022-02-24 09:18:45 784

原创 入门前端自动化测试-jest-基础

jest基础jest官网匹配器 命令行工具测试异步钩子函数mock快照dom匹配器jest默认环境是node如果想在jest环境使用esmodule,需要借助@babel/core转化工具, @babel/preset-env指明如何转化{ "presets": [ [ "@babel/preset-env", { "targets": {

2022-02-15 23:10:48 5394

原创 typescript 高级

1 类型推断从右向左流动:// let a: number 类型从右向左流动 let a = 1;通过return关键字推断返回值的类型 底部流出 function add(a: number) { return a; }从左向右: //从左向右 type S = (a: number) => void; const s: S = (a) => { // parameter) a: number console.log(a); };

2022-02-09 13:49:42 936

原创 typescript 基础

基础ts1 普通枚举enum Gender { GIRL = "d", BOY = "e",}console.log(Gender.GIRL);编译成 var Gender;(function (Gender) { Gender[Gender["GIRL"] = 'd'] = "GIRL"; // Gender[d] = GIRL Gender['GIRL'] = 'd'(默认是0) Gender[Gender["BOY"] = 'e'] = "BOY";}

2022-02-09 13:48:43 884

原创 一文搞懂react的Schedule调度系统

Schedulereact有一套基于Fiber架构的调度系统,这套调度系统的基本功能包括:1 更新具有不同的优先级2 一次根因可能涉及多个组件的render,这些render可能分配到多个宏任务中执行(即时间切片)3 搞优先级更新打断低优先级更新实现第一版的调度系统,如图:(图借于魔术师卡颂)可以看到是同步的,workList存放所有的work,然后schedule取出后,给perform执行,执行完后继续执行schdeule,递归直到所有work执行完毕。// 用work

2022-02-08 19:27:49 1417 1

原创 自顶而下学习react源码 (3)架构篇 commit阶段

commit阶段在rootFiber.firstEffect上保存了一条需要执行副作用的Fiber节点的单向链表effectList,这些Fiber节点的updateQueue中保存了变化的props。这些副作用对应的dom操作在commit阶段执行,除此之外,一些生命周期钩子如componentDidXXX,useEffect需要在commit阶段执行。commit阶段的工作主要分为三个部分:before mutation阶段(执行DOM操作前)mutation阶段(执行DOM操作)layou

2022-02-08 14:35:22 684

原创 极简hooks实现,与react的思路一样的useState

使用App函数模拟根组件 function App() { const [num, updateNum] = useState(0); console.log(`${isMount ? "mount" : "update"} num: `, num); button.textContent = num; return { click() { updateNum((num) => num +

2022-02-03 23:33:26 1679

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除