Mindblown: a blog about philosophy.
-
JS底层原理之浏览器原理
Chromium是目前使用最广泛,功能最强大的浏览器内核,广泛使用在Chrome, Edge等浏览器中。除此之外还有Firefox的Gecko, Safari的webkit。 浏览器内核中最重要的部分就是渲染引擎了。 Chromium实际上一种浏览器的架构,实际上Chrome使用的内核叫做Blink,他是Google基于Webkit开发的一套新的内核。Blink负责渲染真个渲染管道,包括DOM树、样式、事件、和V8集成。它解析DOM树,渲染样式,确定所有元素的视觉几何位置。也就是说浏览器引擎在渲染页面时会调用我们的javascript引擎将javascript编译成本地机器代码并执行,及Blink会调用v8引擎去解析js。 同理Safari的js引擎是JavascriptCore, Firefox的是SpiderMonkey。 V8引擎 接下来就要介绍一下今天的主角V8引擎了。 V8引擎做的第一件事是先下载源代码,可以通过网络、缓存或service workers来完成。 收到代码之后就是解析了,V8引擎会通过解析器识别并创建一个抽象语法书(AST),树上的每个节点都表示代码中的一个结构。类似于虚拟DOM树。 Ignition模块,是引擎的解释器,他可以将AST转换成ByteCode字节码,字节码是0和1组成的二进制文件,也就是计算机可以识别的机器语言。 TurboFan模块,一个编译器,可以将字节码编译为CPU认识的机器码。 一个完整的Javascript引擎的执行过程大概包括: 源代码 -> 抽象语法书 -> 字节码 -> JIT(即时编译) -> 本地代码
-
JS底层原理之调用栈
先回顾一下计算机中的两个重要原理,栈和队列 栈(Stack), 栈的特点就是先进后出,可以想象成一个竖置的瓶子,先入栈的会进入到最底部,所以出来的时候只能排在最后的位置 队列(Queue), 队列的特点就是先进先出,可以想象成一个管子,管子两侧分别对应进入和离开, 所以先进来的也会第一个出来。 调用栈: 调用栈是js引擎追踪函数执行流程的一种机制,当执行环境中调用了多个函数时,通过这种机制,我们能追踪到哪个函数正在执行,执行的函数体又调用了哪个函数。 简单举例 从脚本开始执行起 调用栈溢出 调用栈溢出是指当前调用栈没有剩余空间了,通常是发生在递归函数没有明确的结束条件时,因此会抛出调用栈超出执行范围的异常 调用栈调试 在源代码(source)这里我们可以通过添加断点来查看当前函数执行的调用栈等信息,从而帮助我们更快速的解决问题
-
Nodejs 之 异常的处理和记录
异常的处理 对于异常的在promise中我们通常用catch, 在async/await中我们通常用try…catch…, 这造成的问题是代码冗余,处理相同的错误我们也要在不同的位置多次修改,因此在express中我们可以使用自定义中间件来创造一个错误处理中间件,例 这样就批量完成了错误的处理。 但这个方法的缺点是在api这里要调用asyncMiddlware这个方法。 更简单的方法当然是使用npm包啦,就是express-async-errors, 导入之后就会自动处理异步请求了 异常的记录 winston 是一个常用的错误记录库。 winston中一个重要的名词是transport, 其实就是数据的存储,他可以存储到本地的文件中,存储到数据库中,或者通过http存储到其他数据平台。 winston中记录的错误可以分为不同的错误等级 { error: 0, warn: 1, info: 2, http: 3, verbose: 4, debug: 5, silly: 6 } 如果没有指定错误等级,winston会默认按照上面的错误等级
-
Prisma系列课程 – 1
Prisma 简介 简单来说Prisma是一款数据库连接工具,他包含以下三部分: Prisma client可以使用在nodejs或typescript应用中,例如expressjs或nextjs等, 并且支持Rest API和GraphQL API。 Prisma Schema 是prisma的数据库模型文件,里面包含生成器generator, 数据库连接信息datasource,以及数据模型model。下面主要介绍一下模型,model。 Model prisma schema文件中通常包含多个model,model主要有两种用途 生成model既可以手动编写,也可以从已有的数据库中反向生成。 另外每次更新schema之后需要执行prisma generate更新连接, prisma也根据schema的不同生成方式有两种不同的标准工作流: Prisma Migrate: 数据库迁移
-
React 性能优化
useCallback 场景一: 避免子组件的重复渲染 当我们需要从子组件传递消息时,通常使用的是由父组件传递方法给子组件,子组件调用方法时将消息当做参数传递给这个方法。 但在有些情况我们想在重新渲染父组件时并不需要重新渲染这个子组件(子组件渲染很耗时),就可以用到useCallback+memo的组合了,(memo是一个包裹组件的的api,在组件接收的prop不变时,父组件重新渲染不会触发该组件的重新渲染) 场景二: 当方法需要在useEffect中调用时 因为需要添加到dependency list中,如果每次都重新初始化的话会导致useEffect每次都重新调用,因此可以将方法用useCallback包裹起来 场景三: 优化自定义hooks React建议在自定义的钩子中,所有返回的函数都用useCallback包裹 这能确保在使用这个自定义hook的时候,可以做一些性能上的优化,参照场景一二 useDeferredValue vs Suspense useDeferredValue是一个推迟渲染的钩子,他是使React先用useDeferredValue传入的更新之前的值先渲染一次,如果值有更新的话再用更新后的值再渲染一次。通常和useState共同使用 首次渲染时,deferred value就是传入的默认值更新渲染时,react会先不更新deferred value用旧的值先渲染一次,再用更新后的值再渲染一次。注意这个再次更新是可打断的,如果再次更新deferred value,react会打断这个渲染,而使用新的数据重新渲染,用户看到的始终都是原始的数据渲染的结果 另外再使用useDeferredValue,做性能优化时,需要和memo配合使用。 memo的作用是传入的prop没变化则不更新组件。
-
React Hooks 之 useReducer
useReducer 另外一个可以管理state的hook,常被用来处理复杂的state管理。在实际开发中,基本上普通类型的state,如number, boolean, string等直接使用useState就可以了,涉及到复杂的state一般用useReducer来管理。 useReducer接收两个参数,一个reducer函数,一个初始state,他会返回更新后的state和更新state的方法dispatch 注意事项:
-
three.js的响应式设计
three.js的物体是通过canvas渲染的,在不同的屏幕尺寸上我们通常需要改变canvas的大小来让场景显示完整。 回忆一下我们在配置相机时的代码 这里的aspect就是画布的宽高比,因此我们也需要动态调整这个aspect的值,才能让物体在屏幕拉伸时保持原来的形状 另外的一个问题是物体出现了块状化,即物体边缘出现锯齿。 这是因为canvas其实有两个尺寸,一个是显示尺寸,一个是分辨率尺寸。 我们改变了显示尺寸而分辨率尺寸并没有相应的跟随改变。 在three.js中我们有renderer.setSize来帮助改变canvas的分辨率尺寸(drawing buffer)
-
JS中异常的处理方式
今天回顾一下JS中处理异常的几种方式 onerror try…catch…finally throw抛出错误 用来抛出一个自定义的错误,试用的场景是语法没有错误,逻辑有错时,常与try…catch…一同使用
-
JS中的正则
正则算是编程中的一个强大的工具,经常被用做前端输入的校验,今天我们来详细归纳总结一下这个利器。 在JS中,常用的api是search()和replace()这两个方法 修饰符 修饰符 描述 i 执行对大小写不敏感的匹配。 g 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。 m 执行多行匹配。 方括号 表达式 描述 [abc] 查找方括号之间的任何字符。 [^abc] 查找任何不在方括号之间的字符。 [0-9] 查找任何从 0 至 9 的数字。 [a-z] 查找任何从小写 a 到小写 z 的字符。 [A-Z] 查找任何从大写 A 到大写 Z 的字符。 [A-z] 查找任何从大写 A 到小写 z 的字符。 [adgk] 查找给定集合内的任何字符。 [^adgk] 查找给定集合外的任何字符。 (red|blue|green) 查找任何指定的选项。 元字符 元字符 描述 . 查找单个字符,除了换行和行结束符。 \w 查找数字、字母及下划线。…
-

