两次 Wi-Fi 故障排查:DNS 无响应、AP 去认证与端口扫描告警

发表于 | 分类于 网络

先后遇到过两次表面相似的 Wi-Fi 故障:

  • 第一次是在酒店。Mac 显示 Wi-Fi 已连接,但网站无法访问,改用公共 DNS 后恢复。
  • 第二次是在公司。网络间歇性中断,系统日志同时出现 DNS 无响应、无线 AP 去认证和 DHCP 失效;公司的安全系统还把本机标记为端口扫描攻击来源。

两次问题都表现为“连着 Wi-Fi 但无法正常上网”,实际故障层次并不相同。第一次主要位于 DNS 解析链路;第二次同时涉及 DNS、无线链路和可能的网络安全策略。

AI编码的一些体会

发表于 | 分类于 杂项

从 2023 年开始,我每年都会写一篇与 AI 有关的文章,记录自己在当时阶段对 AI 的认识和实际使用感受。

2023 年的《初识 ChatGPT》主要是在了解 ChatGPT、AIGC 和大语言模型等基本概念;2024 年的《我对于 AIGC 的一些看法》讨论了 AIGC 的理解与创作能力,以及它可能带来的影响;2025 年的《一个 AI 独立完成的游戏自动化脚本》则记录了第一次让 AI 基本独立完成一个实际项目的过程。

到了今年,AI 已经从问答和辅助编码工具,逐渐变成可以持续读取项目、修改代码和执行任务的 Agent。这篇文章是这组年度记录的第四篇,关注点也从“AI 能不能写代码”转向了“人应该如何与 AI 一起完成工程开发”。

现在已经没有必要再质疑 AI 能不能参与实际开发了。至少在代码生成、局部修改、调研验证和问题排查等任务上,它已经具备明确的实用价值。

但 AI 能不能替代开发者,是我今年一直在思考的问题。

ENNotes on Coding with AI

发表于

Since 2023 I have written one article a year about AI, recording what I understood about it at the time and what actually using it felt like.

The 2023 piece was about getting acquainted with ChatGPT, AIGC and large language models. The 2024 piece discussed AIGC's comprehension and generative abilities and their likely consequences. The 2025 piece documented the first time I let an AI complete a real project largely on its own. (All three are in Chinese: 初识 ChatGPT, 我对于 AIGC 的一些看法, 一个 AI 独立完成的游戏自动化脚本.)

This year AI has moved from a question-answering and autocomplete tool to an agent that continuously reads a project, edits code and executes tasks. This is the fourth entry in that annual series, and the question has shifted from "can AI write code" to "how should a person work with AI to build software".

There is no longer any point in debating whether AI can participate in real development. For code generation, localised edits, research, verification and debugging, it has clear practical value.

Whether AI can replace developers is the question I have been sitting with all year.

VitePress博客从Valine迁移到Waline:部署、接入与数据迁移

发表于 | 分类于 博客

很久没看博客的留言了,最近登录一下,发现之前用的leancloud已经要停服了

决定来迁移一下,把相关的数据迁移到一个新的留言系统,经过调研,最终决定迁移到Valine。

本文涉及Waline 客户端、Vercel 服务端和 Neon PostgreSQL。内容从账号和项目创建开始,依次完成数据库初始化、VitePress 接入、LeanCloud 历史数据转换、导入校验和上线检查。即使没有历史数据,也可以只使用前半部分完成一个新的 Waline 评论系统。

基于 Puppeteer 与 Chrome Trace 的前端性能自动化测量工具

发表于 | 分类于 前端/前端工程

复杂前端应用的性能问题,往往不发生在首屏加载阶段,而是发生在页面已经运行之后:大批量数据进入、组件持续更新、列表滚动、图表刷新或用户连续操作时,页面开始出现 CPU 占用升高、内存增长、掉帧和响应变慢。

