Skip to main content

博客

关于 Web 开发、性能与工具——偶尔也聊点更大的话题。

iOSSafariWebKitLexicalcontenteditableDebugging

四个 bug 一起杀死了 iOS 上的文本选择——而且每一个都掩盖着下一个

放在 vaul 抽屉里的 Lexical 编辑器在哪里都正常,唯独在真实 iPhone 上不行:选择手柄拖不动,滚动在边缘卡死,工具栏沉到键盘下面。靠猜什么也修不好,因为根本不存在唯一的元凶——是四个相互独立的问题,每一个都掩盖着下一个。真正起作用的是二分法试验台:同一副骨架,为每个嫌疑对象设一个开关,在实体设备上验证。这是完整的追凶过程——毒害选择手势的 href、vaul 的拖拽处理器、我们自己的 tap-focus、在手指下方移动的容器——外加滚动锁死的解剖,以及让 rubber-band 回弹手感如原生般顺滑的三次一次性 scrollTop 写入,包括在回弹进行中接住一次滑动。

2026年9月5日15 分钟阅读
阅读文章
Claude CodeAICLIBashAutomationResilience

智能体级联:终端自己挑出还活着的那个

Claude 部分宕机、一些模型停止响应时,我想切换到 Gemini——却发现自己的后备方案早就坏了好几个月。这篇讲的是怎么做一个真正扛得住的。

2026年8月29日9 分钟阅读
阅读文章
Claude CodeAIAutomationMonitoringlaunchdResilience

system-droid:一只自己巡检、自己修复我所有系统的看门狗

我的本地服务总是悄无声息地挂掉:早晨的简报不来了,令牌过期了,备份卡住了——而我总是最后一个知道。于是我做了一个 launchd droid:每两小时检查一切,能安全修的交给 Claude 智能体去修,只有真正需要人时才给我发消息。

2026年8月17日10 分钟阅读
阅读文章
Next.jsA/B TestingProxyPerformanceSSG

一个其实是 A/B 测试的静态页面

A/B 测试通常的做法会把页面从 CDN 上拽下来,变成按请求渲染。其实不必如此。让每个变体都保持完全静态,把分配决策交给一个 proxy(Next.js 改名后的 middleware)——它通过实验平台、基于稳定的 device id 来解析,且只有当访客不在对照组时才做 rewrite。URL 从不改变,CDN 照旧缓存,而常见路径不付出任何代价。

2026年8月14日8 分钟阅读
阅读文章
VercelGitHub ActionsCI/CDDeploymentMonorepo

当提交者不是团队成员时,如何从 CI 部署到 Vercel

把仓库迁进 GitHub 组织后,Vercel 会悄悄开始拦截你的部署:提交“无法匹配到团队成员”。本文讲我如何改用 GitHub Actions + Vercel CLI 部署——提交依旧计入我自己的 GitHub 贡献图,仪表盘依旧显示是谁 push 的,而我不必为每个贡献者买一个席位。

2026年8月10日8 分钟阅读
阅读文章
Next.jsMemory LeakDockerAWS LambdaNode.js

Next.js 内存泄漏:Fetch + Standalone 模式——2年未修复

Next.js 修补全局 fetch 并添加一个在每次请求时泄漏内存的缓存层。在 Docker/K8s 中,这会导致每隔几小时发生 OOM 崩溃。该 bug 自 Next.js 14 以来就存在,在 16.2.x 中仍未解决。

更新于 2026年8月10日10 分钟阅读
阅读文章
claude-codeproductivityclidevtools

在一台设备上运行多个 Claude Code 账号

如何并行使用两个(或更多)Claude Code 账号——个人和企业——通过单个环境变量实现完全隔离。

更新于 2026年8月9日4 分钟阅读
阅读文章
SolidJSSolidStartPerformanceSSGCode Splitting

在 SolidStart 中懒加载博客内容而不失去 SSG

你的博客很可能把每篇文章的正文都打进同一个 bundle——我的已经涨到 2.88 MB,连只需要标题的列表页也要下载它。下面是我如何把每篇文章的正文拆成按需加载的懒加载 chunk,同时让每个页面仍然完整地服务端渲染以保证 SEO。