React18 新特性
React18提供了全新的创建根节点的方式: ReactDOM.createRoot(),用这个创建根节点可以开启React18的全新特性。如Concurrent模式等。 那么React18到底带来了哪些新的功能呢?我们一起来看一下。 Concurrent Rendering(并行渲染) 时间切片:在并行渲染的模式下,当更新任务无法在一帧之内完成时,任务会被切割为多个任务进行可中断的更新,以此来保证没帧都有多余的时间来进行渲染 更新优先级: 更新的任务会有优先级,更高优先级的任务会打断当前执行的任务先进行处理,处理之后再恢复执行原来的任务。 startTransition & useTransition 设想一个长列表搜索的场景,当用户输入搜索时,需要按照条件渲染出长列表,这就会造成卡顿。 实际上这里有两次渲染,即输入框的渲染和列表的渲染。常规的解决办法是利用debounce防抖。 React现在提供了一个内置的方法,可以更好的处理这种问题 用startTransition包裹执行的任务会被标记为不紧急渲染,因此会被其他紧急的任务抢占先机 useTransition和startTransition的功能一样,使用方法 setState合并更新 在react18之前,setState是合并更新,在setTimeOut中是按同步顺序更新的 在react18之后,所有的setState都是合并更新的了 setState的队列 正常情况下我们在setState中传入的是state的值,但当我们传入的是方法的时候React就会按照队列的方式执行 这里的原则就是传入的是方法就会被添加到队列中去执行,而传入的是值就会替换原来的值 suspense suspense用于在组件渲染之前的等待期间显示Suspense的callback内容, suspense内的组件优先级会比其他组件的优先级更低
Got any book recommendations?