Chrome DevTools 很适合定位一次具体问题,但手工录制难以稳定复现相同场景,也不方便比较两个版本。要让性能评测可以重复执行,需要把浏览器启动、场景操作、性能采集、指标解析和结果对比串成一条自动化链路。

本文整理一种基于 Puppeteer、Chrome Trace Event 和 Chrome DevTools Protocol(下文简称 CDP)的实现思路,重点讨论工具的边界、模块设计和指标提取规则,不涉及任何具体业务代码。

ENAutomating Frontend Performance Measurement with Puppeteer and Chrome Trace

发表于

Performance problems in complex frontend applications usually do not happen during initial load. They happen after the page is already running: large data sets arrive, components keep updating, lists scroll, charts refresh, or a user performs a rapid sequence of actions — and CPU climbs, memory grows, frames drop, and interactions get slower.

Chrome DevTools is excellent for diagnosing one specific occurrence. It is a poor tool for reproducing the same scenario reliably, and a worse one for comparing two builds. Making performance evaluation repeatable means wiring browser launch, scenario steps, data collection, metric extraction and result comparison into a single automated chain.

This post describes an approach built on Puppeteer, Chrome Trace Events and the Chrome DevTools Protocol (CDP). The emphasis is on the tool's boundaries, its module design, and the exact extraction rules for each metric. There is no application-specific code here.

记一次图片缺少EOI导致的渲染异常

发表于 | 分类于 前端/前端工程

最近排查了一个图片预览切换偶发空白的问题,前前后后试了好几种前端方案都没修好,最后发现根因根本不在前端逻辑,而是一张JPEG缺少了EOI结束标记。整个过程有点绕,记录一下。

ENA Truncated JPEG Broke Every Image After It in Chrome

发表于

An image preview would intermittently go blank when stepping through a gallery. I spent a long time inside compositing layers, React render timing and cache behaviour, and fixed none of it. The root cause was two missing bytes at the end of one JPEG.

The detour is the interesting part, so this write-up keeps it.

AMD异步模块配合webpack代码拆分实现业务模块按需加载

发表于 | 分类于 前端/前端工程

最近做了一个业务模块库的按需加载改造。这个库聚合了十几个业务子模块,原来宿主应用一上来就把所有模块全量加载,随着模块越来越多,首屏时间肉眼可见地变长。

目标是:宿主侧零改造,消费方无感知,用到哪个模块才去加载哪个模块对应的 chunk。这篇文章整理了这个过程中的核心技术细节,重点在两块:AMD loader 怎么改造才能支持异步模块,以及 webpack 的 import() 到底做了什么让 factory 变成异步的

初识Web3之从零构建许愿墙DApp

发表于 | 分类于 杂项

春节假期闲来无聊,打算了解一下web3,借助AI构建了一个简单的许愿墙 DApp,学习Web2应用和Web3应用有什么差异。

这篇文章主要整理一下整个过程,包括遇到的坑和解决方案。

基于monorepo的antd二次开发调试方案

发表于 | 分类于 前端/前端工程

最近在做 Ant Design 的二次开发,需要深度定制一些组件,甚至要改底层的 rc-* 组件。这个过程并不是很顺利,遇到了很多流程上的问题。

本文将介绍一种基于monorepo 二开antd代码的方案,解决antd 二开遇到的一些问题。

cssText和setAttribute在CSP中的差异

发表于 | 分类于 前端/前端业务

最近测试反馈了几个组件库的样式问题,在 dev 和 sit 线上环境可以复现,本地 dev server 却无法复现。排查了一下,发现居然跟对应环境是否开启 CSP 有关。

这个问题挺有意思的,涉及到浏览器对不同样式设置方式的处理差异,值得记录一下。

ENWhy CSP Blocks setAttribute('style') but Not style.cssText

发表于

QA reported styling glitches in a component library that reproduced on the dev and staging deployments but never on a local dev server. The distinguishing factor turned out to be whether the environment sent a Content-Security-Policy header.