2026年8月5日8 分钟阅读
阅读文章
ailearningcareermethodology

CRAFT:一套用 AI 提升效率而不丧失核心能力的方法

指出问题却不给出解决方案,只会徒增焦虑。继那篇关于 AI 导致技能退化的文章之后,这里给出处方:CRAFT——五条原则(Challenge First、Review Adversarially、Ask Why Not What、Friction on Purpose、Test Your Understanding),共同服从一个公理:AI 做你已经掌握的事,你做你仍在学习的事。一套实用、易记的方法,让你每天与 AI 协作,却不在不知不觉中失去真正的能力。

更新于 2026年8月5日6 分钟阅读
阅读文章
JavaScriptAnalyticsEvent DelegationServer ComponentsPerformance

一个监听器,取代每个按钮一个客户端组件

当你给一个组件加上点击埋点的那一刻,它就变成了一个会下发 JavaScript 的客户端组件。在整个站点上重复这么做,光是埋点就会让你的打包体积膨胀。本文要讲的是另一种方案——它其实一直就躺在平台里:一个委托监听器、声明式的 data 属性,以及始终保持纯服务端渲染 HTML 的组件。

2026年7月28日10 分钟阅读
阅读文章
CSSHTMLAccordionFrontendPerformance

零 JavaScript 的丝滑手风琴

要做一个手风琴,大家都会习惯性地用上 React state 和一个测量高度的 hook。可浏览器早就内置了一个原生的——而且从 2024 年起,它已经能用纯 CSS 实现展开和收起的动画。本文讲透整套技法:details[name]、::details-content、interpolate-size,以及那个让收起也能有动画的关键属性。

2026年7月28日9 分钟阅读
阅读文章
JavaScriptWebThird-Party ScriptsFrontendPatterns

在第三方值刚落地 window 的那一刻就捕获它

一个你无法控制的脚本,会在你无法预测的时间点,把结果写入 window 上的全局变量。大多数代码要么用 timeout 跟它赛跑,要么用轮询白白消耗主线程。本文介绍一个 accessor property(访问器属性)技巧,把这次写入变成一个事件——还会讲到你绝不能遗漏的 getter,以及如何彻底替换这个值。

2026年7月27日9 分钟阅读
阅读文章
CSSContainer QueriesTypographyFrontendPerformance

用纯 CSS 让文本适配容器 — 无需 JavaScript

人人都在写一个 JavaScript hook,通过缩小 font-size 让文本塞进容器。这里有一个完全可用、零 JS 的替代方案,使用容器查询单位、clamp() 和按语言的连字符断词 — 包括让很多人放弃的层叠陷阱。

2026年7月24日11 分钟阅读
阅读文章
Next.jsPerformanceCode SplittingTurbopackReact Server Components

next/dynamic 救不了你:为什么 CMS 驱动的 Next.js 页面会把每个 chunk 都发出去

我们那些 CMS 驱动的 Next.js 页面,在每一个路由上都发出了全部约 100 个 section 组件——尽管我们用的是教科书级别的 next/dynamic。我们把 bundler 层面的每一种修法(直接 import()、拆分文件、Turbopack 配置、webpack splitChunks)都试遍了,才找到真正的原因:可达性,而非 chunk 拆分。构建期代码生成加上 rewrites 把 first-load JS 削减了 53%。

2026年7月18日14 分钟阅读
阅读文章
obsidianmiroautomationtoolsopen-source

把我的 Miro boards 搬到 Obsidian

Miro 的 Export 按钮只给你 PNG 或 PDF —— 那是数据的照片,不是数据本身。如果你的 boards 是积累多年的 load-bearing 思维地图,它们应该住在 Obsidian 里:editable、searchable、放在本地 vault。我如何通过 REST API 把 boards 从 Miro 里拽出来,转成 Excalidraw / Obsidian Canvas —— 保留位置、颜色、字体、curved connectors、mindmap nodes —— 这件事的教训其实比 Miro 大得多:任何 SaaS 都应该在你第一次打开之前就先想好 exit plan。

