React系列:第十二回(调和过程和diff)
本文介绍react的调和过程和diff算法所谓的调和,本质是将虚拟节点转换为真是dom的过程
React15栈调和机制下diff的核心逻辑先看下图的两个节点:
先对比连个根节点,是否为同一个元素,判断依据标签名和key。若是同一节点,更新各个属性,进入子节点的diff,若不是,简单粗暴,删除旧节点,根据新结点的虚拟dom挨个创建。
进入子节点的对比后,从头至尾依次对比。旧节点所有子节点从左到右一次同新虚拟dom的子节点对比。判断是否为同一节点,是则更新相关属性下一个。不是,删除旧节点。图中依次是B、D、E,到D时,发现不同,删除D创建C。到E时发现不同删除E创建D。
最后因为新节点还有一个E剩余,创建之。完毕。注意:react15的栈调和是深度优先遍历的。倘若D有子组件,那么会继续往下走,最后再往回冒。
上述过程存在的一个问题,新节点中明明也有D、E,但是我们还是经过了删除、创建,明显浪费。此时,就祭出了我们的key.
key属性帮助react记住节点。D、E只需要执行插入即可
The Method Of Learning
The Study Method That Works For Technical Subjects
Step 1 - Preparation: Find an authoritative reference book that covers most of the fundamentals, and skim through the whole book quickly
Step 2: Locate a reliable mentor, work through the entire course, and correct misunderstandings. Pay extreme attention to hands-on practice
Step 3: Take a comprehensive test to verify you truly understand what you learned
Step 4: Focus on misunderstanding points, practice repeatedly through hands-on exercisesOv ...
第一回:开宗明义的聊聊
本文简单聊聊“整洁代码”的几个点究竟什么样的代码才是高质量可维护的代码(没有味道的代码)?什么样的组件才能叫作好的组件?函数怎么写才是干净、高效、得体的?瓦卡利马僧。但是,本文中我们尝试着去瓦卡利。
组件化编程随着业务量代码的积累,自己突然感觉有点力不从心:代码太容易成为“屎山”了。就拿目前项目的一个场景举例:写一个创建任务的表单组件。听起来很简单是吧?是很简单,但写起来,极度费劲。原因在于,该创建表单项过多,且伴随着各种联动需求。一开始愣头愣脑的上去就是干。写到一半,发现已经写不下去了—->该文件已经超过了 1000 行,变量无数,单单 flag 就十几二十来个,如若再这么写下去,我估计即使勉强实现了需求,后面接手的人都会顺着网线来砍我。此时,我的心情是崩溃且尴尬的。你能够想象,在一个单文件代码超过1000 行游走是什么感觉吗?望着这座自己亲手堆砌的半坐“屎山“,觉得自己有义务寻求一些解决方案,免得被后人耻笑。简单的讲就是一个字:拆。在《重构》这本书的指导下,疯狂拆分这座屎山,当然,这个过程也是无偿加班的过程。最终单文件代码量干到了 300 来行,虽然被拆出去的儿子组件的可复用 ...
vue3备忘录:同前代的优化
优化总结
为了更好支持ts,类型检查,类型推导
优化代码可读性、可维护性(composition API 取代options API)
优化代码可复用性。vue2使用mixin去复用代码逻辑存在俩问题:命名冲突、数据来源不清晰。vue3抄了一把react,也用了hook的方式去复用代码
打包速度更快
diff算法优化。
响应式系统优化。通过proxy解决俩问题:新增删除的数据监听问题。2.对象嵌套过深引起的性能问题.需要注意的是,使用proxy代理整个对象的前提是该对象非嵌套,如果是嵌套的,需要在get再加一层代理逻辑
treeshaking。实际就是删除无用代码
SEO相关手段
目下前端SEO三大核心手段语义化 HTML(让爬虫识别内容结构)用语义标签替代无意义 div,明确内容层级,提升爬虫解析效率。
<h1>2025战国策略手游 - 官方首页</h1> <!-- 唯一h1,定义页面核心主题 -->
<main> <!-- 核心内容区 -->
<article>
<h2>游戏核心玩法:战国七雄争霸</h2>
</article>
</main>
Meta 标签精准配置(提升搜索结果相关性)title/description 含核心关键词,控制字符长度,直接影响搜索展示。
<title>战国策略手游 - 还原真实历史 | 2025公测</title> <!-- 60字符内 -->
<meta name="description" content="战国策略手游主打真实历史还原,招募名将、攻城略地,2025年全平台公测!"> <!-- 120字符内 -->
JS 渲染适配(解决 SPA 爬虫抓取问题)SPA 页面需让爬虫获取完整内容,避免空页面抓取。如果 ...
博弈论概论
多年前导师的博弈论,最近想着重温记录下来,便有此文。博弈论的核心,是掌握「策略化思考」的底层逻辑—— 从 “只算自己的最优解”,变成 预判他人选择、再选自己最优解。
经典场景案例有两个嫌疑犯 A 和 B,被警察抓住,关在不同房间审讯。警察告诉他们:
A的选择 \ B的选择
沉默
招供
沉默
(1,1)
(5,0)
招供
(0,5)
(3,3)
用收益表表示(数字越小越好,因为是刑期)。
方案:纳什均衡没有任何一个参与者可以通过单独改变自己的策略来提高收益,它只要求 “稳定”,不要求 “最好”。对于A而言,若B沉默,A的最优解时选择招,不用坐牢,若B招供,A的最优解还是选择招,只判三年。针对B也是一样。所以,此处的纳什均衡,就是(3,3)。但是很明显都沉默才是集体的最优解。个体理性 → 导致集体最差结果(纳什均衡),但集体最优结果却不稳定(不是纳什均衡)。
canvas离屏渲染详解
本文通过实例介绍下,针对canvas,如何通过离屏渲染做性能优化业务场景某些场景下,我们需要在canvas进行诸多的绘制渲染的操作,当渲染量达到一定程度时,例如绘制的图形个数巨大,渲染耗时大到页面处于暂时性卡死,该如何破?离屏渲染
实现思路在主线程中,通过transferControlToOffscreen,将渲染的工作给到worker处理,以此规避卡死主线程的目的。
演示react核心代码
const drawCanvasOne = () => {
if (!canvasOneRef.current || !canvasTwoRef.current) return
const canvas:HTMLCanvasElement = canvasOneRef.current
const ctx = canvas.getContext('2d');
if (!ctx) return
let frameCount = 0;
const render = () => {
frameCount++;
...
基于opensumi的编辑器问题
本文简单整理下,公司编辑器项目遇到的坑,及对应的解决方案这段时间在整公司的一个web3的编辑器,基于opensumi开发的,主要是支持编写各种合约语言然后编译、部署的一整套流程。总结下过程中遇到的问题。
性能问题这是绝对的大头。比如一个文件10MB+,用户需要编辑,但是用 OpenSumi 打开后,就会出现明显的卡顿(输入文字时光标滞后 0.5-1 秒)、滚动不流畅,甚至偶尔白屏。方案:
Monaco Editor 层优化
开启「增量渲染」:设置 editor.maxTokenizationLineLength = 500(超过 500 行的文件仅渲染可视区域,滚动时再渲染其他区域);
禁用大文件语法高亮:通过 OpenSumi 的 IEditorService 扩展,判断文件大小 > 5MB 时,自动切换为「纯文本模式」,关闭语法高亮和代码补全;
OpenSumi层 文件缓存策略优化重写 IFileService 的 readFile 方法,大文件采用「流式读取」(createReadStream),而非一次性读取全量内容,类似视频流。
自定义插件与第三方插件加载顺 ...
Webkit系列:第二回(HTML解释器和DOM模型)
本文将尽可能的解释Webkit的HTML解释器流程及Dom模型相关的知识点在前文介绍从输入url到页面的最终呈现的过程,其中有一步:渲染器进程获取到资源后会将html资源给到html解释器,用来生成dom节点最终生成dom树形结构的对象。那么html解释器具体做了啥呢?
总体流程:字节流被解码成字符流,字符流通过词法分析器被解释成词语,词语通过语法分析器构建成节点,最后节点组合成dom树。
1. 字节 —> 字符收到字节流之后,解释器会根据网页内容所使用的编码格式,将字节流解析成对应的字符串。如果没有特别指定编码格式,直接进入下一步的词法分析。
2. 字符 —> 词语HTMLTokenizerHTMLTokenizer类负责词法解析。输入字符串,输出是一个个的词语。解释完成的词语会经过XSSAuditor安全验证,干嘛的呢?实质就是将一些可能会导致安全问题的词语过滤掉。只有通过安全验证的词语,才会继续下一步。
3. 词语 —> 节点HTMLTreebuilder类的construcTree由词语创建节点过程中,坑会遇到js代码。这就是为什么全局执行的js无法访问dom ...
