-
前端状态机实践:用状态机管理复杂交互
一个上传组件里出现五个布尔标志不算稀奇: isLoading 、 isError 、 isSuccess 、 isPaused 、 isValidating 。每个标志单独看都合理,合在一起就埋下了隐患。 布尔标志的组合爆炸 $n$ 个独立的布尔标志,理论上能表示 $2^n$ 种组合。五个标志就是 32 种,而真正合法的 UI 状态可能只有 6 个:待选择、校验中、上传中、已暂停、成功、失败。 剩
林见川
-
Vue 3 响应式原理:Proxy 与依赖收集
Vue 3 把响应式底层从 Object.defineProperty 换成了 Proxy 。这个替换不只是换个 API,它顺带解决了一批历史遗留问题,也引入了新的边界情况。 Proxy 相比 defineProperty 强在哪 defineProperty 要拦截属性读写,就必须 对每个已知属性逐个定义 getter/setter 。这带来三个麻烦: 新增属性拦不到,必须调 Vue.set ;
江眠
-
现代 CSS 布局:Grid、Flex 与容器查询
布局能力的几次升级,方向是把"由 JS 计算尺寸"这件事逐步还给 CSS。掌握每种能力的适用边界,比记住语法重要。 一维与二维:Flex 与 Grid 的分工 Flex 是一维布局模型:沿主轴排列项目,能控制分布、对齐、伸缩,但不关心行与列是否对齐。Grid 是二维模型:同时定义行轨道和列轨道,项目直接落进单元格。 选择依据不是"哪个新用哪个",而是 你是否需要行列同时对齐 。 /* 工具栏:一维
North 北境
-
前端国际化工程:文案、时区与布局适配
把界面上的中文换成英文,只是国际化里最容易被看见、也最不麻烦的一块。真正消耗工期的,是那些换了语言之后行为会跟着变的东西。 翻译之外还有什么 一个看似简单的"订单已提交"提示,在不同地区要处理:金额用什么货币、小数点和小数位是否一致、日期是月/日还是日/月、数量是单数还是复数、句子里的时间是用户所在时区还是商家时区、这段文字从右往左排时布局会不会散架。 具体到实现层,需要拆成六个相对独立的子问题:
林见川
-
前端构建工具演进:Webpack、Vite 与 esbuild
构建工具的迭代方向很清晰:开发时尽可能少做工作,生产时尽可能多做优化。理解这条主线,就能看懂冷启动速度差异的来源。 bundle 与 no-bundle:dev server 的本质差异 传统打包式 dev server(Webpack Dev Server)的工作方式:启动时从入口开始遍历整个模块图,把所有模块合并成若干 bundle,存进内存,然后才能提供服务。改一个文件,它需要重新计算受影响
晚棠
-
浏览器渲染管线:从 HTML 到像素的每一步
页面上的一个像素要出现在屏幕上,中间要穿过解析、样式计算、布局、绘制、栅格化、合成这几道工序。搞清楚每道工序的输入输出,才能解释为什么改 width 卡而改 transform 不卡。 解析:字节流变成两棵树 HTML 解析器拿到的是字节流,先按编码( <meta charset> 、HTTP 头、BOM 推断)解码成字符,再交给分词器产出 token,最后组装成 DOM 节点。这个流式过程意味着
陈砚舟
-
WebAssembly 的真实用途与边界
WebAssembly 常被误解成"让网页变快的银弹"。它在特定场景确实有用,但用错地方反而更慢。搞清楚它是什么、代价在哪,判断力就有了。 WASM 是什么 WebAssembly 是一种 低层的、可移植的二进制指令格式 ,设计目标是作为高级语言的编译目标。它跑在一个基于栈的虚拟机里,有线性内存、有类型化的函数和局部变量。 几点必须厘清: 它 不是 JavaScript 的替代品,而是补充。WAS
叶南
-
前端测试策略:单测、组件测试与 E2E 的配比
测试金字塔给的经典配比是 70/20/10,但直接套到前端项目上会失真。理解失真在哪里,比记住一个数字重要。 金字塔在前端的现实形态 经典金字塔的两个前提在前端都不完全成立。 E2E 比后端的集成测试贵得多 。后端集成测试通常在进程内跑,而前端 E2E 要启动真实浏览器、加载完整应用、等待网络与渲染。单个用例的耗时量级从毫秒级跳到秒级,相差三个数量级。慢不只是等待时间的问题,它直接决定了反馈周期能
Vector 陈
-
React 状态管理演进:从 Redux 到原子化
状态管理方案的更替,主线其实只有一条: 订阅粒度从粗到细 。每一次范式变化都在解决"一个状态变化,到底要重渲染多少个组件"。 单向数据流与可预测性 React 的基本模型是 UI = f(state) 。状态存在组件树里,自上而下流动;用户事件从下往上触发状态更新,再重新渲染。这条单向路径带来的好处是可预测性:给定同样的状态树,渲染结果一定相同。 问题出在"状态放哪"。局部状态( useState
NullZone
-
微前端架构:qiankun、Module Federation 与 iframe
微前端是把后端微服务的组织思路搬到前端。它解决的是 组织问题 ,不是技术问题——这个定位决定了什么时候该用、什么时候不该用。 它真正解决什么 三个真实诉求: 独立部署 :A 团队改了订单页,不需要等 B 团队的发布窗口,也不需要整站回归; 技术栈异构 :老系统停在旧框架版本,新模块想用新版本或新框架,各自演进; 团队边界清晰 :代码库按业务域拆分,权限与责任对应得上。 反过来,下面这些情况 不该上
陈砚舟
-
前端性能监控:指标采集与异常上报
自己搭一套监控,难点不在"怎么发请求",而在 采集口径是否稳定、数据能否还原现场、上报是否影响性能本身 。这三件事决定了数据是资产还是噪音。 PerformanceObserver 采集要点 核心指标都通过 PerformanceObserver 拿,而不是 performance.timing (后者已被标记为废弃,且语义是导航时间点不是用户体验指标)。 function observe(typ
Maren
-
Core Web Vitals 优化:LCP、INP、CLS 的成因与手段
三个指标其实在回答三个不同问题:内容多久能看到(LCP)、操作多久有响应(INP)、页面视觉稳不稳(CLS)。它们各自的成因几乎不重叠,优化手段也必须分开谈。 三个指标各自衡量什么 LCP (Largest Contentful Paint):视口内最大内容元素(图片、视频封面、块级文本)的渲染时间。衡量"主要内容加载完成"的感知速度。 INP (Interaction to Next Paint
温言
-
TypeScript 类型体操:泛型、条件类型与映射类型
类型体操不是炫技。它真正的价值在于:把运行时的约束前移到编译期,让一批错误在写代码时就暴露。代价是可读性和编译时间,所以要懂得在哪里停手。 泛型约束与默认值 裸泛型 <T> 意味着"任何类型",等于放弃检查。约束让泛型带上前提: function getKey<T extends object, K extends keyof T>(obj: T, key: K): T[K] { return o
苏黎