2026年6月30日6 分钟阅读
阅读文章
claude-codeproductivityclidevtools

Claude Code 多配置文件,v2:干净的 XDG 架构

用了一个月旧的别名方案后,我把自己的 Claude Code 多配置文件 setup 重做成了 XDG 兼容的结构,放在 ~/.config/claude-profiles/ 下。真正的原因不是为了整洁——而是发现 ~/.claude.json 是 home 根目录下一个独立的文件,通过 --scope user 添加的 MCP 服务器一直悄悄地住在那里。

更新于 2026年6月23日9 分钟阅读
阅读文章
ailearningcareerengineering

被 AI 关掉的那份寂静

有了 AI,还值得学编程吗?喧嚣的两种回答两边都错。在 2025–2026 的证据基础上(Nature、Anthropic、AI & Society),问题不是"用不用 AI",而是哪些技能交给 AI、哪些留在自己手里 —— 真正变了的只有一件事:以前现实会用摩擦逼你学,AI 悄悄把这股压力关掉了。

2026年6月22日8 分钟阅读
阅读文章
claude-codeagentsaiprompt-engineeringautomation

如何编写不会对你撒谎的 Claude Code Agent

构建可靠 Claude Code agent pipeline 的两条规则:每个 agent 只做一件事,以及凡涉及定量答案的地方一律用 shell 命令代替 prompt。

2026年5月29日6 分钟阅读
阅读文章
ObsidianClaudeMCPAutomationAI

如何将 Claude Desktop 连接到 Obsidian——穿越 4 个 MCP 服务器的旅程

一个关于寻找通过 Claude 自动化 Obsidian vault 重构的稳定方式的真实故事。什么坏了,什么有效,以及为什么 VaultForge 是唯一可行的选择。

2026年5月3日9 分钟阅读
阅读文章
physicsphilosophyconsciousnessblack-holescosmology

黑洞作为递归宇宙:从物理学到存在的意义

如果每个黑洞都是一个新宇宙的大爆炸呢?探索递归宇宙学、霍金辐射、认知闭合以及宇宙为何可能被设计来促进自我完善。

2026年4月17日10 分钟阅读
阅读文章
aicmsweb-developmentopinionworkflow

AI 杀死了 CMS — 至少对简单网站而言

为什么传统内容管理系统对作品集、博客和着陆页变得不再必要 — 以及AI工具如何用自然语言替代整个CMS层。

2026年4月17日8 分钟阅读
阅读文章
ObsidianPerplexityMCPAIProductivity

如何通过 MCP 将 Perplexity AI 连接到 Obsidian——直接从聊天中记笔记

设置 Perplexity Desktop 使用 MCP filesystem 服务器读写您的 Obsidian vault。在一次对话中搜索网络并保存到笔记。

2026年4月12日5 分钟阅读
阅读文章
Claude CodeAIObsidianAutomationProductivity

使用 Claude Code CLI 和 Obsidian 的每日 AI 新闻摘要——零依赖

如何用6行bash脚本、Claude Code headless模式和macOS launchd构建每日新闻研究代理。

2026年4月12日7 分钟阅读
阅读文章
next.jsreact-19dark-modezustandperformance

Next.js 暗色模式:无闪烁、无 React 19 警告

如何用 Zustand + useServerInsertedHTML 替换 next-themes,在 Next.js 15+ 中实现无闪烁暗色模式。

2026年4月11日8 分钟阅读
阅读文章
Next.jsCSSPerformanceTurbopackSCSS

我如何用一个文档不全的 Turbopack 功能消除了 Next.js 16 中的 94 个渲染阻塞 CSS 文件

经过数天尝试每种方法——从 experimental.inlineCss 到 MutationObserver hack——我发现了 Turbopack Import Attributes,它解决了 Next.js App Router 中的渲染阻塞 CSS 问题。

2026年4月8日12 分钟阅读
阅读文章