Under CSP, styles set with setAttribute('style', …) silently did not apply. Styles set with style.cssText — the same declarations, the same element — applied fine. The DOM inspector showed the attribute present on the element, and the page rendered as though it were not.

基于 Codemod 的前端代码迁移工具开发

发表于 | 分类于 前端/前端工程

前端基础设施升级很少只是修改 package.json。以 React 18 和 Ant Design 4 升级为 React 18 和 Ant Design 5 为例,真正消耗时间的通常是散落在大量项目中的兼容性修改:组件属性更名、路由 API 变化、旧模块导入、样式覆盖失效,以及无法安全自动判断的边界场景。

这类工作如果完全依赖人工,会遇到三个问题:容易遗漏、修改口径不一致、迁移结果难以统计。Codemod 的价值,就是把已经确认的迁移规则固化成可重复执行的程序。

本文总结一个实际迁移工具的设计与实现。示例中的包名、组件名和配置均已泛化,不包含具体业务代码。

实现一个简易的CSS-in-JS工具

发表于 | 分类于 技术原理

最新在处理项目antd4升级到antd5,里面有一个性能问题需要排查antd5里面使用的css in js

之前虽然对于css in js有一些耳闻,但并没有在项目中使用过,对其原理也没有特别了解,因此需要先学习一下。本文将参考@ant-design/cssinjs的源码,实现一个非常简单的css in js工具,了解其核心原理和实现。

pnpm在CI中的严格模式

发表于 | 分类于 前端/前端工程

最近在进行项目的底层库升级,顺带将前端项目的包管理工具从yarn切换为了pnpm。在 CI 部署的时候遇到了一个问题:当 pnpm-lock.yamlpackage.json 里面的包版本不一致时,CI 会直接报错退出。但是在本地执行 pnpm install 却一切正常,依赖照样能装上。

难道是pnpm在本地和 CI安装时会有一些差异?

这个问题最终在pnpm的文档中找到了答案,这其实是 pnpm 的一个精心设计,本文将记录一下这个问题。

ENWhy pnpm install Fails in CI but Works Locally

发表于

While upgrading a project's dependencies I also switched its package manager from yarn to pnpm. The CI pipeline broke immediately: whenever pnpm-lock.yaml disagreed with package.json, the install step failed outright. The exact same command on my laptop installed everything without a word of complaint.

Same commit, same command, two different outcomes. That is not a bug — it is a deliberate design decision, and the switch behind it is worth understanding.

monorepo项目的一些策略

发表于 | 分类于 前端/前端工程

在monorepo的实际落地项目中,存在一些方案策略问题,比如使用产物依赖还是源码依赖,如何管理公共的tsconfig配置和eslint配置,怎么根据依赖构建和批量发布版本等,本文整理一下这些策略点。

JavaScript模拟获取函数执行上下文

发表于 | 分类于 编程语言/JavaScript

在代码开发中,函数嵌套调用时很常见的,有时候需要根据函数的执行上下文做一些事情。

比如a调用了b,b调用了c,c调用了d,最后希望d可以获取是从a调用时的一些信息,一般是通过参数透传等方式来实现,在写法上比较繁琐。

本文将研究在前端js代码实现中,是否有更简单的写法。

一个AI独立完成的游戏自动化脚本

发表于 | 分类于 杂项

从2023年初,ChatGPT横空出世,AIGC逐渐成为一个耳熟能详的词语。过去两年,我每年都会写一篇关于AIGC相关的文章,表达一下我对其看法。

今年这篇文章拖到下半年才开始写,因为今年基本上全程在使用AI工具编写代码了,从最初的ChatGPT、Claude问答式编码,到后面的github copilotCLineCursort,AI编码工具已经经历了不少的迭代,现在基本上可以自动化创建文件、编写、修改代码。

最近沉迷玩一款放置游戏,但是里面有个机制需要人工手动操作,非常繁琐,本文将记录我是如何使用AI,零编码完成一个游戏自动化脚本的开发和使用。