<?xml version="1.0" encoding="utf-8" ?><rss version="2.0">

<channel>
	<title>IT技术博客大学习</title>
	<link>http://www.blogread.cn/it/</link> 
	<description>IT技术博客大学习 共学习 共进步</description>
	<language>zh-cn</language>
	<pubDate>Thu, 11 Jun 2026 02:15:37 +0800</pubDate>
	<copyright>Copyright (C) 2009 - 2026 IT技术博客大学习 - 本页面所有内容，未经blogread.cn许可，欢迎转载，但请注明出处</copyright>
	<generator>yayu</generator>
	<lastBuildDate>Thu, 11 Jun 2026 02:15:37 +0800</lastBuildDate>

	<item>
		<title>一个冷门的速查日历方法</title>
		<link>https://blogread.cn/it/article.php?id=8599</link>
		<author>neverland</author>
		<pubDate>2026-06-03 09:03:24</pubDate>
		<category domain="https://blogread.cn/it/category.php?id=8">开发者</category>
		<guid>https://blogread.cn/it/article.php?id=8599</guid>
		<comments>https://blogread.cn/it/article.php?id=8599#comment</comments>
		<description><![CDATA[<p><strong>标签：</strong>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=cal" target="_blank">cal</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=vscodium" target="_blank">vscodium</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=%E7%BA%AF%E6%96%87%E6%9C%AC" target="_blank">纯文本</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=%E7%BB%88%E7%AB%AF" target="_blank">终端</a></p><p>就是终端里的 <code>cal</code> 命令了。之所以喜欢用这个首先是因为快：我平时固定是开着终端的（作为 vscodium 的底部面板），码字过程中直接打个 cal（pun intended）就能看当月日历，比打开日历应用或者 menubar item 都要快。其次因为是终端输出，就是纯文本，可以直接复制到笔记里参考或者进一步标注。当然缺点就是比较简陋，不过我本来就喜欢这种野兽派纯文本风格，所以反而是加分项了。</p>
<p>以下是一些常用选项和参数：</p>
<pre class="blogread-code language-bash" data-lang="bash"><code class="language-bash"># 显示 2025 全年
cal 2025 # shorthand for `cal -y 2025`

# 显示今年 3 月
cal -m 3

# 显示本月和紧邻的前后月份
cal -3

# 旋转行和列（每周为一列）并显示周数
ncal -w # shorthand for `cal -N -w`</code></pre><p>更多用法可以看手册页 <code>man cal</code>。如其中的 history 一节所说这也是个上古命令了，从 Version 1 AT&amp;T UNIX (1971) 就有，几十年就是这样下来了（</p>
				<p><strong>您可能还对下面的文章感兴趣：</strong></p>
				<p><ol><li><a href="https://blogread.cn/it/article.php?id=8365" target="_blank">iTerm2 (Mac Terminal) 清空当前屏幕内容</a> [2022-02-03 13:16:36]</li><li><a href="https://blogread.cn/it/article.php?id=8222" target="_blank">在命令行中步入黑客帝国</a> [2018-12-24 23:58:32]</li><li><a href="https://blogread.cn/it/article.php?id=8205" target="_blank">假装很忙的三个命令行工具</a> [2018-07-05 00:00:26]</li><li><a href="https://blogread.cn/it/article.php?id=6856" target="_blank">Ctrl+S导致Putty或Xterm命令行无响应问题</a> [2014-04-29 22:34:12]</li><li><a href="https://blogread.cn/it/article.php?id=1267" target="_blank">linux下vim的编译以及终端乱码的最终解决方案</a> [2010-03-29 08:51:21]</li><li><a href="https://blogread.cn/it/article.php?id=1154" target="_blank">将GUI配色转化为终端配色的VIM插件</a> [2010-03-08 23:07:19]</li></ol></p>]]></description>
		<content><![CDATA[终端中的 `cal` 命令是一款轻量高效的日历查询工具，特别适合开发者在编码过程中快速查看日期。其核心优势在于调用速度快，作为集成开发环境（如 VSCodium）终端面板的一部分，输入命令即可即时获取日历视图，无需切换至图形化应用。输出为纯文本格式，便于直接复制到笔记中进行后续整理或标注，契合偏好命令行操作的极简风格。

该命令提供多种参数以满足不同场景需求：通过 `cal 2025` 可直接查看指定年份的全年日历；`cal -m 3` 用于显示特定月份；`cal -3` 会同时呈现当前月及其前后月份，便于进行日期规划。进阶用法如 `ncal -w` 能够以每周一列的布局显示日历并附带周数，适合进行周期性任务管理。更多选项可通过 `man cal` 手册查阅，该命令历史悠久，自1971年首次出现在AT&T UNIX系统中，其稳定性和简洁性经受了长期考验。]]></content>
	</item>
	<item>
		<title>Day for Night</title>
		<link>https://blogread.cn/it/article.php?id=8598</link>
		<author>neverland</author>
		<pubDate>2026-06-03 09:03:24</pubDate>
		<category domain="https://blogread.cn/it/category.php?id=13">设计</category>
		<guid>https://blogread.cn/it/article.php?id=8598</guid>
		<comments>https://blogread.cn/it/article.php?id=8598#comment</comments>
		<description><![CDATA[<p><strong>标签：</strong>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=UI%E8%AE%BE%E8%AE%A1" target="_blank">UI设计</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=UX%E8%AE%BE%E8%AE%A1" target="_blank">UX设计</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=%E4%BA%A4%E4%BA%92%E8%AE%BE%E8%AE%A1" target="_blank">交互设计</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=%E5%8A%A8%E7%94%BB" target="_blank">动画</a></p><p><a href="https://unsung.aresluna.org/day-for-night/">Marcin Wichary</a>:</p>
<blockquote>
<p>But there’s a trick [to invert black and white while preserving colors]: do a regular invert and then rotate the hue halfway through. Through the magic of math, this is the same as inverting just L in the HSL space, which means the colors are preserved.</p>
<p>…and, more importantly, [this is] available in CSS as a filter: instead of <code>invert(1)</code>, use <code>hue-rotate(180deg) invert(1)</code>.</p>
</blockquote>
				<p><strong>您可能还对下面的文章感兴趣：</strong></p>
				<p><ol><li><a href="https://blogread.cn/it/article.php?id=8118" target="_blank">优化JavaScript的执行效率</a> [2016-12-22 23:25:54]</li><li><a href="https://blogread.cn/it/article.php?id=8010" target="_blank">javascript动画剖析</a> [2016-03-30 16:01:23]</li><li><a href="https://blogread.cn/it/article.php?id=7896" target="_blank">iOS下自己动手造无限循环图片轮播</a> [2016-03-15 23:28:22]</li><li><a href="https://blogread.cn/it/article.php?id=7293" target="_blank">CSS3 动画系列</a> [2015-01-20 23:22:01]</li><li><a href="https://blogread.cn/it/article.php?id=7174" target="_blank">JavaScript实现的抛物线运动效果</a> [2014-12-10 23:07:04]</li><li><a href="https://blogread.cn/it/article.php?id=6647" target="_blank">移动用户体验设计新要素</a> [2013-08-28 22:19:28]</li><li><a href="https://blogread.cn/it/article.php?id=6631" target="_blank">创造流动的瞬间—探讨移动端交互动效设计</a> [2013-08-21 13:27:58]</li><li><a href="https://blogread.cn/it/article.php?id=5567" target="_blank">自然而流畅——聊聊界面的切换动画</a> [2012-07-19 12:21:24]</li><li><a href="https://blogread.cn/it/article.php?id=4426" target="_blank">HTML5和CSS3工具资源汇总</a> [2011-09-26 23:29:35]</li><li><a href="https://blogread.cn/it/article.php?id=4178" target="_blank">使用JavaScript和Canvas开发游戏（一）</a> [2011-08-18 13:50:53]</li><li><a href="https://blogread.cn/it/article.php?id=4052" target="_blank">精于图片处理的10款jQuery插件</a> [2011-07-24 14:56:36]</li><li><a href="https://blogread.cn/it/article.php?id=3471" target="_blank">Canvas高级特性</a> [2011-03-27 23:55:35]</li><li><a href="https://blogread.cn/it/article.php?id=3466" target="_blank">拥抱并使用CSS3</a> [2011-03-27 23:48:55]</li><li><a href="https://blogread.cn/it/article.php?id=3419" target="_blank">“亲情的朝圣，成长的礼赞”―手机QQ闪屏设计理念</a> [2011-03-07 22:56:59]</li><li><a href="https://blogread.cn/it/article.php?id=3146" target="_blank">PNG现状整理</a> [2011-01-30 19:07:40]</li><li><a href="https://blogread.cn/it/article.php?id=3007" target="_blank">有故事的网页设计――Flash网站奇妙之旅</a> [2011-01-16 22:29:06]</li><li><a href="https://blogread.cn/it/article.php?id=2433" target="_blank">用 CSS3 Transitions 实现动画</a> [2010-09-28 09:23:25]</li><li><a href="https://blogread.cn/it/article.php?id=1360" target="_blank">制作CSS气泡框</a> [2010-04-13 11:10:16]</li><li><a href="https://blogread.cn/it/article.php?id=1099" target="_blank">关于动态gif的帧速</a> [2010-03-01 13:44:38]</li></ol></p>]]></description>
		<content><![CDATA[在CSS中常规使用`invert(1)`滤镜会导致所有颜色反转，包括原本的色彩信息。若想仅反转黑白（明暗关系）而保持色彩不变，可采用组合滤镜方案：先执行反转操作，再通过色相旋转进行补偿。具体实现方式为`hue-rotate(180deg) invert(1)`。这一技巧的原理在于：在HSL颜色模型中，单独反转亮度（L）分量可保留色相（H）与饱和度（S），而先整体反转再旋转180度色相，数学上等效于仅对L分量取反。该方法适用于需要高对比度暗色主题或图像处理的场景，能够在不改变主色调的前提下实现视觉反色效果。]]></content>
	</item>
	<item>
		<title>新特性速递：focus()行为新增focusVisible控制</title>
		<link>https://blogread.cn/it/article.php?id=8597</link>
		<author>张 鑫旭</author>
		<pubDate>2026-06-03 09:03:24</pubDate>
		<category domain="https://blogread.cn/it/category.php?id=7">前端</category>
		<guid>https://blogread.cn/it/article.php?id=8597</guid>
		<comments>https://blogread.cn/it/article.php?id=8597#comment</comments>
		<description><![CDATA[<p><strong>标签：</strong>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=CSS" target="_blank">CSS</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=DOM" target="_blank">DOM</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=JavaScript" target="_blank">JavaScript</a></p><p>by <a href="https://www.zhangxinxu.com/">zhangxinxu</a> from <a href="https://www.zhangxinxu.com/wordpress/?p=12203">https://www.zhangxinxu.com/wordpress/?p=12203</a><br>
本文可全文转载，但需要保留原作者、出处以及文中链接，AI抓取保留原文地址，任何网站均可摘要聚合，商用请联系授权。</p>
<h3>一、focus()的两种控制</h3>
<p>平时让一个输入框聚焦，我们可以这么设置：</p>
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">input.focus();</code></pre>
<p>默认情况下，控件元素通过<code>focus()</code>方法获取焦点，浏览器会通过滚动的方式让元素重定位到页面可视区域内。</p>
<p>但有时候，这种行为会影响体验，毕竟页面会突然跳一下。</p>
<p>如果不希望这种滚动行为触发，可以这么设置。</p>
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">input.focus({
  preventScroll: true
})</code></pre>
<p>此特性已支持多年，我也多次在生产环境使用。</p>
<p><img fetchpriority="high" decoding="async" src="https://image.zhangxinxu.com/image/blog/202605/2026-5-29_151901.png" width="652" height="287" alt="preventScroll兼容性" class="alignnone size-medium"></p>
<p>那么本文要介绍的focusVisible又是什么呢？</p>
<h3>二、focusVisible参数的作用</h3>
<p>focusVisible可以控制元素获得焦点的时候，是否显示浏览器内置的outline轮廓效果。</p>
<p>先看一个案例，如下HTML代码：</p>
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">&lt;a href id="link"&gt;链接&lt;/a&gt;
&lt;button onclick="link.focus()"&gt;点击我&lt;/button&gt;</code></pre>
<p>此时，点击按钮，链接是没有焦点效果的。</p>
<p>这在开发中其实是有用户体验的问题的，用户并不知道这个链接是否真的被聚焦了，除非有专门的CSS定义，例如：</p>
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">:any-link:focus {
  color: red;
}</code></pre>
<p>效果示意：</p>
<p><img decoding="async" src="https://image.zhangxinxu.com/image/blog/202605/2026-5-29_152441.png" width="224" height="82" alt="链接文字颜色变红" class="alignnone size-medium"></p>
<p>不过针对每一个控件元素设置focus效果是啰嗦的，在一些对视觉要求不那么高的场合，通过<code>focusVisible</code>参数进行控制是最快捷的方法，例如：</p>
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">&lt;a href id="link"&gt;链接&lt;/a&gt;
&lt;button onclick="link.focus({focusVisible: true})"&gt;点击我&lt;/button&gt;</code></pre>
<p>点击按钮后的效果示意：</p>
<p><img decoding="async" src="https://image.zhangxinxu.com/image/blog/202605/2026-5-29_152847.png" width="204" height="78" alt="焦点效果示意" class="alignnone size-medium"></p>
<p>如果大家对自己手头的浏览器足够自信，也可以点击下面的按钮，亲自感受下聚焦后的轮廓效果。</p>
<p><a href="https://www.zhangxinxu.com/wordpress/2026/05/js-focus-focusvisible/#">链接</a> <button>点击我</button></p>
<p>当然，<code>focusVisible</code>也能用来关闭浏览器默认的轮廓效果。</p>
<p>例如下面的输入框获得焦点后，浏览器的发光轮廓是不会显示的。</p>
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">&lt;input id="input" type="text"&gt;
&lt;button onclick="input.focus({focusVisible: false})"&gt;点击我&lt;/button&gt;</code></pre>
<p>一般与无障碍访问与用户体验相关的特性，在国内总是无人问津，因为缺少对应的法律法规约束。</p>
<p>所以focusVisible这个特性注定知者寥寥，加上其兼容性，我对其未来的应用程度表示并不乐观。</p>
<p><img loading="lazy" decoding="async" src="https://image.zhangxinxu.com/image/blog/202605/2026-5-29_161411.png" width="651" height="250" alt="fousVisible兼容性" class="alignnone size-medium"></p>
<h3>三、难得碎碎念</h3>
<p>说实话，在AI时代，对AI模型的关注和研究，我已经落后于现在的年轻人了。</p>
<p>我不是做管理的，如果我带着一个团队，我会花很多时间思考这些模型和工具对团队生产力的赋能，因为那可以体现我的价值，或者说为数不多可以体验价值，或者至少让上级看到价值的地方。</p>
<p>虽说单纯的专业技术人员也能做这样的事情，但是，考虑到“上下左右”的现实障碍（这里写了不少，都删掉了，怕厂子的公关过来提醒），是很难推动的，所以很难让我投入大量的精力在这个上面。</p>
<p>作为一个纯专业立足的前端开发，究竟什么才是自己的核心竞争力，这个问题我其实一直在思考。</p>
<p>为什么会一直思考呢？</p>
<p>因为每次分享那些实用或不实用的前端技术，都会有人评论，现在都AI了，学这个还有什么用。</p>
<p>我的回答是：</p>
<p>如果我的水平比AI还要强，我实现的东西比AI实现的还要好，那我是不是不要担心被AI替代，这是不是我的核心竞争力！</p>
<p>人的精力是有限的，尤其到了我现在这个年纪，再像10年前那样，每天研究前端到凌晨1~2点，是不可能了，只能舍弃工具层面的关注与研究，继续把精力放在语言本身上。</p>
<p>那些好的，可能不稳定的特性，那些特别新的但是很高效的实现上。</p>
<p>比方说最近的项目使用<code>scroll-state</code>滚动容器查询：</p>
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">@container excel-scroller scroll-state(scrolled: right) {
  /* 第一列粘性定位启用的时候，出现右边框 */
  :where(td, th):first-child {
    border-right: 1px solid var(--ui-border);
  }
}</code></pre>
<p>AI绝对不会想到这么实现，为何？</p>
<p>一是训练的代码库还没有这样的的代码；二是AI为了项目稳定，一定会使用更加稳健的传统实现，虽然说最终也都能实现最终的效果，但是代码质量天差地别。</p>
<p>作为一个对兼容性要求不那么高的项目，AI生产的稳健代码并非是最好的实现，如果只是单纯使用AI生成一个能跑的东西，为何需要用你呢？换个更便宜的年轻人岂不更好。</p>
<p>不过，想要变得专业层面，至少某一个领域比AI强，还是很难的，而且越往后越难，这个之后的文章再碎碎念吧。</p>
<p>OK，就这样吧，感谢阅读，欢迎分享。</p>
<p><br>
</p>
<p>本文为原创文章，会经常更新知识点以及修正一些错误，因此转载请保留原出处，方便溯源，避免陈旧错误知识的误导，同时有更好的阅读体验。<br>
本文地址：<a href="https://www.zhangxinxu.com/wordpress/?p=12203">https://www.zhangxinxu.com/wordpress/?p=12203</a></p>
<p>（本篇完）</p>
				<p><strong>您可能还对下面的文章感兴趣：</strong></p>
				<p><ol><li><a href="https://blogread.cn/it/article.php?id=8590" target="_blank">Cross-Document View Transitions: Scaling Across Hundreds of Elements</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8571" target="_blank">JSON.rawJSON方法的作用是什么？</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8567" target="_blank">A Scrollytelling Gift for Mum on Mother’s Day 2026</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8565" target="_blank">Soon We Can Finally Banish JavaScript to the ShadowRealm</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8558" target="_blank">Cross-Document View Transitions: The Gotchas Nobody Mentions</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8554" target="_blank">Rethinking “Pixel Perfect” Web Design</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8545" target="_blank">Getting Started With The Popover API</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8541" target="_blank">Moving From Moment.js To The JS Temporal API</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8508" target="_blank">务必谨慎使用JS WeakRef弱引用</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8507" target="_blank">借助mediabunny纯JS实现视频水印、剪裁、合成等功能</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8375" target="_blank">如何使用CSS判断鼠标从哪个方向进入元素？</a> [2026-05-07 14:28:05]</li><li><a href="https://blogread.cn/it/article.php?id=8361" target="_blank">你老了</a> [2021-06-13 23:11:09]</li><li><a href="https://blogread.cn/it/article.php?id=8331" target="_blank">浅谈阿里前端的多样化</a> [2021-05-24 22:43:35]</li><li><a href="https://blogread.cn/it/article.php?id=8317" target="_blank">浅谈 Web 应用的内存优化</a> [2020-02-05 15:13:31]</li><li><a href="https://blogread.cn/it/article.php?id=8260" target="_blank">Javascript创建对象方式总结</a> [2019-04-08 00:55:55]</li><li><a href="https://blogread.cn/it/article.php?id=8172" target="_blank">Chrome runtime 不稳定（GC）导致插件绑定事件失败</a> [2017-10-15 10:00:29]</li><li><a href="https://blogread.cn/it/article.php?id=8171" target="_blank">了解JS中的全局对象window.self和全局作用域self</a> [2017-10-15 09:58:33]</li><li><a href="https://blogread.cn/it/article.php?id=8137" target="_blank">JavaScript: 2016年回顾</a> [2017-02-19 23:59:26]</li><li><a href="https://blogread.cn/it/article.php?id=8134" target="_blank">ECMAScript 6 Modules(模块)系统及语法详解</a> [2017-02-19 23:52:34]</li><li><a href="https://blogread.cn/it/article.php?id=8118" target="_blank">优化JavaScript的执行效率</a> [2016-12-22 23:25:54]</li><li><a href="https://blogread.cn/it/article.php?id=8113" target="_blank">jQuery 3.0 升级指南</a> [2016-11-06 22:36:27]</li><li><a href="https://blogread.cn/it/article.php?id=8111" target="_blank">用webgl打造一款简单第一人称射击游戏</a> [2016-11-06 22:32:41]</li><li><a href="https://blogread.cn/it/article.php?id=8099" target="_blank">谈谈我这三年在技术上的成长</a> [2016-07-11 23:33:33]</li><li><a href="https://blogread.cn/it/article.php?id=8093" target="_blank">Date对象的那些事儿</a> [2016-06-06 23:37:24]</li><li><a href="https://blogread.cn/it/article.php?id=8091" target="_blank">超级小的web手势库AlloyFinger发布</a> [2016-06-06 23:34:30]</li><li><a href="https://blogread.cn/it/article.php?id=8088" target="_blank">前端路由实现与 react-router 源码分析</a> [2016-05-18 00:01:37]</li><li><a href="https://blogread.cn/it/article.php?id=8082" target="_blank">移动web开发调试工具AlloyLever介绍</a> [2016-05-12 12:55:11]</li><li><a href="https://blogread.cn/it/article.php?id=8073" target="_blank">元素选择器 - Mini Query</a> [2016-05-05 22:44:05]</li><li><a href="https://blogread.cn/it/article.php?id=8071" target="_blank">JavaScript 代码执行效率对比工具</a> [2016-05-05 22:41:53]</li><li><a href="https://blogread.cn/it/article.php?id=8070" target="_blank">用javascript比较语义化版本号</a> [2016-05-05 22:39:15]</li><li><a href="https://blogread.cn/it/article.php?id=8063" target="_blank">聊聊前端</a> [2016-04-21 13:31:32]</li><li><a href="https://blogread.cn/it/article.php?id=8058" target="_blank">JavaScript 被忽视的细节</a> [2016-04-20 13:14:18]</li><li><a href="https://blogread.cn/it/article.php?id=8039" target="_blank">使用jquery卸载全部事件</a> [2016-04-02 22:44:16]</li><li><a href="https://blogread.cn/it/article.php?id=8032" target="_blank">提高JavaScript性能</a> [2016-04-02 14:09:17]</li><li><a href="https://blogread.cn/it/article.php?id=8024" target="_blank">前端开发者不得不知的ES6十大特性</a> [2016-04-02 13:27:57]</li><li><a href="https://blogread.cn/it/article.php?id=8021" target="_blank">React 的骨架  JSX</a> [2016-04-02 13:19:08]</li><li><a href="https://blogread.cn/it/article.php?id=8011" target="_blank">React Native for Android Windows环境搭建</a> [2016-03-30 16:03:47]</li><li><a href="https://blogread.cn/it/article.php?id=8010" target="_blank">javascript动画剖析</a> [2016-03-30 16:01:23]</li><li><a href="https://blogread.cn/it/article.php?id=8005" target="_blank">玩转npm</a> [2016-03-30 13:02:30]</li><li><a href="https://blogread.cn/it/article.php?id=8000" target="_blank">探索react native首屏渲染最佳实践</a> [2016-03-29 23:36:39]</li><li><a href="https://blogread.cn/it/article.php?id=7999" target="_blank">从Promise的Then说起</a> [2016-03-29 23:34:32]</li><li><a href="https://blogread.cn/it/article.php?id=7989" target="_blank">我是如何从装修转到前端</a> [2016-03-23 17:01:39]</li><li><a href="https://blogread.cn/it/article.php?id=7966" target="_blank">浅谈javascript闭包</a> [2016-03-21 23:57:20]</li><li><a href="https://blogread.cn/it/article.php?id=7964" target="_blank">Web前端文件处理</a> [2016-03-21 23:51:06]</li><li><a href="https://blogread.cn/it/article.php?id=7952" target="_blank">深入理解JavaScript定时机制</a> [2016-03-21 23:18:09]</li><li><a href="https://blogread.cn/it/article.php?id=7947" target="_blank">浅析 JavaScript 中的 “闭包”</a> [2016-03-21 22:53:39]</li><li><a href="https://blogread.cn/it/article.php?id=7939" target="_blank">Ballade: 重新诠释 Flux 架构</a> [2016-03-21 00:25:19]</li><li><a href="https://blogread.cn/it/article.php?id=7938" target="_blank">React 高效开发环境的搭建</a> [2016-03-21 00:24:38]</li><li><a href="https://blogread.cn/it/article.php?id=7937" target="_blank">从Java和JavaScript来学习Haskell和Groovy（类型系统）</a> [2016-03-20 22:18:59]</li><li><a href="https://blogread.cn/it/article.php?id=7936" target="_blank">从Java和JavaScript来学习Haskell和Groovy（引子）</a> [2016-03-20 22:17:59]</li><li><a href="https://blogread.cn/it/article.php?id=7919" target="_blank">React-Native学习指南</a> [2016-03-18 16:50:56]</li><li><a href="https://blogread.cn/it/article.php?id=7908" target="_blank">JavaScript 封装问题</a> [2016-03-17 00:00:52]</li><li><a href="https://blogread.cn/it/article.php?id=7902" target="_blank">前后端分离的思考与实践（一）</a> [2016-03-15 23:51:42]</li><li><a href="https://blogread.cn/it/article.php?id=7901" target="_blank">让我们写快速的JavaScript,JS性能优化小窍门</a> [2016-03-15 23:46:25]</li><li><a href="https://blogread.cn/it/article.php?id=7861" target="_blank">“NodeJS在大搜车” 之 MVC基础结构</a> [2016-03-09 12:59:48]</li><li><a href="https://blogread.cn/it/article.php?id=7857" target="_blank">从Java和JavaScript来学习Haskell和Groovy（元编程）</a> [2016-03-07 23:57:54]</li><li><a href="https://blogread.cn/it/article.php?id=7840" target="_blank">JavaScript中的继承方式</a> [2016-03-03 13:09:02]</li><li><a href="https://blogread.cn/it/article.php?id=7838" target="_blank">前端编码风格规范（3）—— JavaScript 规范</a> [2016-03-02 23:53:03]</li><li><a href="https://blogread.cn/it/article.php?id=7836" target="_blank">前端编码规范（1）—— 一般规范</a> [2016-03-02 23:47:43]</li><li><a href="https://blogread.cn/it/article.php?id=7833" target="_blank">12行代码的浏览器DoS攻击分析及防御</a> [2016-03-02 00:02:05]</li><li><a href="https://blogread.cn/it/article.php?id=7811" target="_blank">NodeJS的代码调试和性能调优</a> [2016-02-29 23:41:55]</li><li><a href="https://blogread.cn/it/article.php?id=7809" target="_blank">近几年前端技术盘点以及 2016 年技术发展方向</a> [2016-02-29 23:30:34]</li><li><a href="https://blogread.cn/it/article.php?id=7801" target="_blank">从Java和JavaScript来学习Haskell和Groovy（DSL）</a> [2016-02-21 22:47:37]</li><li><a href="https://blogread.cn/it/article.php?id=7785" target="_blank">JSON.parse()和JSON.stringify()方法总结</a> [2016-02-20 14:19:36]</li><li><a href="https://blogread.cn/it/article.php?id=7782" target="_blank">DOM中Property与Attribute的区别</a> [2016-02-20 14:14:26]</li><li><a href="https://blogread.cn/it/article.php?id=7781" target="_blank">[JavaWeb教程]第二章-jQuery简明开发教程</a> [2016-02-20 11:48:34]</li><li><a href="https://blogread.cn/it/article.php?id=7769" target="_blank">Node.js 给前端带来了什么</a> [2016-02-16 22:56:04]</li><li><a href="https://blogread.cn/it/article.php?id=7762" target="_blank">你不该忽视的小问题之margin叠加篇</a> [2016-02-16 22:07:59]</li><li><a href="https://blogread.cn/it/article.php?id=7731" target="_blank">由NodeJieba谈谈Node.js异步实现 </a> [2016-02-13 23:39:24]</li><li><a href="https://blogread.cn/it/article.php?id=7730" target="_blank">一个“三端”开发者眼中的React Native</a> [2016-02-13 23:14:36]</li><li><a href="https://blogread.cn/it/article.php?id=7714" target="_blank">js代码因逗号不规范导致IE不兼容的问题</a> [2016-02-12 17:44:22]</li><li><a href="https://blogread.cn/it/article.php?id=7694" target="_blank">javascript定义对象的几种方法</a> [2016-02-11 16:23:48]</li><li><a href="https://blogread.cn/it/article.php?id=7687" target="_blank">JavaScript初体验 </a> [2016-02-11 14:54:11]</li><li><a href="https://blogread.cn/it/article.php?id=7685" target="_blank">用JavaScript将数字转换为大写金额</a> [2016-02-11 14:49:39]</li><li><a href="https://blogread.cn/it/article.php?id=7681" target="_blank">跨域访问和防盗链基本原理（二）</a> [2016-02-10 23:09:10]</li><li><a href="https://blogread.cn/it/article.php?id=7670" target="_blank">jQuery对象和DOM对象小结</a> [2016-02-09 23:31:26]</li><li><a href="https://blogread.cn/it/article.php?id=7666" target="_blank">小tip: 子元素scroll父元素容器不跟随滚动JS实现</a> [2016-02-09 23:08:00]</li><li><a href="https://blogread.cn/it/article.php?id=7663" target="_blank">自己动手打造基于 WKWebView 的混合开发框架（二）——js 向 Native 一句话传值并反射出 Swift 对象执行指定函数</a> [2016-02-09 23:02:45]</li><li><a href="https://blogread.cn/it/article.php?id=7642" target="_blank">小tips: CSS或JS实现gif动态图片的停止与播放</a> [2016-02-07 14:06:53]</li><li><a href="https://blogread.cn/it/article.php?id=7632" target="_blank">小tip: 如何让contenteditable元素只能输入纯文本</a> [2016-02-06 23:30:38]</li><li><a href="https://blogread.cn/it/article.php?id=7614" target="_blank">充分发挥 JavaScript 语言的优势</a> [2016-01-27 22:44:11]</li><li><a href="https://blogread.cn/it/article.php?id=7606" target="_blank">基于原生HTML的UI组件开发</a> [2016-01-26 23:53:04]</li><li><a href="https://blogread.cn/it/article.php?id=7570" target="_blank">用 JavaScript 实现 mailto:</a> [2015-11-02 23:05:49]</li><li><a href="https://blogread.cn/it/article.php?id=7525" target="_blank">我的npm笔记</a> [2015-09-04 21:33:36]</li><li><a href="https://blogread.cn/it/article.php?id=7510" target="_blank">聊聊移动端跨平台开发的各种技术</a> [2015-07-17 13:24:44]</li><li><a href="https://blogread.cn/it/article.php?id=7506" target="_blank">使用yuicompressor.jar实现对js、css文件的代码压缩</a> [2015-06-04 10:25:43]</li><li><a href="https://blogread.cn/it/article.php?id=7495" target="_blank">JavaScript 中的 相等检测</a> [2015-06-02 13:32:28]</li><li><a href="https://blogread.cn/it/article.php?id=7493" target="_blank">什么是全栈工程师？</a> [2015-06-02 13:27:00]</li><li><a href="https://blogread.cn/it/article.php?id=7492" target="_blank">React初探</a> [2015-06-02 13:18:39]</li><li><a href="https://blogread.cn/it/article.php?id=7491" target="_blank">用 JS 复制艺术</a> [2015-06-02 13:17:58]</li><li><a href="https://blogread.cn/it/article.php?id=7487" target="_blank">javascript双向数据绑定</a> [2015-06-01 23:26:14]</li><li><a href="https://blogread.cn/it/article.php?id=7486" target="_blank">javascript依赖注入</a> [2015-06-01 23:25:30]</li><li><a href="https://blogread.cn/it/article.php?id=7482" target="_blank">正则表达式基础</a> [2015-06-01 10:03:59]</li><li><a href="https://blogread.cn/it/article.php?id=7475" target="_blank">JavaScript中真正的哈希映射（译）</a> [2015-05-29 20:10:43]</li><li><a href="https://blogread.cn/it/article.php?id=7474" target="_blank">iframe大小自适应</a> [2015-05-29 20:10:08]</li><li><a href="https://blogread.cn/it/article.php?id=7469" target="_blank">用 Virtual DOM 加速开发</a> [2015-05-29 20:00:11]</li><li><a href="https://blogread.cn/it/article.php?id=7460" target="_blank">React入门：关于虚拟DOM（Virtual DOM）</a> [2015-05-11 23:33:16]</li><li><a href="https://blogread.cn/it/article.php?id=7457" target="_blank">细说JavaScript中对象的属性和方法</a> [2015-05-11 23:22:08]</li><li><a href="https://blogread.cn/it/article.php?id=7453" target="_blank">编写一个简单的JavaScript模板引擎</a> [2015-04-26 23:00:33]</li><li><a href="https://blogread.cn/it/article.php?id=7446" target="_blank">javascript语句的执行过程分析</a> [2015-04-26 22:42:46]</li><li><a href="https://blogread.cn/it/article.php?id=7431" target="_blank">JavaScript模块的前世今生</a> [2015-04-08 14:19:31]</li><li><a href="https://blogread.cn/it/article.php?id=7385" target="_blank">jquery js 动态加载 js文件</a> [2015-02-14 14:07:45]</li><li><a href="https://blogread.cn/it/article.php?id=7378" target="_blank">我希望我知道的七个JavaScript技巧</a> [2015-02-06 22:27:24]</li><li><a href="https://blogread.cn/it/article.php?id=7371" target="_blank">图片动态局部毛玻璃模糊效果的实现</a> [2015-02-06 22:06:06]</li><li><a href="https://blogread.cn/it/article.php?id=7362" target="_blank">JavaScript：多维数组像ORDER BY一样实现多键值排序 </a> [2015-02-03 22:07:12]</li><li><a href="https://blogread.cn/it/article.php?id=7335" target="_blank">Android利用webView调用JavaScript</a> [2015-01-24 23:40:04]</li><li><a href="https://blogread.cn/it/article.php?id=7330" target="_blank">围住神经猫 1步玩法-”作弊”</a> [2015-01-24 23:16:57]</li><li><a href="https://blogread.cn/it/article.php?id=7323" target="_blank">如何在一个页面上让多个jQuery版本共存</a> [2015-01-23 23:49:54]</li><li><a href="https://blogread.cn/it/article.php?id=7322" target="_blank">JavaScript的闭包问题</a> [2015-01-23 23:49:11]</li><li><a href="https://blogread.cn/it/article.php?id=7319" target="_blank">揭秘JavaScript中谜一样的this</a> [2015-01-22 23:37:27]</li><li><a href="https://blogread.cn/it/article.php?id=7318" target="_blank">利用函数的惰性载入提高javascript代码性能</a> [2015-01-22 23:36:25]</li><li><a href="https://blogread.cn/it/article.php?id=7316" target="_blank">给你的网站添加 console.js</a> [2015-01-22 23:32:04]</li><li><a href="https://blogread.cn/it/article.php?id=7315" target="_blank">JavaScript中的this关键字</a> [2015-01-22 23:31:30]</li><li><a href="https://blogread.cn/it/article.php?id=7314" target="_blank">仅100行的JavaScript DOM操作类库</a> [2015-01-22 23:30:54]</li><li><a href="https://blogread.cn/it/article.php?id=7310" target="_blank">Javascript继承-原型的陷阱</a> [2015-01-21 23:51:49]</li><li><a href="https://blogread.cn/it/article.php?id=7309" target="_blank">高效jQuery的奥秘</a> [2015-01-21 23:46:20]</li><li><a href="https://blogread.cn/it/article.php?id=7308" target="_blank">JavaScript里的依赖注入</a> [2015-01-21 23:45:41]</li><li><a href="https://blogread.cn/it/article.php?id=7306" target="_blank">JavaScript的作用域和提升机制</a> [2015-01-21 23:43:40]</li><li><a href="https://blogread.cn/it/article.php?id=7305" target="_blank">每一个JavaScript开发者应该了解的浮点知识</a> [2015-01-21 23:42:41]</li><li><a href="https://blogread.cn/it/article.php?id=7303" target="_blank">JavaScript对象继承一瞥</a> [2015-01-21 23:40:47]</li><li><a href="https://blogread.cn/it/article.php?id=7300" target="_blank">认识javascript中的作用域和上下文</a> [2015-01-20 23:40:21]</li><li><a href="https://blogread.cn/it/article.php?id=7299" target="_blank">有趣的JavaScript原生数组函数</a> [2015-01-20 23:34:42]</li><li><a href="https://blogread.cn/it/article.php?id=7298" target="_blank">在JavaScript中什么时候使用==是正确的？</a> [2015-01-20 23:33:04]</li><li><a href="https://blogread.cn/it/article.php?id=7297" target="_blank">了解JavaScript的执行上下文</a> [2015-01-20 23:31:04]</li><li><a href="https://blogread.cn/it/article.php?id=7290" target="_blank">JavaScript 类型浅解</a> [2015-01-20 23:14:33]</li><li><a href="https://blogread.cn/it/article.php?id=7289" target="_blank">JavaScript 函数、作用域和继承</a> [2015-01-20 23:13:28]</li><li><a href="https://blogread.cn/it/article.php?id=7288" target="_blank">JavaScript优化循环</a> [2015-01-20 23:12:37]</li><li><a href="https://blogread.cn/it/article.php?id=7286" target="_blank">使用window.postMessage实现跨域通信</a> [2015-01-19 23:58:46]</li><li><a href="https://blogread.cn/it/article.php?id=7284" target="_blank">HTML 5 的data-* 自定义属性</a> [2015-01-19 23:55:37]</li><li><a href="https://blogread.cn/it/article.php?id=7283" target="_blank">利用js排序html表格</a> [2015-01-19 23:53:35]</li><li><a href="https://blogread.cn/it/article.php?id=7275" target="_blank">Underscore.js-精巧而强大实用功能库</a> [2015-01-19 23:37:38]</li><li><a href="https://blogread.cn/it/article.php?id=7271" target="_blank">关于请求被挂起页面加载缓慢问题的追查</a> [2015-01-17 00:06:49]</li><li><a href="https://blogread.cn/it/article.php?id=7267" target="_blank">从千分位格式化谈JS性能优化</a> [2015-01-14 13:54:20]</li><li><a href="https://blogread.cn/it/article.php?id=7244" target="_blank">消除疑问：CSS动画 VS JavaScript</a> [2015-01-11 23:39:59]</li><li><a href="https://blogread.cn/it/article.php?id=7242" target="_blank">jQuery选择器对应的DOM API ——选择元素</a> [2015-01-11 23:30:59]</li><li><a href="https://blogread.cn/it/article.php?id=7235" target="_blank">JavaScript內存优化</a> [2015-01-05 23:49:40]</li><li><a href="https://blogread.cn/it/article.php?id=7229" target="_blank">写了10年Javascript未必全了解的连续赋值运算</a> [2015-01-05 23:36:09]</li><li><a href="https://blogread.cn/it/article.php?id=7228" target="_blank">为什么++[[]][+[]]+[+[]]=10？</a> [2015-01-05 23:34:46]</li><li><a href="https://blogread.cn/it/article.php?id=7189" target="_blank">消除JavaScript闭包的一般方法</a> [2014-12-30 12:27:21]</li><li><a href="https://blogread.cn/it/article.php?id=7174" target="_blank">JavaScript实现的抛物线运动效果</a> [2014-12-10 23:07:04]</li><li><a href="https://blogread.cn/it/article.php?id=7166" target="_blank">JavaScript原型之路</a> [2014-12-06 20:40:13]</li><li><a href="https://blogread.cn/it/article.php?id=7147" target="_blank">XSS 前端防火墙 —— 可疑模块拦截</a> [2014-12-04 00:09:35]</li><li><a href="https://blogread.cn/it/article.php?id=7143" target="_blank">JavaScript中双叹号(!!)作用</a> [2014-12-03 23:51:47]</li><li><a href="https://blogread.cn/it/article.php?id=7096" target="_blank">程序员的“横向发展”</a> [2014-11-30 23:54:32]</li><li><a href="https://blogread.cn/it/article.php?id=7034" target="_blank">Javascript中的delete操作符</a> [2014-11-26 23:16:49]</li><li><a href="https://blogread.cn/it/article.php?id=7030" target="_blank">浏览器特性检测工具：Modernizr</a> [2014-11-26 22:59:34]</li><li><a href="https://blogread.cn/it/article.php?id=6977" target="_blank">jQuery的编码标准和最佳实践</a> [2014-11-22 23:20:57]</li><li><a href="https://blogread.cn/it/article.php?id=6967" target="_blank">7 天打造前端性能监控系统</a> [2014-11-21 22:59:13]</li><li><a href="https://blogread.cn/it/article.php?id=6966" target="_blank">从输入 URL 到页面加载完成的过程中都发生了什么事情？</a> [2014-11-21 00:14:31]</li><li><a href="https://blogread.cn/it/article.php?id=6963" target="_blank">实现动态验证码的思路</a> [2014-11-20 23:57:18]</li><li><a href="https://blogread.cn/it/article.php?id=6957" target="_blank">跨平台移动框架iMAG开发入门</a> [2014-11-19 23:30:42]</li><li><a href="https://blogread.cn/it/article.php?id=6944" target="_blank">jQuery 设置复选框选中状态的 BUG</a> [2014-11-19 23:01:54]</li><li><a href="https://blogread.cn/it/article.php?id=6942" target="_blank">js 面向对象日历实现原理详解</a> [2014-11-07 00:08:43]</li><li><a href="https://blogread.cn/it/article.php?id=6930" target="_blank">基于jQuery的简易手风琴切换插件</a> [2014-10-15 23:01:00]</li><li><a href="https://blogread.cn/it/article.php?id=6927" target="_blank">javascript运算符</a> [2014-10-15 22:50:19]</li><li><a href="https://blogread.cn/it/article.php?id=6920" target="_blank">如何捕获和分析 JavaScript Error</a> [2014-09-17 13:59:47]</li><li><a href="https://blogread.cn/it/article.php?id=6917" target="_blank">理解JavaScript 中的 this</a> [2014-09-17 13:44:52]</li><li><a href="https://blogread.cn/it/article.php?id=6914" target="_blank">javascript DOM操作中的insertAdjacentHTML方法</a> [2014-09-17 13:40:44]</li><li><a href="https://blogread.cn/it/article.php?id=6861" target="_blank">移动应用开发工具：PhoneGap与Titanium的比较</a> [2014-05-10 21:21:33]</li><li><a href="https://blogread.cn/it/article.php?id=6851" target="_blank">20年的C2C之路</a> [2014-04-21 12:38:20]</li><li><a href="https://blogread.cn/it/article.php?id=6849" target="_blank">动态创建iframe在IE下的两个问题</a> [2014-04-15 22:40:29]</li><li><a href="https://blogread.cn/it/article.php?id=6841" target="_blank">从千分位格式化谈JS性能优化</a> [2014-04-13 22:04:39]</li><li><a href="https://blogread.cn/it/article.php?id=6840" target="_blank">前端开发中Cookie那些事儿</a> [2014-04-08 22:59:37]</li><li><a href="https://blogread.cn/it/article.php?id=6804" target="_blank">Beforeunload打点丢失原因分析及解决方案</a> [2014-03-19 22:42:44]</li><li><a href="https://blogread.cn/it/article.php?id=6783" target="_blank">防止表单重复提交的几种策略</a> [2013-11-20 23:55:45]</li><li><a href="https://blogread.cn/it/article.php?id=6745" target="_blank">如何更好用业余时间做互联网创业？</a> [2013-10-16 22:34:23]</li><li><a href="https://blogread.cn/it/article.php?id=6722" target="_blank">2014网易前端开发笔试题笔记</a> [2013-10-08 12:14:44]</li><li><a href="https://blogread.cn/it/article.php?id=6721" target="_blank">谁说设计师不会写代码？—Photoshop脚本语言简介</a> [2013-09-26 22:34:33]</li><li><a href="https://blogread.cn/it/article.php?id=6707" target="_blank">通过WebRTC获取摄像头影像</a> [2013-09-23 13:56:16]</li><li><a href="https://blogread.cn/it/article.php?id=6703" target="_blank">实现一下webapp的手机摇一摇功能</a> [2013-09-23 13:48:42]</li><li><a href="https://blogread.cn/it/article.php?id=6688" target="_blank">10分钟尝试10种编程语言</a> [2013-09-15 22:33:22]</li><li><a href="https://blogread.cn/it/article.php?id=6686" target="_blank">通过WebRTC获取摄像头影像</a> [2013-09-15 22:28:03]</li><li><a href="https://blogread.cn/it/article.php?id=6642" target="_blank">JavaScript 中的陷阱</a> [2013-08-26 23:09:39]</li><li><a href="https://blogread.cn/it/article.php?id=6633" target="_blank">程序员眼里IE浏览器是什么样的</a> [2013-08-21 13:30:53]</li><li><a href="https://blogread.cn/it/article.php?id=6629" target="_blank">[译文]关于移动Web性能的5个神话</a> [2013-08-21 13:24:10]</li><li><a href="https://blogread.cn/it/article.php?id=6609" target="_blank">使用SeaJS实现模块化JavaScript开发</a> [2013-08-13 13:35:22]</li><li><a href="https://blogread.cn/it/article.php?id=6608" target="_blank">学你妹的计算机！</a> [2013-08-13 13:34:03]</li><li><a href="https://blogread.cn/it/article.php?id=6604" target="_blank">我的博客系统折腾手记暨papery正式发布</a> [2013-08-13 13:05:47]</li><li><a href="https://blogread.cn/it/article.php?id=6603" target="_blank">javascript继承机制</a> [2013-08-13 13:04:31]</li><li><a href="https://blogread.cn/it/article.php?id=6583" target="_blank">JQuery,Extjs,YUI,Prototype,Dojo 等JS框架的区别和应用场景简述</a> [2013-08-02 13:29:59]</li><li><a href="https://blogread.cn/it/article.php?id=6574" target="_blank">JavaScript 设置浏览器标题闪动</a> [2013-07-31 13:18:59]</li><li><a href="https://blogread.cn/it/article.php?id=6567" target="_blank">如何成为一名优秀的web前端工程师（前端攻城师）？</a> [2013-07-31 12:53:05]</li><li><a href="https://blogread.cn/it/article.php?id=6555" target="_blank">Javascript触屏手势库-jTouch</a> [2013-07-29 23:13:05]</li><li><a href="https://blogread.cn/it/article.php?id=6537" target="_blank">用 javascript 判断 IE 版本号</a> [2013-07-28 15:28:59]</li><li><a href="https://blogread.cn/it/article.php?id=6506" target="_blank">javascript函数的throttle和debounce</a> [2013-07-08 22:43:51]</li><li><a href="https://blogread.cn/it/article.php?id=6499" target="_blank">jQuery的data()方法</a> [2013-07-07 21:49:46]</li><li><a href="https://blogread.cn/it/article.php?id=6482" target="_blank">谈谈 jQuery 中的防冲突（noConflict）机制</a> [2013-06-21 00:05:59]</li><li><a href="https://blogread.cn/it/article.php?id=6481" target="_blank">浏览器的渲染原理简介</a> [2013-06-19 23:36:50]</li><li><a href="https://blogread.cn/it/article.php?id=6478" target="_blank">Js事件监听封装（支持匿名函数）</a> [2013-06-18 13:57:30]</li><li><a href="https://blogread.cn/it/article.php?id=6467" target="_blank">Javascript 装载和执行</a> [2013-06-09 13:20:27]</li><li><a href="https://blogread.cn/it/article.php?id=6451" target="_blank">开发者调试工具Chrome Workspace</a> [2013-06-02 20:19:05]</li><li><a href="https://blogread.cn/it/article.php?id=6445" target="_blank">JavaScript的5种调用函数的方法</a> [2013-05-29 23:09:58]</li><li><a href="https://blogread.cn/it/article.php?id=6432" target="_blank">如何判断Event事件是否是用户主动执行的</a> [2013-05-28 22:14:04]</li><li><a href="https://blogread.cn/it/article.php?id=6430" target="_blank">现代浏览器中内置的几个可以等效替代jQuery的功能</a> [2013-05-28 22:09:46]</li><li><a href="https://blogread.cn/it/article.php?id=6429" target="_blank">Javascript中的delete操作符</a> [2013-05-28 22:08:10]</li><li><a href="https://blogread.cn/it/article.php?id=6407" target="_blank">使用python/casperjs编写终极爬虫-客户端App的抓取</a> [2013-05-19 23:27:36]</li><li><a href="https://blogread.cn/it/article.php?id=6400" target="_blank">Javascript的那些事儿</a> [2013-05-16 23:42:19]</li><li><a href="https://blogread.cn/it/article.php?id=6375" target="_blank">如何成为一名优秀的前端工程师</a> [2013-05-08 13:47:33]</li><li><a href="https://blogread.cn/it/article.php?id=6313" target="_blank">JavaScript深度克隆（深度拷贝）一个对象</a> [2013-03-11 13:55:16]</li><li><a href="https://blogread.cn/it/article.php?id=6233" target="_blank">jQuery链式操作</a> [2013-02-28 23:24:16]</li><li><a href="https://blogread.cn/it/article.php?id=6232" target="_blank">Web前端工程师编程能力飞升之路</a> [2013-02-28 23:22:40]</li><li><a href="https://blogread.cn/it/article.php?id=6225" target="_blank">改变文章的字号大小</a> [2013-02-19 12:00:35]</li><li><a href="https://blogread.cn/it/article.php?id=6224" target="_blank">jQuery 1.9升级指南</a> [2013-02-19 11:58:21]</li><li><a href="https://blogread.cn/it/article.php?id=6211" target="_blank">了解前端内存泄露</a> [2013-01-18 14:04:04]</li><li><a href="https://blogread.cn/it/article.php?id=6208" target="_blank">DOM中nodeName、nodeValue 及 nodeType的说明</a> [2013-01-18 13:56:28]</li><li><a href="https://blogread.cn/it/article.php?id=6185" target="_blank">web开发设计人员不可不用的在线web工具和应用</a> [2013-01-16 13:48:45]</li><li><a href="https://blogread.cn/it/article.php?id=6178" target="_blank">深入理解Javascript之执行上下文(Execution Context)</a> [2013-01-10 22:38:47]</li><li><a href="https://blogread.cn/it/article.php?id=6172" target="_blank">flv网页播放器源码</a> [2013-01-10 22:22:41]</li><li><a href="https://blogread.cn/it/article.php?id=6168" target="_blank">如何判断自己是否到了该辞职的时候</a> [2013-01-10 22:14:10]</li><li><a href="https://blogread.cn/it/article.php?id=6160" target="_blank">javascript事件触发器fireEvent和dispatchEvent</a> [2013-01-08 13:00:53]</li><li><a href="https://blogread.cn/it/article.php?id=6158" target="_blank">Node.js和testacular的安装与配置</a> [2012-12-25 12:31:02]</li><li><a href="https://blogread.cn/it/article.php?id=6143" target="_blank">正则表达式 — QQ微信、优酷前端 邮箱正则表达式验证 Bug</a> [2012-12-23 23:29:43]</li><li><a href="https://blogread.cn/it/article.php?id=6128" target="_blank">缓存为王</a> [2012-12-21 13:39:42]</li><li><a href="https://blogread.cn/it/article.php?id=6125" target="_blank">JavaScript中两个感叹号（!!）的作用</a> [2012-12-21 13:35:49]</li><li><a href="https://blogread.cn/it/article.php?id=6124" target="_blank">使用window.postMessage实现跨域通信</a> [2012-12-21 13:35:11]</li><li><a href="https://blogread.cn/it/article.php?id=6112" target="_blank">IE BUG相关文章集合</a> [2012-12-19 13:30:03]</li><li><a href="https://blogread.cn/it/article.php?id=6111" target="_blank">关于前端开发</a> [2012-12-18 23:25:27]</li><li><a href="https://blogread.cn/it/article.php?id=6110" target="_blank">javascript运算/转换技巧</a> [2012-12-18 23:20:19]</li><li><a href="https://blogread.cn/it/article.php?id=6105" target="_blank">使用 SourceMap 来进行前端代码调试</a> [2012-12-18 23:06:31]</li><li><a href="https://blogread.cn/it/article.php?id=6092" target="_blank">取得当前script元素的src(path)</a> [2012-12-14 14:07:00]</li><li><a href="https://blogread.cn/it/article.php?id=6081" target="_blank">javascript扩展Array(数组)类</a> [2012-12-11 13:40:11]</li><li><a href="https://blogread.cn/it/article.php?id=6074" target="_blank">10个超棒jQuery表单操作代码片段</a> [2012-12-09 20:30:08]</li><li><a href="https://blogread.cn/it/article.php?id=6065" target="_blank">谈产品经理的转行</a> [2012-12-08 23:02:32]</li><li><a href="https://blogread.cn/it/article.php?id=6044" target="_blank">JavaScript定时机制、以及浏览器渲染机制 浅谈</a> [2012-12-06 14:04:39]</li><li><a href="https://blogread.cn/it/article.php?id=6043" target="_blank">《javascript权威教程》、《javascript 王者归来》等几本书</a> [2012-12-06 14:02:08]</li><li><a href="https://blogread.cn/it/article.php?id=6035" target="_blank">通过使用Chrome的开发者工具来学习JavaScript</a> [2012-12-06 13:42:09]</li><li><a href="https://blogread.cn/it/article.php?id=6023" target="_blank">tabIndent.js让你在Textarea中也能用Tab键</a> [2012-12-03 23:55:04]</li><li><a href="https://blogread.cn/it/article.php?id=6016" target="_blank">国内团购网前端严重安全漏洞– 以满座网为案例分析</a> [2012-11-27 13:44:15]</li><li><a href="https://blogread.cn/it/article.php?id=6015" target="_blank">关于“浏览器无法拦截的弹出窗口”、IE、Firefox弹出新窗口</a> [2012-11-27 13:41:52]</li><li><a href="https://blogread.cn/it/article.php?id=6014" target="_blank">jQuery 教程的一点总结</a> [2012-11-27 13:40:50]</li><li><a href="https://blogread.cn/it/article.php?id=6005" target="_blank">为什么通过前端 .js 记用户日志会丢数据</a> [2012-11-26 13:49:17]</li><li><a href="https://blogread.cn/it/article.php?id=5997" target="_blank">IE的documentMode属性</a> [2012-11-11 23:46:28]</li><li><a href="https://blogread.cn/it/article.php?id=5976" target="_blank">匿名函数中undefined形参疑问</a> [2012-11-01 13:23:40]</li><li><a href="https://blogread.cn/it/article.php?id=5961" target="_blank">构建web前端异常监控系统–FdSafe</a> [2012-10-28 23:20:05]</li><li><a href="https://blogread.cn/it/article.php?id=5953" target="_blank">Web标志(The Mark of The Web)摘记</a> [2012-10-26 13:32:20]</li><li><a href="https://blogread.cn/it/article.php?id=5946" target="_blank">网站统计中的数据收集原理及实现</a> [2012-10-26 13:09:06]</li><li><a href="https://blogread.cn/it/article.php?id=5942" target="_blank">60多个超炫的视差滚动效果网站设计欣赏</a> [2012-10-26 00:25:29]</li><li><a href="https://blogread.cn/it/article.php?id=5929" target="_blank">JS判断鼠标从什么方向进入一个容器</a> [2012-10-22 22:13:29]</li><li><a href="https://blogread.cn/it/article.php?id=5919" target="_blank">微博Karma和其算法的一些简单介绍</a> [2012-10-22 13:19:38]</li><li><a href="https://blogread.cn/it/article.php?id=5916" target="_blank">HoverDir响应鼠标移动方向的悬停效果插件</a> [2012-10-22 13:16:24]</li><li><a href="https://blogread.cn/it/article.php?id=5912" target="_blank">JavaScript运算符</a> [2012-10-14 23:29:06]</li><li><a href="https://blogread.cn/it/article.php?id=5905" target="_blank">基于有限状态机的交互组件设计与实现</a> [2012-10-14 22:35:25]</li><li><a href="https://blogread.cn/it/article.php?id=5875" target="_blank">巧解 JavaScript 中的嵌套替换</a> [2012-09-20 14:01:04]</li><li><a href="https://blogread.cn/it/article.php?id=5870" target="_blank">网站性能评测点</a> [2012-09-20 13:53:54]</li><li><a href="https://blogread.cn/it/article.php?id=5803" target="_blank">简单js+css实现模拟自定义select样式</a> [2012-09-10 23:29:05]</li><li><a href="https://blogread.cn/it/article.php?id=5793" target="_blank">JS如何实现响应滚轮（同时设置滚动条无效）</a> [2012-09-06 23:59:27]</li><li><a href="https://blogread.cn/it/article.php?id=5792" target="_blank">JS（如何判断）鼠标滚轮事件解析</a> [2012-09-06 23:54:43]</li><li><a href="https://blogread.cn/it/article.php?id=5788" target="_blank">使用jQuery开发一个带有密码强度检验的超酷注册页面</a> [2012-09-06 23:42:16]</li><li><a href="https://blogread.cn/it/article.php?id=5755" target="_blank">优秀的JavaScript模块是怎样炼成的</a> [2012-08-31 00:05:45]</li><li><a href="https://blogread.cn/it/article.php?id=5747" target="_blank">Google Analytics的新秘密——如何定义Visit</a> [2012-08-28 23:13:49]</li><li><a href="https://blogread.cn/it/article.php?id=5744" target="_blank">beforeunload丢失率统计</a> [2012-08-28 14:18:38]</li><li><a href="https://blogread.cn/it/article.php?id=5705" target="_blank">脚本语言ymd：介绍</a> [2012-08-20 23:40:24]</li><li><a href="https://blogread.cn/it/article.php?id=5679" target="_blank">挑战网站分析中的大众智慧（1）——Bounce Rate</a> [2012-08-14 14:04:28]</li><li><a href="https://blogread.cn/it/article.php?id=5650" target="_blank">创业的人招聘怎样的人靠谱？</a> [2012-08-07 13:42:07]</li><li><a href="https://blogread.cn/it/article.php?id=5645" target="_blank">js图片延时加载（jquery特效）</a> [2012-08-07 13:36:08]</li><li><a href="https://blogread.cn/it/article.php?id=5607" target="_blank">“很有激情”的创业预备队员的困惑</a> [2012-07-30 23:49:11]</li><li><a href="https://blogread.cn/it/article.php?id=5596" target="_blank">意识流</a> [2012-07-27 14:11:57]</li><li><a href="https://blogread.cn/it/article.php?id=5548" target="_blank">一种基于flex的可视化多层流量切分界面的实现</a> [2012-07-09 23:10:17]</li><li><a href="https://blogread.cn/it/article.php?id=5520" target="_blank">JavaScript解析：让搜索引擎看到更真实的网页</a> [2012-07-04 14:03:22]</li><li><a href="https://blogread.cn/it/article.php?id=5506" target="_blank">谈谈对O2O产品的一些看法</a> [2012-06-19 23:57:47]</li><li><a href="https://blogread.cn/it/article.php?id=5489" target="_blank">高性能JavaScript模板引擎原理解析</a> [2012-06-17 17:54:54]</li><li><a href="https://blogread.cn/it/article.php?id=5457" target="_blank">云标签，关键字图排版 html5 canvas版（一）</a> [2012-06-10 21:52:12]</li><li><a href="https://blogread.cn/it/article.php?id=5438" target="_blank">Web设计师需要编程知识吗？</a> [2012-06-07 00:10:27]</li><li><a href="https://blogread.cn/it/article.php?id=5397" target="_blank">使用Javascript获取页面所在目录的绝对路径</a> [2012-05-28 12:36:58]</li><li><a href="https://blogread.cn/it/article.php?id=5314" target="_blank">Cookie安全漫谈</a> [2012-05-11 00:01:25]</li><li><a href="https://blogread.cn/it/article.php?id=5295" target="_blank">DOM元素上jQuery事件几点学习</a> [2012-05-08 00:05:47]</li><li><a href="https://blogread.cn/it/article.php?id=5289" target="_blank">中国创业环境之殇</a> [2012-05-07 23:53:56]</li><li><a href="https://blogread.cn/it/article.php?id=5258" target="_blank">Juicer – 一个Javascript模板引擎的实现和优化</a> [2012-04-27 00:03:09]</li><li><a href="https://blogread.cn/it/article.php?id=5257" target="_blank">JAVASCRIPT完美实现UTF8页面提交数据到GB2312</a> [2012-04-26 23:55:45]</li><li><a href="https://blogread.cn/it/article.php?id=5251" target="_blank">如何制作chrome扩展程序</a> [2012-04-26 23:36:39]</li><li><a href="https://blogread.cn/it/article.php?id=5207" target="_blank">初识PhoneGap</a> [2012-04-12 13:34:32]</li><li><a href="https://blogread.cn/it/article.php?id=5205" target="_blank">为什么我们要学习Haskell这样的编程语言</a> [2012-04-12 13:33:09]</li><li><a href="https://blogread.cn/it/article.php?id=5204" target="_blank">Object类相关的属性，方法和操作符</a> [2012-04-12 13:32:38]</li><li><a href="https://blogread.cn/it/article.php?id=5176" target="_blank">javascript实现简单的链式调用</a> [2012-04-07 21:46:19]</li><li><a href="https://blogread.cn/it/article.php?id=5135" target="_blank">轻触，数据美丽的外衣</a> [2012-03-31 23:32:36]</li><li><a href="https://blogread.cn/it/article.php?id=5132" target="_blank">JavaScript Slider效果实现思路</a> [2012-03-31 23:28:03]</li><li><a href="https://blogread.cn/it/article.php?id=5125" target="_blank">设计师也需要了解的一些前端知识</a> [2012-03-31 22:39:03]</li><li><a href="https://blogread.cn/it/article.php?id=5110" target="_blank">js防刷新的倒计时代码</a> [2012-03-25 21:43:50]</li><li><a href="https://blogread.cn/it/article.php?id=5103" target="_blank">网页游戏中的动物世界法则和三角形法则</a> [2012-03-25 21:35:04]</li><li><a href="https://blogread.cn/it/article.php?id=5099" target="_blank">javascript实现简单的链式调用</a> [2012-03-25 21:17:43]</li><li><a href="https://blogread.cn/it/article.php?id=5065" target="_blank">一个独立程序员对自己近九个月工作生活的回顾</a> [2012-03-12 23:53:17]</li><li><a href="https://blogread.cn/it/article.php?id=5056" target="_blank">理解Javascript的闭包</a> [2012-03-12 23:34:51]</li><li><a href="https://blogread.cn/it/article.php?id=5032" target="_blank">迁户口实录(深圳集体户到杭州个户)</a> [2012-03-11 22:04:39]</li><li><a href="https://blogread.cn/it/article.php?id=5027" target="_blank">延迟加载图片的jQuery插件-Lazy Load Plugin for JQuery</a> [2012-03-04 20:47:33]</li><li><a href="https://blogread.cn/it/article.php?id=5017" target="_blank">[译]原生全屏Javascript API</a> [2012-03-04 18:21:23]</li><li><a href="https://blogread.cn/it/article.php?id=5000" target="_blank">如何在WordPress文章内插入onclick</a> [2012-03-04 17:44:42]</li><li><a href="https://blogread.cn/it/article.php?id=4996" target="_blank">再谈javascript面向对象编程</a> [2012-03-04 17:40:56]</li><li><a href="https://blogread.cn/it/article.php?id=4989" target="_blank">Javascript 静态类的实现</a> [2012-03-04 17:33:21]</li><li><a href="https://blogread.cn/it/article.php?id=4974" target="_blank">Javascript 类的实现</a> [2012-02-26 23:14:35]</li><li><a href="https://blogread.cn/it/article.php?id=4940" target="_blank">Javascript 中的 call 和 apply</a> [2012-02-05 23:10:08]</li><li><a href="https://blogread.cn/it/article.php?id=4938" target="_blank">javascript插入样式</a> [2012-02-05 23:06:38]</li><li><a href="https://blogread.cn/it/article.php?id=4931" target="_blank">跨域修改iframe内的文字</a> [2012-02-05 15:32:23]</li><li><a href="https://blogread.cn/it/article.php?id=4928" target="_blank">js和css的顺序关系</a> [2012-02-05 15:30:22]</li><li><a href="https://blogread.cn/it/article.php?id=4903" target="_blank">javascript的configuration/interface变换</a> [2012-01-29 20:53:26]</li><li><a href="https://blogread.cn/it/article.php?id=4873" target="_blank">chrome扩展应用开发教程之开发chrome应用基础</a> [2012-01-27 19:01:53]</li><li><a href="https://blogread.cn/it/article.php?id=4863" target="_blank">像php一样奔跑的js代码</a> [2012-01-27 18:51:38]</li><li><a href="https://blogread.cn/it/article.php?id=4841" target="_blank">最奇特的编程语言特征</a> [2012-01-27 18:05:22]</li><li><a href="https://blogread.cn/it/article.php?id=4840" target="_blank">设置样式方法setStyle</a> [2012-01-27 18:04:32]</li><li><a href="https://blogread.cn/it/article.php?id=4838" target="_blank">受禁锢的异步编程思维</a> [2012-01-27 18:01:06]</li><li><a href="https://blogread.cn/it/article.php?id=4830" target="_blank">Javascript 面向对象编程</a> [2012-01-24 14:06:20]</li><li><a href="https://blogread.cn/it/article.php?id=4822" target="_blank">拒绝平庸――浅谈WEB登录页面设计</a> [2012-01-24 13:52:15]</li><li><a href="https://blogread.cn/it/article.php?id=4809" target="_blank">Javascript绝句欣赏</a> [2012-01-24 13:37:54]</li><li><a href="https://blogread.cn/it/article.php?id=4778" target="_blank">【外刊IT评论网】为什么 ++[[]][+[]]+[+[]] = 10 ？</a> [2012-01-14 22:37:02]</li><li><a href="https://blogread.cn/it/article.php?id=4776" target="_blank">暂停页面资源占用</a> [2012-01-14 22:28:38]</li><li><a href="https://blogread.cn/it/article.php?id=4752" target="_blank">瀑布布局的JavaScript实现方式</a> [2012-01-03 23:48:47]</li><li><a href="https://blogread.cn/it/article.php?id=4749" target="_blank">JavaScript与设计模式</a> [2012-01-03 23:46:43]</li><li><a href="https://blogread.cn/it/article.php?id=4747" target="_blank">Node.js中相同模块是否会被加载多次？</a> [2012-01-03 23:45:06]</li><li><a href="https://blogread.cn/it/article.php?id=4697" target="_blank">知心怪蜀黍NO.1 网站编辑怎样转内容运营</a> [2011-12-21 00:17:21]</li><li><a href="https://blogread.cn/it/article.php?id=4683" target="_blank">Google+开发团队分享经验</a> [2011-12-18 22:24:10]</li><li><a href="https://blogread.cn/it/article.php?id=4680" target="_blank">HTML5 Canvas(画布)教程 </a> [2011-12-18 22:19:47]</li><li><a href="https://blogread.cn/it/article.php?id=4674" target="_blank">javascript中神奇的（+）加操作符</a> [2011-12-18 21:57:34]</li><li><a href="https://blogread.cn/it/article.php?id=4669" target="_blank">PhoneGap应用开发的那些坑爹事儿</a> [2011-12-14 13:40:46]</li><li><a href="https://blogread.cn/it/article.php?id=4661" target="_blank">移动互联网api设计实践</a> [2011-12-11 16:21:09]</li><li><a href="https://blogread.cn/it/article.php?id=4656" target="_blank">JavaScript6看上去很美</a> [2011-12-11 15:53:55]</li><li><a href="https://blogread.cn/it/article.php?id=4655" target="_blank">Web开发中需要了解的东西</a> [2011-12-11 15:38:12]</li><li><a href="https://blogread.cn/it/article.php?id=4652" target="_blank">浅析来源分析的数据可视化</a> [2011-12-11 15:34:34]</li><li><a href="https://blogread.cn/it/article.php?id=4642" target="_blank">jQuery事件的冒泡过程</a> [2011-11-23 23:57:56]</li><li><a href="https://blogread.cn/it/article.php?id=4616" target="_blank">javascript嵌套函数的效率问题</a> [2011-11-21 00:07:40]</li><li><a href="https://blogread.cn/it/article.php?id=4602" target="_blank">IE6中javascript文件开启Gzip出现代码不执行情况</a> [2011-11-16 23:43:57]</li><li><a href="https://blogread.cn/it/article.php?id=4594" target="_blank">正确理解javascript的this关键字</a> [2011-11-16 00:12:45]</li><li><a href="https://blogread.cn/it/article.php?id=4577" target="_blank">javascript的String.replace的妙用</a> [2011-11-13 23:59:31]</li><li><a href="https://blogread.cn/it/article.php?id=4566" target="_blank">我做前端一年半</a> [2011-11-13 21:11:21]</li><li><a href="https://blogread.cn/it/article.php?id=4554" target="_blank">javascript作用域和作用域链</a> [2011-11-06 22:42:21]</li><li><a href="https://blogread.cn/it/article.php?id=4545" target="_blank">如何用 JS 实现 3D 赛车效果</a> [2011-11-06 22:30:41]</li><li><a href="https://blogread.cn/it/article.php?id=4544" target="_blank">JS 3D 模型</a> [2011-11-06 22:30:16]</li><li><a href="https://blogread.cn/it/article.php?id=4536" target="_blank">Javascript模板引擎分享</a> [2011-11-04 22:22:13]</li><li><a href="https://blogread.cn/it/article.php?id=4533" target="_blank">【外刊IT评论网】关于node.js语言的讨论</a> [2011-11-04 22:15:51]</li><li><a href="https://blogread.cn/it/article.php?id=4506" target="_blank">细节魔鬼与精简团队</a> [2011-10-18 23:29:39]</li><li><a href="https://blogread.cn/it/article.php?id=4492" target="_blank">javascript获取隐藏dom的宽高</a> [2011-10-14 14:01:24]</li><li><a href="https://blogread.cn/it/article.php?id=4490" target="_blank">nodejs教程：安装及配置app.js文件</a> [2011-10-14 13:59:03]</li><li><a href="https://blogread.cn/it/article.php?id=4466" target="_blank">新版微博体验</a> [2011-10-13 14:05:19]</li><li><a href="https://blogread.cn/it/article.php?id=4464" target="_blank">stream.js ：一个新的JavaScript数据结构</a> [2011-10-13 13:57:53]</li><li><a href="https://blogread.cn/it/article.php?id=4442" target="_blank">js 获取url的get传值函数</a> [2011-10-11 23:49:06]</li><li><a href="https://blogread.cn/it/article.php?id=4437" target="_blank">前端要给力之：分解对象构造过程new()</a> [2011-10-04 18:04:09]</li><li><a href="https://blogread.cn/it/article.php?id=4425" target="_blank">div+css+js无缝滚动代码</a> [2011-09-26 23:28:14]</li><li><a href="https://blogread.cn/it/article.php?id=4400" target="_blank">规范自己的JavaScript书写 </a> [2011-09-21 23:22:22]</li><li><a href="https://blogread.cn/it/article.php?id=4398" target="_blank">html中链接地址的重要性</a> [2011-09-21 23:16:45]</li><li><a href="https://blogread.cn/it/article.php?id=4395" target="_blank">js编码之 encodeURIComponent</a> [2011-09-21 22:24:17]</li><li><a href="https://blogread.cn/it/article.php?id=4389" target="_blank">为什么招不到人</a> [2011-09-21 13:36:24]</li><li><a href="https://blogread.cn/it/article.php?id=4386" target="_blank">前端要给力之：原子，与原子联结的友类、友函数</a> [2011-09-20 22:34:21]</li><li><a href="https://blogread.cn/it/article.php?id=4370" target="_blank">jquery实现的回车(Enter)替换为Tab键</a> [2011-09-19 23:42:51]</li><li><a href="https://blogread.cn/it/article.php?id=4368" target="_blank">Jquery通用表单验证类</a> [2011-09-19 23:41:14]</li><li><a href="https://blogread.cn/it/article.php?id=4367" target="_blank">遍历一个对象并执行其中的方法</a> [2011-09-19 23:40:13]</li><li><a href="https://blogread.cn/it/article.php?id=4337" target="_blank">瀑布流布局浅析</a> [2011-09-16 00:05:55]</li><li><a href="https://blogread.cn/it/article.php?id=4310" target="_blank">用 JavaScript 对 JSON 进行模式匹配 (Part 2 - 实现)</a> [2011-09-07 23:20:04]</li><li><a href="https://blogread.cn/it/article.php?id=4309" target="_blank">用 JavaScript 对 JSON 进行模式匹配 (Part 1 - 设计)</a> [2011-09-07 23:19:05]</li><li><a href="https://blogread.cn/it/article.php?id=4275" target="_blank">使用canvas绘制时钟</a> [2011-09-04 22:35:51]</li><li><a href="https://blogread.cn/it/article.php?id=4271" target="_blank">什么是Node？</a> [2011-09-04 14:23:49]</li><li><a href="https://blogread.cn/it/article.php?id=4238" target="_blank">使用navigator.geolocation来获取用户的地理位置信息</a> [2011-08-23 13:41:03]</li><li><a href="https://blogread.cn/it/article.php?id=4235" target="_blank">iframe自适应高度代码</a> [2011-08-23 13:24:07]</li><li><a href="https://blogread.cn/it/article.php?id=4201" target="_blank">使用JavaScript和Canvas开发游戏（五）</a> [2011-08-21 10:35:52]</li><li><a href="https://blogread.cn/it/article.php?id=4200" target="_blank">使用JavaScript和Canvas开发游戏（四）</a> [2011-08-21 10:28:43]</li><li><a href="https://blogread.cn/it/article.php?id=4199" target="_blank">使用JavaScript和Canvas开发游戏（三）</a> [2011-08-21 10:25:18]</li><li><a href="https://blogread.cn/it/article.php?id=4198" target="_blank">使用JavaScript和Canvas开发游戏（二）</a> [2011-08-21 10:21:26]</li><li><a href="https://blogread.cn/it/article.php?id=4179" target="_blank">javascript的词法作用域</a> [2011-08-19 22:55:43]</li><li><a href="https://blogread.cn/it/article.php?id=4178" target="_blank">使用JavaScript和Canvas开发游戏（一）</a> [2011-08-18 13:50:53]</li><li><a href="https://blogread.cn/it/article.php?id=4177" target="_blank">微博，将让新浪血尽而死</a> [2011-08-18 13:49:59]</li><li><a href="https://blogread.cn/it/article.php?id=4149" target="_blank">javascript变量类型</a> [2011-08-14 15:49:27]</li><li><a href="https://blogread.cn/it/article.php?id=4134" target="_blank">IE的fireEvent方法</a> [2011-08-09 08:25:46]</li><li><a href="https://blogread.cn/it/article.php?id=4125" target="_blank">JavaScript：假如default不是switch的最后一项</a> [2011-08-09 08:13:19]</li><li><a href="https://blogread.cn/it/article.php?id=4120" target="_blank">使用JavaScript和Canvas开发游戏</a> [2011-08-09 08:06:05]</li><li><a href="https://blogread.cn/it/article.php?id=4119" target="_blank">强大的纯JS数据图工具-flot</a> [2011-08-05 13:51:45]</li><li><a href="https://blogread.cn/it/article.php?id=4113" target="_blank">javascript匿名函数</a> [2011-08-05 13:44:04]</li><li><a href="https://blogread.cn/it/article.php?id=4090" target="_blank">你的网站使用Flash了吗？</a> [2011-07-30 21:54:56]</li><li><a href="https://blogread.cn/it/article.php?id=4087" target="_blank">三谈类型问题：ECMAScript为什么错了？</a> [2011-07-30 21:47:01]</li><li><a href="https://blogread.cn/it/article.php?id=4081" target="_blank">再谈JavaScript的数据类型问题</a> [2011-07-30 21:37:42]</li><li><a href="https://blogread.cn/it/article.php?id=4074" target="_blank">确认框的设计</a> [2011-07-30 21:16:39]</li><li><a href="https://blogread.cn/it/article.php?id=4072" target="_blank">JSON对象和字符串之间的相互转换</a> [2011-07-30 20:35:01]</li><li><a href="https://blogread.cn/it/article.php?id=4070" target="_blank">10种方式实现跨域资源的共享</a> [2011-07-26 13:43:28]</li><li><a href="https://blogread.cn/it/article.php?id=4069" target="_blank">前端开发中HTML与javascript的常用字符编码</a> [2011-07-26 13:42:25]</li><li><a href="https://blogread.cn/it/article.php?id=4052" target="_blank">精于图片处理的10款jQuery插件</a> [2011-07-24 14:56:36]</li><li><a href="https://blogread.cn/it/article.php?id=4051" target="_blank">十款Firefox插件帮助Web开发者提高效率</a> [2011-07-24 14:56:15]</li><li><a href="https://blogread.cn/it/article.php?id=4049" target="_blank">给数据穿上美丽的外衣</a> [2011-07-24 14:55:27]</li><li><a href="https://blogread.cn/it/article.php?id=4048" target="_blank">使用 HTML5 可以做的五件很棒的事情</a> [2011-07-24 14:55:01]</li><li><a href="https://blogread.cn/it/article.php?id=4042" target="_blank">JavaScript是Web的汇编语言（二）：疯狂，亦或只是精神错乱？</a> [2011-07-22 00:04:25]</li><li><a href="https://blogread.cn/it/article.php?id=4041" target="_blank">JavaScript是Web的汇编语言（一）：语义Web已死！</a> [2011-07-22 00:03:10]</li><li><a href="https://blogread.cn/it/article.php?id=4040" target="_blank">IE6中a标签location.href失效解决方法</a> [2011-07-22 00:01:37]</li><li><a href="https://blogread.cn/it/article.php?id=4026" target="_blank">关于JavaScript中Function Declaration与Function Expression的进一步说明</a> [2011-07-18 13:40:39]</li><li><a href="https://blogread.cn/it/article.php?id=4022" target="_blank">使用SeaJS实现模块化JavaScript开发</a> [2011-07-18 13:35:39]</li><li><a href="https://blogread.cn/it/article.php?id=4021" target="_blank">在SeaJS中实现html模板文件的加载（Temod介绍）</a> [2011-07-18 13:34:43]</li><li><a href="https://blogread.cn/it/article.php?id=4019" target="_blank">用In.js颗粒化管理、加载你的Javascript模块</a> [2011-07-18 12:31:22]</li><li><a href="https://blogread.cn/it/article.php?id=4000" target="_blank">解决jQuery动画在chrome下暴走的问题</a> [2011-07-15 00:13:53]</li><li><a href="https://blogread.cn/it/article.php?id=3997" target="_blank">javascript事件：获取事件对象getEvent函数</a> [2011-07-15 00:03:45]</li><li><a href="https://blogread.cn/it/article.php?id=3988" target="_blank">Javascript匿名函数解读</a> [2011-07-12 13:49:11]</li><li><a href="https://blogread.cn/it/article.php?id=3984" target="_blank">华丽丽的HTML5新特性</a> [2011-07-12 13:34:57]</li><li><a href="https://blogread.cn/it/article.php?id=3983" target="_blank">jQuery判断一个元素是否为另一个元素的子元素(或者其本身)</a> [2011-07-12 13:32:45]</li><li><a href="https://blogread.cn/it/article.php?id=3977" target="_blank">Javascript和CSS浏览器兼容总结</a> [2011-07-09 22:44:14]</li><li><a href="https://blogread.cn/it/article.php?id=3969" target="_blank">新浪微博jsSDK操作指南</a> [2011-07-09 22:31:20]</li><li><a href="https://blogread.cn/it/article.php?id=3960" target="_blank">JavaScript逻辑运算符及优先级</a> [2011-07-06 23:48:25]</li><li><a href="https://blogread.cn/it/article.php?id=3953" target="_blank">7款实用的Javascript代码高亮脚本</a> [2011-07-05 23:21:25]</li><li><a href="https://blogread.cn/it/article.php?id=3937" target="_blank">Javascript诞生记</a> [2011-06-30 23:51:52]</li><li><a href="https://blogread.cn/it/article.php?id=3929" target="_blank">Javascript中的this</a> [2011-06-24 14:08:30]</li><li><a href="https://blogread.cn/it/article.php?id=3924" target="_blank">如何编写高质量的Javascript代码</a> [2011-06-24 14:06:03]</li><li><a href="https://blogread.cn/it/article.php?id=3920" target="_blank">jQuery是大规模应用开发的最佳选择吗？</a> [2011-06-24 13:59:52]</li><li><a href="https://blogread.cn/it/article.php?id=3904" target="_blank">javascript数组排序的问题</a> [2011-06-23 13:42:28]</li><li><a href="https://blogread.cn/it/article.php?id=3903" target="_blank">javascript正则表达式教程</a> [2011-06-23 13:42:01]</li><li><a href="https://blogread.cn/it/article.php?id=3889" target="_blank">Web表单设计:表单结构</a> [2011-06-23 13:27:48]</li><li><a href="https://blogread.cn/it/article.php?id=3885" target="_blank">对大量子节点DOM操作的最佳实践方式</a> [2011-06-23 00:29:36]</li><li><a href="https://blogread.cn/it/article.php?id=3884" target="_blank">自己写的一个轻量级javascript框架的设计模式</a> [2011-06-23 00:27:12]</li><li><a href="https://blogread.cn/it/article.php?id=3883" target="_blank">转变代码思路：js浏览器判断方法</a> [2011-06-23 00:25:23]</li><li><a href="https://blogread.cn/it/article.php?id=3881" target="_blank">浏览器对JavaScript代码执行的限制</a> [2011-06-23 00:21:34]</li><li><a href="https://blogread.cn/it/article.php?id=3875" target="_blank">JavaScript，只有你想不到</a> [2011-06-23 00:08:33]</li><li><a href="https://blogread.cn/it/article.php?id=3867" target="_blank">快速排序（Quicksort）的Javascript实现</a> [2011-06-22 00:12:39]</li><li><a href="https://blogread.cn/it/article.php?id=3861" target="_blank">十年以前，我想做个网站！</a> [2011-06-22 00:01:17]</li><li><a href="https://blogread.cn/it/article.php?id=3854" target="_blank">在 JavaScript 中监听 IME 键盘输入事件</a> [2011-06-21 23:51:50]</li><li><a href="https://blogread.cn/it/article.php?id=3834" target="_blank">Javascript继承机制的设计思想</a> [2011-06-21 13:35:16]</li><li><a href="https://blogread.cn/it/article.php?id=3829" target="_blank">前端设计类书籍推荐</a> [2011-06-21 13:27:01]</li><li><a href="https://blogread.cn/it/article.php?id=3825" target="_blank">javascript继承的写法</a> [2011-06-21 13:22:45]</li><li><a href="https://blogread.cn/it/article.php?id=3810" target="_blank">优化innerHTML操作</a> [2011-06-20 13:34:52]</li><li><a href="https://blogread.cn/it/article.php?id=3795" target="_blank">JavaScript本地存储实践（html5的localStorage和ie的userData）</a> [2011-06-13 13:56:36]</li><li><a href="https://blogread.cn/it/article.php?id=3774" target="_blank">js判断一个元素是否为另一个元素的子元素</a> [2011-06-09 14:04:52]</li><li><a href="https://blogread.cn/it/article.php?id=3771" target="_blank">在浏览器中加密Cookie</a> [2011-06-02 23:44:09]</li><li><a href="https://blogread.cn/it/article.php?id=3768" target="_blank">Ajax和WEB服务数据格式：XML SOAP HTML</a> [2011-06-02 23:33:36]</li><li><a href="https://blogread.cn/it/article.php?id=3761" target="_blank">能说明你的Javascript技术很烂的五个原因</a> [2011-06-02 23:06:05]</li><li><a href="https://blogread.cn/it/article.php?id=3753" target="_blank">使用YUI 3开发Web应用的诀窍</a> [2011-06-02 22:46:38]</li><li><a href="https://blogread.cn/it/article.php?id=3709" target="_blank">使用javascript将XML解析为JSON</a> [2011-06-02 00:08:29]</li><li><a href="https://blogread.cn/it/article.php?id=3696" target="_blank">跨浏览器的HTML5占位文本(PlaceHolder)方案</a> [2011-06-01 23:55:59]</li><li><a href="https://blogread.cn/it/article.php?id=3676" target="_blank">流量统计方法分类</a> [2011-06-01 13:36:56]</li><li><a href="https://blogread.cn/it/article.php?id=3675" target="_blank">理解JSON：3分钟课程</a> [2011-06-01 13:34:32]</li><li><a href="https://blogread.cn/it/article.php?id=3672" target="_blank">jQuery延时绑定事件(lazy-bind)</a> [2011-06-01 13:28:03]</li><li><a href="https://blogread.cn/it/article.php?id=3666" target="_blank">分享？亦或收藏？</a> [2011-05-31 14:01:19]</li><li><a href="https://blogread.cn/it/article.php?id=3655" target="_blank">Firebug Console API 与命令行</a> [2011-05-30 13:54:25]</li><li><a href="https://blogread.cn/it/article.php?id=3643" target="_blank">NodeList集合跟Array数组的区别</a> [2011-05-25 13:44:14]</li><li><a href="https://blogread.cn/it/article.php?id=3632" target="_blank">insertContent-在文本框光标位置插入内容并选中</a> [2011-05-25 13:28:11]</li><li><a href="https://blogread.cn/it/article.php?id=3603" target="_blank">更好的用vim浏览Javascript代码</a> [2011-05-17 09:08:49]</li><li><a href="https://blogread.cn/it/article.php?id=3601" target="_blank">用JavaScript判断IE版本号</a> [2011-05-17 09:01:23]</li><li><a href="https://blogread.cn/it/article.php?id=3593" target="_blank">快速清除多选框的已选中状态</a> [2011-05-17 08:51:58]</li><li><a href="https://blogread.cn/it/article.php?id=3587" target="_blank">正则表达式字面量在ECMAScript5中的变化</a> [2011-05-17 08:43:40]</li><li><a href="https://blogread.cn/it/article.php?id=3586" target="_blank">JS文件加载失败处理</a> [2011-05-17 08:42:19]</li><li><a href="https://blogread.cn/it/article.php?id=3584" target="_blank">IE中Image .onload方法问题</a> [2011-05-15 14:35:32]</li><li><a href="https://blogread.cn/it/article.php?id=3581" target="_blank">如何判断Javascript对象是否存在</a> [2011-05-15 14:32:38]</li><li><a href="https://blogread.cn/it/article.php?id=3542" target="_blank">利用跨域资源共享（CORS）实现ajax跨域调用</a> [2011-04-28 13:20:11]</li><li><a href="https://blogread.cn/it/article.php?id=3534" target="_blank">使用Jscex实现排序算法动画</a> [2011-04-27 23:51:44]</li><li><a href="https://blogread.cn/it/article.php?id=3533" target="_blank">UglifyJS有个不错的JavaScript解析器</a> [2011-04-27 23:51:10]</li><li><a href="https://blogread.cn/it/article.php?id=3532" target="_blank">使用Google Closure Compiler全力压缩代码</a> [2011-04-27 23:50:38]</li><li><a href="https://blogread.cn/it/article.php?id=3530" target="_blank">Jscex使用BSD授权协议正式发布</a> [2011-04-27 23:46:05]</li><li><a href="https://blogread.cn/it/article.php?id=3488" target="_blank">Firefox滚动残影</a> [2011-03-30 13:46:52]</li><li><a href="https://blogread.cn/it/article.php?id=3486" target="_blank">关于前端开发那些事（五）激励体制</a> [2011-03-29 00:17:10]</li><li><a href="https://blogread.cn/it/article.php?id=3485" target="_blank">关于前端开发那些事儿(四) 技术的本质何在?</a> [2011-03-29 00:16:51]</li><li><a href="https://blogread.cn/it/article.php?id=3471" target="_blank">Canvas高级特性</a> [2011-03-27 23:55:35]</li><li><a href="https://blogread.cn/it/article.php?id=3451" target="_blank">jQuery中的动画</a> [2011-03-27 23:34:23]</li><li><a href="https://blogread.cn/it/article.php?id=3443" target="_blank">为什么IE9是网页设计师的噩梦</a> [2011-03-22 23:43:41]</li><li><a href="https://blogread.cn/it/article.php?id=3438" target="_blank">Canvas学习教程 : Canvas介绍</a> [2011-03-22 23:37:12]</li><li><a href="https://blogread.cn/it/article.php?id=3434" target="_blank">图说浏览器战争：火狐、微软、谷歌那些事</a> [2011-03-22 23:31:22]</li><li><a href="https://blogread.cn/it/article.php?id=3428" target="_blank">JavaScript基于计时器的伪线程机制</a> [2011-03-21 00:11:07]</li><li><a href="https://blogread.cn/it/article.php?id=3425" target="_blank">如何在JavaScript中处理大量数据</a> [2011-03-21 00:07:17]</li><li><a href="https://blogread.cn/it/article.php?id=3413" target="_blank">如何安装Node.js</a> [2011-03-07 22:44:53]</li><li><a href="https://blogread.cn/it/article.php?id=3406" target="_blank">如何写出高质量的Javascript代码</a> [2011-03-06 22:53:44]</li><li><a href="https://blogread.cn/it/article.php?id=3383" target="_blank">有趣的变量作用域-PHP中global和Javascript中的var关键字</a> [2011-03-02 23:03:38]</li><li><a href="https://blogread.cn/it/article.php?id=3378" target="_blank">javascript with延伸的作用域是只读的吗？</a> [2011-03-02 22:58:13]</li><li><a href="https://blogread.cn/it/article.php?id=3361" target="_blank">Javascript中的函数声明和函数表达式</a> [2011-03-01 22:40:09]</li><li><a href="https://blogread.cn/it/article.php?id=3326" target="_blank">让你的网站也像Gmail一样支持文件拖放上传-HTML5之File API</a> [2011-02-23 22:26:27]</li><li><a href="https://blogread.cn/it/article.php?id=3323" target="_blank">让人又爱又恨的标签们</a> [2011-02-23 22:18:59]</li><li><a href="https://blogread.cn/it/article.php?id=3312" target="_blank">Pinterest：充分挖掘视觉的潜力</a> [2011-02-22 23:23:16]</li><li><a href="https://blogread.cn/it/article.php?id=3290" target="_blank">建设一个网站的成本（之二）</a> [2011-02-16 22:25:04]</li><li><a href="https://blogread.cn/it/article.php?id=3289" target="_blank">建设一个网站的成本（之一）</a> [2011-02-16 22:24:34]</li><li><a href="https://blogread.cn/it/article.php?id=3282" target="_blank">Web开发人员速查卡</a> [2011-02-16 22:16:42]</li><li><a href="https://blogread.cn/it/article.php?id=3272" target="_blank">怎样限制用户</a> [2011-02-15 22:54:10]</li><li><a href="https://blogread.cn/it/article.php?id=3265" target="_blank">适合JavaScript 1.7中迭代生成器的异步编程机制</a> [2011-02-14 22:37:47]</li><li><a href="https://blogread.cn/it/article.php?id=3264" target="_blank">JavaScript版本的AsyncEnumerator</a> [2011-02-14 22:37:28]</li><li><a href="https://blogread.cn/it/article.php?id=3261" target="_blank">一段Javascript的代码</a> [2011-02-14 21:26:04]</li><li><a href="https://blogread.cn/it/article.php?id=3245" target="_blank">JS游戏引擎列表</a> [2011-02-13 22:47:06]</li><li><a href="https://blogread.cn/it/article.php?id=3240" target="_blank">服务器端执行JavaScript代码</a> [2011-02-13 22:36:26]</li><li><a href="https://blogread.cn/it/article.php?id=3239" target="_blank">使用Narcissus解析JavaScript代码</a> [2011-02-13 22:32:32]</li><li><a href="https://blogread.cn/it/article.php?id=3229" target="_blank">用户及用户特征</a> [2011-02-13 21:03:25]</li><li><a href="https://blogread.cn/it/article.php?id=3200" target="_blank">程序员的档次？有没有搞错？！</a> [2011-02-10 22:20:09]</li><li><a href="https://blogread.cn/it/article.php?id=3116" target="_blank">JavaScript ( (__ = !$ + $)[+$] + ({} + $)[_/_] +({} + $)[_/_] )</a> [2011-01-28 03:27:33]</li><li><a href="https://blogread.cn/it/article.php?id=3111" target="_blank">Nicholas C. Zakas谈怎样才能成为优秀的前端工程师</a> [2011-01-27 22:57:44]</li><li><a href="https://blogread.cn/it/article.php?id=3098" target="_blank">网站开发人员应该知道的61件事</a> [2011-01-26 21:16:37]</li><li><a href="https://blogread.cn/it/article.php?id=3088" target="_blank">前端要给力之：代码可以有多烂？</a> [2011-01-25 23:04:28]</li><li><a href="https://blogread.cn/it/article.php?id=3087" target="_blank">IE7中js的执行顺序</a> [2011-01-25 22:43:12]</li><li><a href="https://blogread.cn/it/article.php?id=3084" target="_blank">渐进式的脚本加载</a> [2011-01-25 22:33:25]</li><li><a href="https://blogread.cn/it/article.php?id=3076" target="_blank">从用户体验出发的性能指标分析-TTI</a> [2011-01-24 22:53:51]</li><li><a href="https://blogread.cn/it/article.php?id=3066" target="_blank">创业与招聘</a> [2011-01-23 19:30:27]</li><li><a href="https://blogread.cn/it/article.php?id=3059" target="_blank">前端代码之丑（3）：蛋疼的压缩式写法</a> [2011-01-20 22:40:29]</li><li><a href="https://blogread.cn/it/article.php?id=3058" target="_blank">前端代码之丑（2）：丑陋的条件语句</a> [2011-01-20 22:39:53]</li><li><a href="https://blogread.cn/it/article.php?id=3057" target="_blank">前端代码之丑（一）：分支化技巧</a> [2011-01-20 22:39:10]</li><li><a href="https://blogread.cn/it/article.php?id=3056" target="_blank">JavaScript 的异步测试</a> [2011-01-20 22:37:40]</li><li><a href="https://blogread.cn/it/article.php?id=3055" target="_blank">JavaScript 测试覆盖率检测工具</a> [2011-01-20 22:36:50]</li><li><a href="https://blogread.cn/it/article.php?id=3045" target="_blank">SEO:百度百科理论知识大汇总</a> [2011-01-19 22:19:36]</li><li><a href="https://blogread.cn/it/article.php?id=3036" target="_blank">Nodejs和MongoDB初体验</a> [2011-01-18 22:18:35]</li><li><a href="https://blogread.cn/it/article.php?id=3034" target="_blank">新浪操作textarea的工具函数</a> [2011-01-18 22:17:25]</li><li><a href="https://blogread.cn/it/article.php?id=3019" target="_blank">基于 SeaJS 模块化开发的一个实例</a> [2011-01-17 22:31:10]</li><li><a href="https://blogread.cn/it/article.php?id=2998" target="_blank">前端开发小工具集合</a> [2011-01-12 23:12:00]</li><li><a href="https://blogread.cn/it/article.php?id=2986" target="_blank">jQuery打印插件</a> [2011-01-10 23:17:56]</li><li><a href="https://blogread.cn/it/article.php?id=2967" target="_blank">天朝第二代身份证号码的验证机制</a> [2011-01-05 22:34:58]</li><li><a href="https://blogread.cn/it/article.php?id=2963" target="_blank">网易首页2011新版随想</a> [2011-01-05 22:11:18]</li><li><a href="https://blogread.cn/it/article.php?id=2959" target="_blank">标题栏新消息提示</a> [2011-01-05 03:32:11]</li><li><a href="https://blogread.cn/it/article.php?id=2942" target="_blank">新媒体艺术的分众性研究</a> [2010-12-29 21:49:23]</li><li><a href="https://blogread.cn/it/article.php?id=2940" target="_blank">关于前端开发那些事儿（三）技术之变现</a> [2010-12-29 21:46:25]</li><li><a href="https://blogread.cn/it/article.php?id=2930" target="_blank">前端要给力之：分解对象构造过程new()</a> [2010-12-29 09:12:00]</li><li><a href="https://blogread.cn/it/article.php?id=2926" target="_blank">让“提到”、“转发”和“评论”各司其职</a> [2010-12-28 20:56:16]</li><li><a href="https://blogread.cn/it/article.php?id=2925" target="_blank">Closure Compiler 高级模式及更多思考</a> [2010-12-28 20:55:40]</li><li><a href="https://blogread.cn/it/article.php?id=2903" target="_blank">门户、创新、创业之道</a> [2010-12-26 20:57:54]</li><li><a href="https://blogread.cn/it/article.php?id=2871" target="_blank">基于WEB2.0的社交网络浅析</a> [2010-12-15 22:45:49]</li><li><a href="https://blogread.cn/it/article.php?id=2868" target="_blank">两行 JavaScript 代码</a> [2010-12-15 22:16:36]</li><li><a href="https://blogread.cn/it/article.php?id=2865" target="_blank">多余的逗号</a> [2010-12-15 22:13:52]</li><li><a href="https://blogread.cn/it/article.php?id=2859" target="_blank">关于WEB登录注册系统的下午茶</a> [2010-12-14 22:05:06]</li><li><a href="https://blogread.cn/it/article.php?id=2781" target="_blank">社区获取新用户的一些尝试</a> [2010-12-01 22:46:50]</li><li><a href="https://blogread.cn/it/article.php?id=2772" target="_blank">JavaScript 压缩中的权衡</a> [2010-11-30 22:48:25]</li><li><a href="https://blogread.cn/it/article.php?id=2769" target="_blank">JSCoverage 的一个 Uncoverage</a> [2010-11-30 22:38:13]</li><li><a href="https://blogread.cn/it/article.php?id=2761" target="_blank">让生活变简单的简单网站</a> [2010-11-29 22:45:37]</li><li><a href="https://blogread.cn/it/article.php?id=2748" target="_blank">模拟宽度自适应的输入框</a> [2010-11-24 23:10:19]</li><li><a href="https://blogread.cn/it/article.php?id=2734" target="_blank">如何开发Web应用程序</a> [2010-11-22 21:22:54]</li><li><a href="https://blogread.cn/it/article.php?id=2704" target="_blank">行进中的前端类库：KISSY</a> [2010-11-14 21:13:31]</li><li><a href="https://blogread.cn/it/article.php?id=2702" target="_blank">一场关于YUI3/jQuery的精彩辩论</a> [2010-11-14 21:11:09]</li><li><a href="https://blogread.cn/it/article.php?id=2701" target="_blank">将你的 KISSY 程序移植到服务器端 </a> [2010-11-14 21:10:22]</li><li><a href="https://blogread.cn/it/article.php?id=2690" target="_blank">弹窗广告开发</a> [2010-11-13 09:07:19]</li><li><a href="https://blogread.cn/it/article.php?id=2687" target="_blank">红孩子网站推广方案</a> [2010-11-13 08:54:33]</li><li><a href="https://blogread.cn/it/article.php?id=2680" target="_blank">JavaScript语法检查插件 jsLint for Vim</a> [2010-11-11 19:40:55]</li><li><a href="https://blogread.cn/it/article.php?id=2678" target="_blank">自己实现的简单的html元素选择器，类似jquery选择器，比jquery选择器还要快！</a> [2010-11-11 19:35:43]</li><li><a href="https://blogread.cn/it/article.php?id=2675" target="_blank">网站UI实现的8种方式</a> [2010-11-10 18:58:23]</li><li><a href="https://blogread.cn/it/article.php?id=2657" target="_blank">前端开发是产品设计么</a> [2010-11-07 22:39:24]</li><li><a href="https://blogread.cn/it/article.php?id=2653" target="_blank">编写高性能的jQuery代码</a> [2010-11-07 08:47:10]</li><li><a href="https://blogread.cn/it/article.php?id=2651" target="_blank">jquery中的数组过滤筛选-$.grep()</a> [2010-11-04 21:53:09]</li><li><a href="https://blogread.cn/it/article.php?id=2624" target="_blank">用javascript来摧毁你所访问的网站</a> [2010-10-31 23:33:11]</li><li><a href="https://blogread.cn/it/article.php?id=2623" target="_blank">a.x = a = { }, 深入理解赋值表达式</a> [2010-10-31 23:31:44]</li><li><a href="https://blogread.cn/it/article.php?id=2606" target="_blank">又到一年校招时： 校园用户使用的招聘类网站对比</a> [2010-10-30 07:58:35]</li><li><a href="https://blogread.cn/it/article.php?id=2602" target="_blank">互联网广告的发展史</a> [2010-10-28 22:20:35]</li><li><a href="https://blogread.cn/it/article.php?id=2592" target="_blank">设计模式-自动完成</a> [2010-10-28 07:30:46]</li><li><a href="https://blogread.cn/it/article.php?id=2583" target="_blank">[译]BigPipe：高性能的“流水线技术”网页</a> [2010-10-27 08:53:07]</li><li><a href="https://blogread.cn/it/article.php?id=2563" target="_blank">互联网上的恶趣味以及价值观</a> [2010-10-25 09:04:06]</li><li><a href="https://blogread.cn/it/article.php?id=2561" target="_blank">互联网的人才储备</a> [2010-10-25 09:02:20]</li><li><a href="https://blogread.cn/it/article.php?id=2549" target="_blank">如何在25步之内开发出一个网站</a> [2010-10-22 00:31:07]</li><li><a href="https://blogread.cn/it/article.php?id=2548" target="_blank">Seor想成功必须具备的十大素质</a> [2010-10-22 00:30:39]</li><li><a href="https://blogread.cn/it/article.php?id=2542" target="_blank">跨域资源共享的10种方式</a> [2010-10-21 09:03:36]</li><li><a href="https://blogread.cn/it/article.php?id=2526" target="_blank">JavaScript解析QueryString</a> [2010-10-18 08:15:13]</li><li><a href="https://blogread.cn/it/article.php?id=2510" target="_blank">FlashCookie </a> [2010-10-14 09:09:23]</li><li><a href="https://blogread.cn/it/article.php?id=2508" target="_blank">jQuery 操作option</a> [2010-10-14 09:05:24]</li><li><a href="https://blogread.cn/it/article.php?id=2502" target="_blank">jQuery之保证你的代码安全</a> [2010-10-14 01:06:40]</li><li><a href="https://blogread.cn/it/article.php?id=2491" target="_blank">防垃圾邮件在线生成邮箱地址图标</a> [2010-10-12 22:15:30]</li><li><a href="https://blogread.cn/it/article.php?id=2477" target="_blank">jQuery之简写ready方法</a> [2010-10-10 08:36:51]</li><li><a href="https://blogread.cn/it/article.php?id=2472" target="_blank">jQuery之不要滥用$(this)</a> [2010-10-08 20:59:31]</li><li><a href="https://blogread.cn/it/article.php?id=2457" target="_blank">jQuery之jQuery方法总是返回jQuery对象</a> [2010-10-07 08:22:03]</li><li><a href="https://blogread.cn/it/article.php?id=2444" target="_blank">记录用户体验细节</a> [2010-09-30 03:13:37]</li><li><a href="https://blogread.cn/it/article.php?id=2437" target="_blank">GC与JS内存泄露</a> [2010-09-28 09:29:15]</li><li><a href="https://blogread.cn/it/article.php?id=2433" target="_blank">用 CSS3 Transitions 实现动画</a> [2010-09-28 09:23:25]</li><li><a href="https://blogread.cn/it/article.php?id=2430" target="_blank">回到顶部 -- jQuery插件</a> [2010-09-28 09:17:14]</li><li><a href="https://blogread.cn/it/article.php?id=2419" target="_blank">细说 expando 的来源</a> [2010-09-27 00:13:58]</li><li><a href="https://blogread.cn/it/article.php?id=2414" target="_blank">A/B测试：实现方法</a> [2010-09-26 22:23:45]</li><li><a href="https://blogread.cn/it/article.php?id=2413" target="_blank">团购体验记 -- 上岛咖啡</a> [2010-09-26 09:08:53]</li><li><a href="https://blogread.cn/it/article.php?id=2411" target="_blank">关于网页问卷入口的小结</a> [2010-09-26 08:58:43]</li><li><a href="https://blogread.cn/it/article.php?id=2400" target="_blank">优雅地扩大链接响应区域</a> [2010-09-24 23:48:43]</li><li><a href="https://blogread.cn/it/article.php?id=2391" target="_blank">防止垃圾邮件小技巧两则</a> [2010-09-14 08:56:18]</li><li><a href="https://blogread.cn/it/article.php?id=2390" target="_blank">Array的push与unshift方法性能分析</a> [2010-09-14 08:53:23]</li><li><a href="https://blogread.cn/it/article.php?id=2378" target="_blank">浅谈后台页面按钮运用</a> [2010-09-12 23:37:41]</li><li><a href="https://blogread.cn/it/article.php?id=2376" target="_blank">弹出窗口的兼容方案</a> [2010-09-11 09:56:16]</li><li><a href="https://blogread.cn/it/article.php?id=2375" target="_blank">Inline Form Labels（2）</a> [2010-09-11 09:55:12]</li><li><a href="https://blogread.cn/it/article.php?id=2344" target="_blank">社交网络语法：关于“Checkin”</a> [2010-09-05 23:29:35]</li><li><a href="https://blogread.cn/it/article.php?id=2327" target="_blank">JS不是前端的全部</a> [2010-08-30 04:34:02]</li><li><a href="https://blogread.cn/it/article.php?id=2308" target="_blank">头像web版交互设计总结</a> [2010-08-23 22:04:19]</li><li><a href="https://blogread.cn/it/article.php?id=2307" target="_blank">jRaiser与jQuery的冲突问题</a> [2010-08-23 22:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=2260" target="_blank">HTML5中的自定义属性</a> [2010-08-17 23:06:35]</li><li><a href="https://blogread.cn/it/article.php?id=2259" target="_blank">从另外两道题说起</a> [2010-08-17 23:05:33]</li><li><a href="https://blogread.cn/it/article.php?id=2256" target="_blank">js 操作option</a> [2010-08-17 22:57:14]</li><li><a href="https://blogread.cn/it/article.php?id=2255" target="_blank">[Perl]Template Toolkit 内插引起 JavaScript  $ 异常</a> [2010-08-17 22:54:46]</li><li><a href="https://blogread.cn/it/article.php?id=2253" target="_blank">jQuery实例为什么在firebug下表现出数组的特征</a> [2010-08-17 10:19:43]</li><li><a href="https://blogread.cn/it/article.php?id=2246" target="_blank">世界海底光缆分布图</a> [2010-08-17 01:27:49]</li><li><a href="https://blogread.cn/it/article.php?id=2241" target="_blank">Javascript预解析相关一则</a> [2010-08-15 22:48:39]</li><li><a href="https://blogread.cn/it/article.php?id=2235" target="_blank">警惕网站分析监测实施的陷阱（下）</a> [2010-08-15 22:31:17]</li><li><a href="https://blogread.cn/it/article.php?id=2220" target="_blank">js selector设计及实现（二）――完善及优化</a> [2010-08-12 23:34:51]</li><li><a href="https://blogread.cn/it/article.php?id=2219" target="_blank">js selector设计及实现（一）――实现思路</a> [2010-08-12 23:32:21]</li><li><a href="https://blogread.cn/it/article.php?id=2207" target="_blank">Switch Case中的经典</a> [2010-08-12 09:13:19]</li><li><a href="https://blogread.cn/it/article.php?id=2201" target="_blank">优雅绝妙的Javascript跨域问题解决方案</a> [2010-08-12 04:36:17]</li><li><a href="https://blogread.cn/it/article.php?id=2190" target="_blank">优雅兼容之理想与现实</a> [2010-08-10 22:29:01]</li><li><a href="https://blogread.cn/it/article.php?id=2184" target="_blank">前端优化总结</a> [2010-08-09 09:37:37]</li><li><a href="https://blogread.cn/it/article.php?id=2183" target="_blank">DOM操作琐碎知识点</a> [2010-08-09 09:36:11]</li><li><a href="https://blogread.cn/it/article.php?id=2181" target="_blank">两行 JavaScript 代码</a> [2010-08-08 23:56:59]</li><li><a href="https://blogread.cn/it/article.php?id=2179" target="_blank">Javascript浅拷贝与深拷贝</a> [2010-08-08 23:53:50]</li><li><a href="https://blogread.cn/it/article.php?id=2177" target="_blank">jQuery.animate简单分析</a> [2010-08-06 09:47:10]</li><li><a href="https://blogread.cn/it/article.php?id=2172" target="_blank">relatedTarget, fromElement, toElement</a> [2010-08-06 00:16:45]</li><li><a href="https://blogread.cn/it/article.php?id=2171" target="_blank">elem.style.left与elem.offsetLeft的区别</a> [2010-08-06 00:15:38]</li><li><a href="https://blogread.cn/it/article.php?id=2167" target="_blank">图片旋转的小例子</a> [2010-08-05 10:00:54]</li><li><a href="https://blogread.cn/it/article.php?id=2162" target="_blank">JS中如何判断字符串类型的数字</a> [2010-08-04 23:35:47]</li><li><a href="https://blogread.cn/it/article.php?id=2159" target="_blank">Inline Form Labels</a> [2010-08-04 23:17:16]</li><li><a href="https://blogread.cn/it/article.php?id=2154" target="_blank">不要用setAttribute设置className</a> [2010-08-04 00:07:31]</li><li><a href="https://blogread.cn/it/article.php?id=2153" target="_blank">获取元素在页面的绝对位置</a> [2010-08-04 00:06:48]</li><li><a href="https://blogread.cn/it/article.php?id=2152" target="_blank">改写jQuery UI的Accordion</a> [2010-08-04 00:06:05]</li><li><a href="https://blogread.cn/it/article.php?id=2149" target="_blank">js数组去重</a> [2010-08-03 23:53:32]</li><li><a href="https://blogread.cn/it/article.php?id=2125" target="_blank">别让妈妈生气――浅谈长者用户</a> [2010-08-02 02:28:46]</li><li><a href="https://blogread.cn/it/article.php?id=2115" target="_blank">【翻译】构建成功web应用的十项黄金法则</a> [2010-07-29 22:53:24]</li><li><a href="https://blogread.cn/it/article.php?id=2109" target="_blank">三谈Iframe自适应高度</a> [2010-07-28 09:36:32]</li><li><a href="https://blogread.cn/it/article.php?id=2108" target="_blank">JS 常用继承实现方式</a> [2010-07-28 09:31:56]</li><li><a href="https://blogread.cn/it/article.php?id=2101" target="_blank">Microstrategy 8.1.2 Web Universal  开发问题整理</a> [2010-07-27 23:23:34]</li><li><a href="https://blogread.cn/it/article.php?id=2100" target="_blank">Google Docs Ctrl + C 技术浅析</a> [2010-07-27 23:22:51]</li><li><a href="https://blogread.cn/it/article.php?id=2098" target="_blank">警惕网站分析监测实施的陷阱（上）</a> [2010-07-27 23:19:49]</li><li><a href="https://blogread.cn/it/article.php?id=2081" target="_blank">禁用或启用一个ValidationGroup里的全部验证控件</a> [2010-07-25 22:31:01]</li><li><a href="https://blogread.cn/it/article.php?id=2067" target="_blank">用 JS 枚举质数</a> [2010-07-25 09:07:40]</li><li><a href="https://blogread.cn/it/article.php?id=2064" target="_blank">网站性能监测工具Boomerang</a> [2010-07-23 00:19:58]</li><li><a href="https://blogread.cn/it/article.php?id=2057" target="_blank">js窗口间通信摘要</a> [2010-07-23 00:08:47]</li><li><a href="https://blogread.cn/it/article.php?id=2056" target="_blank">JS操作iframe里的dom</a> [2010-07-23 00:08:26]</li><li><a href="https://blogread.cn/it/article.php?id=2051" target="_blank">不要纠结于实现的圈套中</a> [2010-07-22 20:05:56]</li><li><a href="https://blogread.cn/it/article.php?id=2032" target="_blank">关于动态创建script元素</a> [2010-07-21 23:31:38]</li><li><a href="https://blogread.cn/it/article.php?id=2026" target="_blank">JavaScript性能陷阱</a> [2010-07-21 09:54:59]</li><li><a href="https://blogread.cn/it/article.php?id=2010" target="_blank">HTML5文件API之图片预览</a> [2010-07-20 23:14:35]</li><li><a href="https://blogread.cn/it/article.php?id=2000" target="_blank">亚马逊用户体验改善</a> [2010-07-20 09:50:25]</li><li><a href="https://blogread.cn/it/article.php?id=1997" target="_blank">KISSY 近期更新 &amp; 设计思路讨论</a> [2010-07-19 22:55:33]</li><li><a href="https://blogread.cn/it/article.php?id=1980" target="_blank">jQuery实例为什么在firebug下表现出数组的特征</a> [2010-07-19 19:47:46]</li><li><a href="https://blogread.cn/it/article.php?id=1964" target="_blank">jQuery.animate简单分析</a> [2010-07-18 23:30:13]</li><li><a href="https://blogread.cn/it/article.php?id=1960" target="_blank">按钮制作一小例</a> [2010-07-18 23:28:23]</li><li><a href="https://blogread.cn/it/article.php?id=1959" target="_blank">jRaiser与jQuery的冲突问题</a> [2010-07-18 08:42:45]</li><li><a href="https://blogread.cn/it/article.php?id=1939" target="_blank">javascript 缓存提供程序</a> [2010-07-15 08:43:00]</li><li><a href="https://blogread.cn/it/article.php?id=1933" target="_blank">互联网产品设计十年</a> [2010-07-14 22:27:47]</li><li><a href="https://blogread.cn/it/article.php?id=1925" target="_blank">What really it is, not what it is</a> [2010-07-14 09:42:04]</li><li><a href="https://blogread.cn/it/article.php?id=1922" target="_blank">同是做网站，他们是怎么用词的？</a> [2010-07-14 00:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=1920" target="_blank">各公司对前端开发的职位描述</a> [2010-07-14 00:01:20]</li><li><a href="https://blogread.cn/it/article.php?id=1914" target="_blank">WEB性能测试工具推荐</a> [2010-07-12 23:27:11]</li><li><a href="https://blogread.cn/it/article.php?id=1913" target="_blank">JavaScript Interface 接口的实现</a> [2010-07-12 23:26:03]</li><li><a href="https://blogread.cn/it/article.php?id=1906" target="_blank">电子商务网站“用户评论”模块浅析</a> [2010-07-09 13:13:20]</li><li><a href="https://blogread.cn/it/article.php?id=1901" target="_blank">我们来做一个会呼吸的菜单吧!!</a> [2010-07-07 12:29:39]</li><li><a href="https://blogread.cn/it/article.php?id=1882" target="_blank">关于排行榜代码优化</a> [2010-07-02 09:31:20]</li><li><a href="https://blogread.cn/it/article.php?id=1881" target="_blank">window.location.href,window.location.replace(),window.location.reload() 三者的区别</a> [2010-06-30 15:54:28]</li><li><a href="https://blogread.cn/it/article.php?id=1871" target="_blank">IE中createElement需要注意的一个小问题</a> [2010-06-27 22:30:03]</li><li><a href="https://blogread.cn/it/article.php?id=1868" target="_blank">“铁”饭碗</a> [2010-06-27 22:26:43]</li><li><a href="https://blogread.cn/it/article.php?id=1862" target="_blank">2010网页设计趋势</a> [2010-06-27 22:14:17]</li><li><a href="https://blogread.cn/it/article.php?id=1854" target="_blank">IE6图片加载的一个BUG</a> [2010-06-25 12:20:42]</li><li><a href="https://blogread.cn/it/article.php?id=1844" target="_blank">页面中的全局污染</a> [2010-06-23 13:03:04]</li><li><a href="https://blogread.cn/it/article.php?id=1835" target="_blank">网站分析“高考”答案</a> [2010-06-23 12:54:15]</li><li><a href="https://blogread.cn/it/article.php?id=1823" target="_blank">实现一个更精简的Tab</a> [2010-06-21 17:29:49]</li><li><a href="https://blogread.cn/it/article.php?id=1819" target="_blank">再论Javascript的类继承</a> [2010-06-20 23:46:10]</li><li><a href="https://blogread.cn/it/article.php?id=1813" target="_blank">以用户为中心的 API 异常设计</a> [2010-06-18 18:08:38]</li><li><a href="https://blogread.cn/it/article.php?id=1812" target="_blank">创业和投资人的眼光</a> [2010-06-18 18:07:53]</li><li><a href="https://blogread.cn/it/article.php?id=1809" target="_blank">href,replace(),reload() 三者的区别</a> [2010-06-18 18:05:55]</li><li><a href="https://blogread.cn/it/article.php?id=1807" target="_blank">网站分析的应用和价值</a> [2010-06-18 18:03:07]</li><li><a href="https://blogread.cn/it/article.php?id=1775" target="_blank">IE6下appendChild的一个小问题。</a> [2010-06-12 17:46:10]</li><li><a href="https://blogread.cn/it/article.php?id=1764" target="_blank">在服务端合并和压缩JavaScript和CSS文件</a> [2010-06-11 11:55:52]</li><li><a href="https://blogread.cn/it/article.php?id=1756" target="_blank">移动网站开发――标记语言</a> [2010-06-07 13:04:59]</li><li><a href="https://blogread.cn/it/article.php?id=1717" target="_blank">谦虚一点去工作</a> [2010-06-03 13:17:33]</li><li><a href="https://blogread.cn/it/article.php?id=1711" target="_blank">JavaScript Creating Objects Other Pattern</a> [2010-06-02 23:00:51]</li><li><a href="https://blogread.cn/it/article.php?id=1709" target="_blank">JavaScript Dynamic Prototype Pattern</a> [2010-06-02 22:56:39]</li><li><a href="https://blogread.cn/it/article.php?id=1700" target="_blank">关于JS获取select的值</a> [2010-06-02 11:51:44]</li><li><a href="https://blogread.cn/it/article.php?id=1694" target="_blank">BO报表系统嵌入Iframe在firefox下的错误修改</a> [2010-06-01 21:56:50]</li><li><a href="https://blogread.cn/it/article.php?id=1692" target="_blank">关于前端开发的那些事（一）</a> [2010-06-01 13:12:16]</li><li><a href="https://blogread.cn/it/article.php?id=1682" target="_blank">我的互联网信仰</a> [2010-06-01 13:01:12]</li><li><a href="https://blogread.cn/it/article.php?id=1672" target="_blank">狗血的中天置地</a> [2010-05-31 23:56:55]</li><li><a href="https://blogread.cn/it/article.php?id=1663" target="_blank">HTML在线编辑器的实现难点</a> [2010-05-28 18:39:13]</li><li><a href="https://blogread.cn/it/article.php?id=1656" target="_blank">ExtJS源码研究笔记之总评</a> [2010-05-28 09:35:35]</li><li><a href="https://blogread.cn/it/article.php?id=1626" target="_blank">parseInt 小陷阱</a> [2010-05-25 13:32:22]</li><li><a href="https://blogread.cn/it/article.php?id=1622" target="_blank">Javascript面向对象编程（三）：非函数对象的继承</a> [2010-05-25 13:28:44]</li><li><a href="https://blogread.cn/it/article.php?id=1615" target="_blank">websocket 通信协议</a> [2010-05-24 16:27:42]</li><li><a href="https://blogread.cn/it/article.php?id=1613" target="_blank">用工具跟踪用户的行为</a> [2010-05-24 16:26:34]</li><li><a href="https://blogread.cn/it/article.php?id=1603" target="_blank">Javascript面向对象编程（二）：继承</a> [2010-05-24 09:46:15]</li><li><a href="https://blogread.cn/it/article.php?id=1602" target="_blank">Javascript 面向对象编程（一）：封装</a> [2010-05-24 09:45:40]</li><li><a href="https://blogread.cn/it/article.php?id=1593" target="_blank">全兼容的滚动js脚本</a> [2010-05-23 21:42:02]</li><li><a href="https://blogread.cn/it/article.php?id=1590" target="_blank">社会化媒体营销</a> [2010-05-22 13:09:13]</li><li><a href="https://blogread.cn/it/article.php?id=1572" target="_blank">一个IE6下重复加载的BUG</a> [2010-05-20 13:25:14]</li><li><a href="https://blogread.cn/it/article.php?id=1552" target="_blank">jRaiser揭秘――事件监听兼容处理</a> [2010-05-17 13:08:38]</li><li><a href="https://blogread.cn/it/article.php?id=1546" target="_blank">Javascript原型链和原型的一个误区</a> [2010-05-14 13:49:08]</li><li><a href="https://blogread.cn/it/article.php?id=1519" target="_blank">互动传媒 ―― 带你进入网络的互动视界</a> [2010-05-07 13:49:49]</li><li><a href="https://blogread.cn/it/article.php?id=1513" target="_blank">Javascript的this用法</a> [2010-05-05 13:31:14]</li><li><a href="https://blogread.cn/it/article.php?id=1493" target="_blank">Google对网页时间的关注</a> [2010-05-04 10:09:36]</li><li><a href="https://blogread.cn/it/article.php?id=1491" target="_blank">Array.prototype.slice</a> [2010-05-04 10:07:52]</li><li><a href="https://blogread.cn/it/article.php?id=1489" target="_blank">关于腾讯微博的一些思考……</a> [2010-04-30 15:47:32]</li><li><a href="https://blogread.cn/it/article.php?id=1457" target="_blank">支持多浏览器的网站变灰方法</a> [2010-04-27 13:48:13]</li><li><a href="https://blogread.cn/it/article.php?id=1442" target="_blank">关于对浏览器兼容性的一点点理解</a> [2010-04-25 21:58:03]</li><li><a href="https://blogread.cn/it/article.php?id=1410" target="_blank">IE下pre标签的InnerHTML问题</a> [2010-04-16 13:28:58]</li><li><a href="https://blogread.cn/it/article.php?id=1399" target="_blank">界面程序开发的一些总结</a> [2010-04-16 09:20:18]</li><li><a href="https://blogread.cn/it/article.php?id=1391" target="_blank">Zakas解答Baranovskiy的JavaScript小测试</a> [2010-04-15 13:45:23]</li><li><a href="https://blogread.cn/it/article.php?id=1381" target="_blank">不一样的交互组件（下）</a> [2010-04-14 13:44:04]</li><li><a href="https://blogread.cn/it/article.php?id=1375" target="_blank">如何创建google浏览器插件</a> [2010-04-14 13:35:59]</li><li><a href="https://blogread.cn/it/article.php?id=1367" target="_blank">javascript对XML的读写操作</a> [2010-04-14 09:20:09]</li><li><a href="https://blogread.cn/it/article.php?id=1356" target="_blank">JSON 轻量级的数据交换格式</a> [2010-04-13 10:59:08]</li><li><a href="https://blogread.cn/it/article.php?id=1352" target="_blank">2009年前端技术领域回顾</a> [2010-04-12 23:49:30]</li><li><a href="https://blogread.cn/it/article.php?id=1351" target="_blank">你真的了解HTML吗</a> [2010-04-12 23:48:33]</li><li><a href="https://blogread.cn/it/article.php?id=1329" target="_blank">JavaScript组件打包模式</a> [2010-04-09 09:12:53]</li><li><a href="https://blogread.cn/it/article.php?id=1328" target="_blank">superLink，让伪链接更有可用性</a> [2010-04-09 09:12:16]</li><li><a href="https://blogread.cn/it/article.php?id=1327" target="_blank">让Vim(gvim)更好的支持javascript编程</a> [2010-04-09 09:10:39]</li><li><a href="https://blogread.cn/it/article.php?id=1323" target="_blank">什么是网页标准？</a> [2010-04-08 23:52:05]</li><li><a href="https://blogread.cn/it/article.php?id=1322" target="_blank">百度HI QQ和MSN 阿里旺旺贸易通MSN在线客服聊天代码</a> [2010-04-08 14:23:50]</li><li><a href="https://blogread.cn/it/article.php?id=1315" target="_blank">语义化的label？</a> [2010-04-07 09:11:44]</li><li><a href="https://blogread.cn/it/article.php?id=1314" target="_blank">兼容所有浏览器的设为首页与显示小策略</a> [2010-04-07 09:11:06]</li><li><a href="https://blogread.cn/it/article.php?id=1313" target="_blank">Debugging JavaScript：throw与console</a> [2010-04-07 09:08:41]</li><li><a href="https://blogread.cn/it/article.php?id=1286" target="_blank">如何让discuz7 版规支持html代码</a> [2010-03-31 09:28:21]</li><li><a href="https://blogread.cn/it/article.php?id=1282" target="_blank">一个兼容多种场合的Javascript图片大小自适应function</a> [2010-03-31 09:24:22]</li><li><a href="https://blogread.cn/it/article.php?id=1257" target="_blank">异步完成后新开窗口</a> [2010-03-28 15:13:54]</li><li><a href="https://blogread.cn/it/article.php?id=1240" target="_blank">js对cookie的几个操作函数(仅作备忘)</a> [2010-03-24 22:28:36]</li><li><a href="https://blogread.cn/it/article.php?id=1173" target="_blank">在wordpress中使用Google Reader “Send To”</a> [2010-03-09 13:13:34]</li><li><a href="https://blogread.cn/it/article.php?id=1168" target="_blank">防止垃圾邮件小技巧两则</a> [2010-03-09 09:14:15]</li><li><a href="https://blogread.cn/it/article.php?id=1153" target="_blank">在js中对中文和特殊字符转码</a> [2010-03-08 23:06:43]</li><li><a href="https://blogread.cn/it/article.php?id=1145" target="_blank">Script 元素的异步加载属性</a> [2010-03-07 23:28:31]</li><li><a href="https://blogread.cn/it/article.php?id=1138" target="_blank">jQuery边框圆角插件：DivCorners</a> [2010-03-03 23:58:12]</li><li><a href="https://blogread.cn/it/article.php?id=1113" target="_blank">JavaScript 全半角转换</a> [2010-03-02 13:46:45]</li><li><a href="https://blogread.cn/it/article.php?id=1108" target="_blank">JavaScript 屏蔽右键</a> [2010-03-02 13:40:15]</li><li><a href="https://blogread.cn/it/article.php?id=1073" target="_blank">js中鼠标滚轮事件详解</a> [2010-02-25 09:31:18]</li><li><a href="https://blogread.cn/it/article.php?id=1036" target="_blank">外链点击没有 referrer 信息?!</a> [2010-02-09 09:09:58]</li><li><a href="https://blogread.cn/it/article.php?id=1031" target="_blank">JQuery实现Excel表格呈现</a> [2010-02-09 09:04:36]</li><li><a href="https://blogread.cn/it/article.php?id=983" target="_blank">Fastest JavaScript Trim</a> [2010-01-15 14:56:00]</li><li><a href="https://blogread.cn/it/article.php?id=978" target="_blank">WebGame的力量有多大</a> [2010-01-15 14:42:37]</li><li><a href="https://blogread.cn/it/article.php?id=967" target="_blank">获取Dom元素的X/Y坐标</a> [2010-01-13 09:12:02]</li><li><a href="https://blogread.cn/it/article.php?id=964" target="_blank">YUI3设计中的激进和妥协</a> [2010-01-12 13:28:48]</li><li><a href="https://blogread.cn/it/article.php?id=963" target="_blank">The Deferred Evaluation of YUI 3</a> [2010-01-12 13:26:18]</li><li><a href="https://blogread.cn/it/article.php?id=961" target="_blank">终于想到如何给《三枪》归类了</a> [2010-01-12 13:24:35]</li><li><a href="https://blogread.cn/it/article.php?id=956" target="_blank">如何做好一份前端工程师的简历？</a> [2010-01-11 12:13:21]</li><li><a href="https://blogread.cn/it/article.php?id=951" target="_blank">用javascript悬停效果改善你的在线商店的12种方法</a> [2010-01-08 17:05:42]</li><li><a href="https://blogread.cn/it/article.php?id=948" target="_blank">手机网站开发必修课[2009总结版]</a> [2010-01-08 13:03:31]</li><li><a href="https://blogread.cn/it/article.php?id=946" target="_blank">12种不宜使用的Javascript语法</a> [2010-01-08 13:00:16]</li><li><a href="https://blogread.cn/it/article.php?id=904" target="_blank">能看到的都不是核心竞争力</a> [2010-01-04 12:51:07]</li><li><a href="https://blogread.cn/it/article.php?id=895" target="_blank">vim的一个js代码整理的插件jsbeautify.vim</a> [2009-12-28 10:45:11]</li><li><a href="https://blogread.cn/it/article.php?id=875" target="_blank">Javascript Selectors 入门篇</a> [2009-12-23 13:34:13]</li><li><a href="https://blogread.cn/it/article.php?id=866" target="_blank">图片轮播控件 Carousel Controls</a> [2009-12-22 14:22:26]</li><li><a href="https://blogread.cn/it/article.php?id=844" target="_blank">2009年年终盘点</a> [2009-12-19 17:58:19]</li><li><a href="https://blogread.cn/it/article.php?id=840" target="_blank">你的网上商店需要用TAB栏吗？</a> [2009-12-18 15:42:34]</li><li><a href="https://blogread.cn/it/article.php?id=831" target="_blank">如何给JavaScript文件传递参数</a> [2009-12-17 09:21:25]</li><li><a href="https://blogread.cn/it/article.php?id=830" target="_blank">可能被你忽略的 JavaScript 代码陷阱</a> [2009-12-17 09:16:28]</li><li><a href="https://blogread.cn/it/article.php?id=810" target="_blank">JS+CSS实现隔行换色</a> [2009-12-13 20:20:43]</li><li><a href="https://blogread.cn/it/article.php?id=800" target="_blank">javascript 验证例子,让你精通js</a> [2009-12-11 22:52:45]</li><li><a href="https://blogread.cn/it/article.php?id=799" target="_blank">javascript各种各样的验证方法(正则表达式)</a> [2009-12-11 22:52:15]</li><li><a href="https://blogread.cn/it/article.php?id=789" target="_blank">国务院发布2010年放假安排</a> [2009-12-09 16:43:44]</li><li><a href="https://blogread.cn/it/article.php?id=765" target="_blank">色板 -- 颜色收集</a> [2009-12-04 13:33:03]</li><li><a href="https://blogread.cn/it/article.php?id=764" target="_blank">JavaScript性能优化--创建表格</a> [2009-12-03 22:40:07]</li><li><a href="https://blogread.cn/it/article.php?id=749" target="_blank">JavaScript性能优化--创建文档碎片</a> [2009-12-01 23:16:34]</li><li><a href="https://blogread.cn/it/article.php?id=748" target="_blank">都是转义惹的祸</a> [2009-12-01 16:32:57]</li><li><a href="https://blogread.cn/it/article.php?id=734" target="_blank">梦醒时分</a> [2009-11-30 09:03:27]</li><li><a href="https://blogread.cn/it/article.php?id=723" target="_blank">用 Jquery 模拟 select</a> [2009-11-27 22:37:14]</li><li><a href="https://blogread.cn/it/article.php?id=700" target="_blank">JavaScript程序执行顺序问题总结</a> [2009-11-25 23:58:34]</li><li><a href="https://blogread.cn/it/article.php?id=642" target="_blank">frame调用另外一个frame的内容</a> [2009-11-18 23:40:47]</li><li><a href="https://blogread.cn/it/article.php?id=629" target="_blank">javascript 回退到前一页的写法</a> [2009-11-18 13:39:42]</li><li><a href="https://blogread.cn/it/article.php?id=628" target="_blank">IE 中无提示关闭窗口的方法</a> [2009-11-18 13:39:27]</li><li><a href="https://blogread.cn/it/article.php?id=607" target="_blank">优化次数过多的循环</a> [2009-11-16 23:25:03]</li><li><a href="https://blogread.cn/it/article.php?id=595" target="_blank">PHP的escape函数的实现方法</a> [2009-11-16 23:09:36]</li><li><a href="https://blogread.cn/it/article.php?id=591" target="_blank">jQuery性能优化指南</a> [2009-11-16 13:29:39]</li><li><a href="https://blogread.cn/it/article.php?id=576" target="_blank">用onpropertychange,oninput事件解决onchange事件的不足</a> [2009-11-15 18:27:14]</li><li><a href="https://blogread.cn/it/article.php?id=575" target="_blank">js中String的常用扩展</a> [2009-11-15 18:24:20]</li><li><a href="https://blogread.cn/it/article.php?id=574" target="_blank">js不同浏览器检测</a> [2009-11-13 18:38:20]</li><li><a href="https://blogread.cn/it/article.php?id=573" target="_blank">动态加载JavaScript的小实践</a> [2009-11-13 18:37:49]</li><li><a href="https://blogread.cn/it/article.php?id=570" target="_blank">在HTML中获取正确的URL属性值</a> [2009-11-13 18:34:05]</li><li><a href="https://blogread.cn/it/article.php?id=569" target="_blank">JavaScript获取准确的行高</a> [2009-11-13 18:31:08]</li><li><a href="https://blogread.cn/it/article.php?id=545" target="_blank">jquery判断是否隐藏</a> [2009-11-11 13:57:39]</li><li><a href="https://blogread.cn/it/article.php?id=544" target="_blank">jquery表格色彩差异显示</a> [2009-11-11 13:56:42]</li><li><a href="https://blogread.cn/it/article.php?id=541" target="_blank">AIR 编程的途径</a> [2009-11-11 13:52:33]</li><li><a href="https://blogread.cn/it/article.php?id=524" target="_blank">javascript 最简单的UI实现（学习）</a> [2009-11-10 12:34:11]</li><li><a href="https://blogread.cn/it/article.php?id=497" target="_blank">客户端应该去计算什么？</a> [2009-11-09 09:29:16]</li><li><a href="https://blogread.cn/it/article.php?id=484" target="_blank">IE6支持PNG透明(alpha通道)的4种方法</a> [2009-11-08 23:03:01]</li><li><a href="https://blogread.cn/it/article.php?id=445" target="_blank">js制作提示公告带关闭可保存cookie</a> [2009-11-04 14:58:14]</li><li><a href="https://blogread.cn/it/article.php?id=444" target="_blank">js添加查询删除cookie操作代码</a> [2009-11-04 13:34:49]</li><li><a href="https://blogread.cn/it/article.php?id=443" target="_blank">js实现预加载图片让图片快速显示</a> [2009-11-04 13:34:18]</li><li><a href="https://blogread.cn/it/article.php?id=440" target="_blank">全站换域名时利用nginx和javascript做简单友好的换域名跳转通知</a> [2009-11-04 11:31:18]</li><li><a href="https://blogread.cn/it/article.php?id=426" target="_blank">Firefox调试正常，IE下面缺少对象，IE的编码问题</a> [2009-11-03 09:29:16]</li><li><a href="https://blogread.cn/it/article.php?id=407" target="_blank">Javascript Widget入门解析</a> [2009-11-02 16:47:12]</li><li><a href="https://blogread.cn/it/article.php?id=406" target="_blank">LinkageSelect 基于jQuery的联动下拉菜单</a> [2009-11-02 13:34:16]</li><li><a href="https://blogread.cn/it/article.php?id=386" target="_blank">关于Javascript的俩个有趣的探讨</a> [2009-10-30 08:52:41]</li><li><a href="https://blogread.cn/it/article.php?id=384" target="_blank">深入理解JavaScript定时机制</a> [2009-10-30 08:46:44]</li><li><a href="https://blogread.cn/it/article.php?id=382" target="_blank">深入理解Javascript之this关键字</a> [2009-10-29 23:43:22]</li><li><a href="https://blogread.cn/it/article.php?id=378" target="_blank">正确使用JS中的正则</a> [2009-10-29 22:48:19]</li><li><a href="https://blogread.cn/it/article.php?id=368" target="_blank">Javascript作用域原理</a> [2009-10-29 15:23:47]</li><li><a href="https://blogread.cn/it/article.php?id=367" target="_blank">JS文件装载器(Eve Js Loader)</a> [2009-10-29 14:08:23]</li><li><a href="https://blogread.cn/it/article.php?id=366" target="_blank">使用JS做文档处理</a> [2009-10-29 13:56:14]</li><li><a href="https://blogread.cn/it/article.php?id=365" target="_blank">浏览器的结构</a> [2009-10-29 13:52:37]</li><li><a href="https://blogread.cn/it/article.php?id=358" target="_blank">分享一个JQUERY颜色选择插件</a> [2009-10-29 08:49:14]</li><li><a href="https://blogread.cn/it/article.php?id=332" target="_blank">基于鼠标点击跟踪的用户点击行为分析</a> [2009-10-27 15:29:59]</li><li><a href="https://blogread.cn/it/article.php?id=308" target="_blank">IE下的优秀JavaScript调试工具Companion.JS</a> [2009-10-25 22:28:44]</li><li><a href="https://blogread.cn/it/article.php?id=307" target="_blank">JavaScript 实现 PHP (trim)</a> [2009-10-25 22:28:23]</li><li><a href="https://blogread.cn/it/article.php?id=299" target="_blank">为脚本语言平反-JavaScript篇（3）</a> [2009-10-23 23:55:03]</li><li><a href="https://blogread.cn/it/article.php?id=298" target="_blank">为脚本语言平反-JavaScript篇（2）</a> [2009-10-23 23:53:32]</li><li><a href="https://blogread.cn/it/article.php?id=297" target="_blank">为脚本语言平反-JavaScript篇（1）</a> [2009-10-23 23:50:50]</li><li><a href="https://blogread.cn/it/article.php?id=296" target="_blank">在js中做数字字符串补0</a> [2009-10-23 23:48:12]</li><li><a href="https://blogread.cn/it/article.php?id=282" target="_blank">模式化窗口</a> [2009-10-22 09:37:49]</li><li><a href="https://blogread.cn/it/article.php?id=246" target="_blank">JavaScript函数调用规则</a> [2009-10-20 22:30:16]</li><li><a href="https://blogread.cn/it/article.php?id=191" target="_blank">母亲也是爱美的</a> [2009-10-16 12:16:11]</li><li><a href="https://blogread.cn/it/article.php?id=189" target="_blank">构造”前进”,“后退”按钮能用的Javascript应用</a> [2009-10-16 12:15:21]</li><li><a href="https://blogread.cn/it/article.php?id=157" target="_blank">javascript 在各个浏览器中的超时时间</a> [2009-10-14 13:33:51]</li><li><a href="https://blogread.cn/it/article.php?id=138" target="_blank">用Javascript获取页面元素的位置</a> [2009-10-13 23:07:15]</li><li><a href="https://blogread.cn/it/article.php?id=134" target="_blank">基础体验决定上层应用</a> [2009-10-13 23:02:29]</li><li><a href="https://blogread.cn/it/article.php?id=130" target="_blank">奇淫技巧和西天取经</a> [2009-10-13 22:58:04]</li><li><a href="https://blogread.cn/it/article.php?id=128" target="_blank">instanceof 内部机制探析</a> [2009-10-13 22:55:07]</li><li><a href="https://blogread.cn/it/article.php?id=127" target="_blank">Loop Benchmarks</a> [2009-10-13 22:53:30]</li><li><a href="https://blogread.cn/it/article.php?id=126" target="_blank">JavaScript 快速组合算法</a> [2009-10-13 22:52:51]</li><li><a href="https://blogread.cn/it/article.php?id=29" target="_blank">一篇关于新媒体和新媒体营销的小结</a> [2009-10-10 23:56:20]</li><li><a href="https://blogread.cn/it/article.php?id=27" target="_blank">网站导航栏的过去与现在</a> [2009-10-10 23:43:59]</li><li><a href="https://blogread.cn/it/article.php?id=18" target="_blank">20个有趣的网站</a> [2009-10-10 18:14:11]</li><li><a href="https://blogread.cn/it/article.php?id=9" target="_blank">用js给fckeditor赋值的办法</a> [2009-10-10 14:09:00]</li></ol></p>]]></description>
		<content><![CDATA[浏览器原生focus()方法新增focusVisible参数，可精准控制元素获取焦点时是否显示默认的outline轮廓样式。默认情况下，通过JavaScript主动调用focus()触发焦点时，部分浏览器不会显示焦点轮廓，导致用户无法直观感知焦点位置。focusVisible参数允许开发者显式强制显示或隐藏该轮廓，例如设置`focus({focusVisible: true})`即可让链接或按钮在程序化聚焦时呈现明显的视觉提示，提升无障碍体验；反之设置为false则可抑制轮廓显示。该特性提供了比传统CSS选择器`:focus-visible`更直接的编程控制方式，尤其适用于需要统一管理焦点视觉反馈的交互场景。作者同时指出，尽管该特性对用户体验有益，但受兼容性和国内开发环境影响，实际应用前景可能有限。]]></content>
	</item>
	<item>
		<title>科技爱好者周刊（第 398 期）：Token 费用难以负担</title>
		<link>https://blogread.cn/it/article.php?id=8596</link>
		<author>阮一峰</author>
		<pubDate>2026-06-03 09:03:24</pubDate>
		<category domain="https://blogread.cn/it/category.php?id=4">AI</category>
		<guid>https://blogread.cn/it/article.php?id=8596</guid>
		<comments>https://blogread.cn/it/article.php?id=8596#comment</comments>
		<description><![CDATA[<p><strong>标签：</strong>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=Transformer" target="_blank">Transformer</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=%E5%A4%A7%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B" target="_blank">大语言模型</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0" target="_blank">机器学习</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=%E8%87%AA%E7%84%B6%E8%AF%AD%E8%A8%80%E5%A4%84%E7%90%86" target="_blank">自然语言处理</a></p><p>这里记录每周值得分享的科技内容，周五发布。</p>

        <p>本杂志<a href="https://github.com/ruanyf/weekly">开源</a>，欢迎<a href="https://github.com/ruanyf/weekly/issues">投稿</a>。另有<a href="https://github.com/ruanyf/weekly/issues/9815">《谁在招人》</a>服务，发布程序员招聘信息。合作请<a href="mailto:yifeng.ruan@gmail.com">邮件联系</a>（yifeng.ruan@gmail.com）。</p>

<h2>封面图</h2>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052803.webp" alt="" title=""></p>

<p>去年开放的浙江省安吉县的安吉文化艺术中心。当地盛产竹子，屋顶都采用竹叶造型。（<a href="https://www.instagram.com/p/DYKVQBKiBG1/?img_index=1">daemin_kg@ig</a>）</p>

<h2>Token 费用难以负担</h2>

<p>上周，OpenClaw（龙虾）的创始人彼得·斯坦伯格（Peter Steinberger）贴出了自己的 <a href="https://x.com/steipete/status/2055346265869721905">Token 使用量</a>。</p>

<p>他不是故意炫耀，自己用了多少 Token，而是为了介绍工具软件 <a href="https://codexbar.app/">CodexBar</a>。这个菜单栏小工具可以统计你的 Token 使用量，计算出对应的费用。</p>

<p>大家猜猜看，他用了多少 Token？</p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026051701.webp" alt="" title=""></p>

<p>根据截图，他一个月发出了760万个请求，消耗的 Token 数量为6030亿。根据预设的费率，这些 Token 价值130万美元！</p>

<p>也就是说，<strong>他的 AI 编程平均每天要花费4万多美元</strong>。</p>

<p>当然，这个数字不是真实支出。因为他是 OpenAI 公司的员工，可以无限量免费使用公司的 Token。所以，这些钱并不是真实的支出。</p>

<p>但是，他的 Token 使用量是真的。绝大部分公司需要外购 Token，大家可以用他的例子计算一下，如果一个程序员每月用掉几千亿、甚至上万亿的 Token，公司要出多少钱？</p>

<p>他一个人一个月130万美元，相当于近900万人民币，<strong>一年下来超过1亿人民币！</strong> 这就是放开使用顶级模型，公司要支付的费用。</p>

<p>如果改用便宜的模型，国内最便宜的开源模型，价格大约是国外旗舰模型的1/30到1/50，那么一年就是200万～300万人民币。</p>

<p>结论就是，<strong>如果放开不限量使用，一个程序员一年最少会花掉两三百万人民币的 Token 费用</strong>。要是使用美国的旗舰模型，费用会快速上涨到几千万甚至上亿人民币。</p>

<p>公司想要降低成本，有两个方法：一是购买包月套餐，但是大项目不够用；二是自己架设开源模型，省掉外购的费用，但是硬件费用不便宜，而且最强的模型目前是不开源的。</p>

<p>权衡下来，我猜想，<strong>公司几乎肯定会设置限制，不允许程序员无限量使用外部模型</strong>。那样的话，巨额的 Token 费用难以承受。程序员的工资已经不低了，再加上每人每年至少几百万人民币的 Token 费用，公司的开发成本会爆炸的。</p>

<p>大家可以说说，有没有公司对程序员提供外部模型无限量 API 调用？我是没有听说过。</p>

<p>事实上，因为 Token 费用太高，公司收紧 AI 编程的例子，我倒是知道几个。</p>

<p>比如，网约车巨头 <a href="https://www.forbes.com/sites/janakirammsv/2026/05/17/uber-burns-its-2026-ai-budget-in-four-months-on-claude-code/">Uber</a> 今年头四个月就花完了全年34亿美元的 AI 预算，不得不限制使用 AI 了。</p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052405.webp" alt="" title=""></p>

<p>再比如，<a href="https://aiweekly.co/alerts/microsoft-drops-claude-code-after-budget-overrun">微软</a>也因为费用超标，放弃了 Claude Code，改用自家托管的 OpenAI 模型。</p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052406.webp" alt="" title=""></p>

<p>如果 Uber 和微软这样的巨头，都承受不了巨额的 Token 费用，那大概就没有公司能够承受了。</p>

<p>总之，AI 编程虽然听起来很美好，但是看到账单的那一刻，公司就会清醒：<strong>AI 编程比真人程序员昂贵太多了</strong>。</p>

<p>所以，AI 会替代程序员吗？对于有大型软件项目的公司，我认为不会大规模替代，因为成本放在那里。至少现阶段如此，如果未来 Token 费用大幅下降，那就难说了。</p>

<h2>漏洞赏金计划的终结</h2>

<p><a href="https://turso.tech/">Turso</a> 是一个开源的云数据库，代码放在 GitHub。</p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052804.webp" alt="" title=""></p>

<p>它有一个赏金计划，给予发现漏洞的人1000美元奖金。本来运作得挺好，自从大模型可以用来发现漏洞以后，事情就不对了。</p>

<p>它的仓库的 PR 页面（外部代码提交）已经变成下面这样。</p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026051606.webp" alt="" title=""></p>

<p>提交漏洞的人泛滥成灾，都是冲着奖金而来。他们所谓的漏洞，往往是故意注入垃圾字节，或者是配置错误，自然就是无法运行。</p>

<p>开发团队精疲力尽，不胜其扰。有时候，关掉这些 PR，提交者还会跟你争论，用 AI 生成的<a href="https://github.com/tursodatabase/turso/pull/6257#issuecomment-4216531987">长篇大论</a>告诉开发团队"我没错，你们搞错了"，令人啼笑皆非。</p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026051607.webp" alt="" title=""></p>

<p>最终，开发团队只能宣布，<a href="https://turso.tech/blog/the-wonders-of-ai">终止赏金计划</a>，提交漏洞和 PR 都不会有奖金。</p>

<blockquote>
  <p>炮制垃圾内容的人可能只需要一分钟就能提交，但我们却要花费数小时来阅读、理解和回应。而且，这类内容的生成速度几乎是无限的。</p>

<p>虽然可以设置自动化脚本来过滤 PR，但由于涉及到奖金，提交 AI 代码的动机实在太大，总是有人无休止地争论、重新打开同一个 PR 等等。</p>
</blockquote>

<p>这件事告诉我们，传统的漏洞赏金计划在 AI 时代大概率行不通。以后，发现漏洞很可能没有奖金。不知道这会不会导致线上攻击行为的增加。</p>

<h2>科技动态</h2>

<p>1、<a href="https://news.yale.edu/2026/05/20/warmer-temps-heavier-owl-monkeys-climate-linked-weight-gain-primates">体重与气温</a></p>

<p>一支耶鲁大学的考察队，发现阿根廷的猫头鹰猴比25年前更重。2023年的猴子平均体重比1999年重了50克，相当于增加了4%。</p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052103.webp" alt="" title=""></p>

<p>科学家认为，这与气温上升有关。1999年阿根廷的日平均气温为22.2摄氏度，2023年上升到了23.8摄氏度。</p>

<p>气温上升使得猴子减少用于体温调节的能量消耗，从而有额外的卡路里来增重。</p>

<p>该理论看上去也适用于人类，也就是说，全球变暖可能让胖子变多。</p>

<p>2、<a href="https://www.nationalgeographic.com/science/article/artificial-egg-colossal-chickens-moa-dodo">人工蛋壳</a></p>

<p>美国生物科技公司 Colossal 制造了"人工蛋壳"，已经孵化了26只小鸡。</p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052403.webp" alt="" title=""></p>

<p>它的外壳是一个坚固的六边形杯状结构，起到支撑作用；内壁是一层半透膜材料，能让氧气轻松通过，又能保持水分。</p>

<p>科研人员将小鸡胚胎放入"人工蛋壳"，在孵化箱中成功孵化了小鸡。</p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052404.webp" alt="" title=""></p>

<p>上图中，蛋壳上方是透明的，可以观察内部情况。</p>

<p>Colossal 公司制造这个装置的目的，是为了复活已经灭绝的渡渡鸟。否则，就算做出了渡渡鸟的克隆胚胎，还是要放在其他动物（比如鸵鸟）体内进行繁殖。</p>

<p>3、<a href="https://p26.bg/news/dupkite-po-ul-chiprovci-v-sofiya-se-prevarnaha-v-ulichna-galeriya-snimki-4310news.html">艺术抗议</a></p>

<p>保加利亚首都索非亚，马路上有一个小坑，市政府长期不修补。</p>

<p>两个艺术家感到不满，就在这个小坑上涂鸦，画了一个生气的鬼脸。</p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026051702.webp" alt="" title=""></p>

<p>鲜艳的图案让司机和行人更容易注意到，减少了事故。同时，也引起了大众的兴趣，新闻媒体纷纷报道，小坑很快就修补了。</p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026051703.webp" alt="" title=""></p>

<p>这件事告诉我们，不满还是要表达出来，可以推动解决，并且采用艺术形式表达，效果会比较好，容易让人接受。</p>

<h2>文章</h2>

<p>1、<a href="https://davidoks.blog/p/ai-is-killing-the-cheap-smartphone">内存涨价的原因</a>（英文）</p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052301.webp" alt="" title=""></p>

<p>内存厂商生产三种内存：DDR（桌面电脑用的内存）、LPDDR（手机用的低功率内存）、HBM（AI 机房用的高带宽内存）。</p>

<p>由于 AI 公司对 HBM 的需求激增，开出高价，内存厂商的生产能力转向 HBM，减少了 DDR 和 LPDDR 的产量，导致消费电子设备的内存短缺，价格上涨。 </p>

<p>2、<a href="https://www.jonaharagon.com/posts/im-getting-into-mesh-networks-meshtastic-meshcore-and-reticulum/">我开始研究 Reticulum</a>（英文）</p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052801.webp" alt="" title=""></p>

<p>Reticulum 是一个自己组网的项目，可以在各种物理网络（WiFi、有线网、无线电、LoRa 等）之上架设虚拟网络，本文是一个简介。</p>

<p>3、<a href="https://z3ugma.github.io/2019/11/18/warm-up-your-macbook/">预热你的 MacBook</a>（英文）</p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052802.webp" alt="" title=""></p>

<p>一篇很冷的文章，Mac 系统有一个 stress 命令，用来让 CPU 运行负载。本文提出可以用这个命令，让冬天冰冷的 MacBook 金属外壳变热。</p>

<p>4、<a href="https://abuseofnotation.github.io/boolean-thinking/">为什么我反对布尔逻辑</a>（英文）</p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052302.webp" alt="" title=""></p>

<p>一篇偏哲学思辨的文章。布尔逻辑只有两个值（真和伪），作者认为，这会导致非黑即白的二元思维。真实世界是非布尔逻辑，充满了不确定性和不唯一性。</p>

<p>5、<a href="https://www.quantamagazine.org/the-math-that-explains-why-bell-curves-are-everywhere-20260316/">为什么中心极限定理无处不在？</a>（英文）</p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202603/bg2026031915.webp" alt="" title=""></p>

<p>一篇科普文章，介绍中心极限定理的历史和含义。这个定理发现了样本平均值的分布规律，所以极其重要。</p>

<p>样本平均值满足正态分布，但有两个注意点，一是每次的样本必须相互独立，二是有时异常值比平均值更重要。</p>

<h2>工具</h2>

<p>1、<a href="https://github.com/eigenpal/docx-editor">DOCX Editor</a></p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052202.webp" alt="" title=""></p>

<p>开源的 docx 文件的网页编辑器，所见即所得。</p>

<p>2、<a href="https://dynip.dev/">DvnIP</a></p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052601.webp" alt="" title=""></p>

<p>动态 IP 服务，个人用户免费。</p>

<p>3、<a href="https://editor.graphite.rs/">Graphite</a></p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202410/bg2024101704.webp" alt="" title=""></p>

<p>一个矢量作图的 Web 应用，<a href="https://github.com/GraphiteEditor/Graphite">代码开源</a>。</p>

<p>4、<a href="https://github.com/chaosprint/hindsight">Hindsight</a></p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202601/bg2026010203.webp" alt="" title=""></p>

<p>一个命令行工具，扫描本地的 git 仓库，生成 GitHub 风格的个人提交热力图。</p>

<p>5、<a href="https://github.com/nyakang/nyaterm">NyaTerm</a></p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052201.webp" alt="" title=""></p>

<p>跨平台的桌面应用，将 SSH、终端会话、远程文件、认证信息、端口转发和配置备份放在同一个工作区。（<a href="https://github.com/ruanyf/weekly/issues/10021">@nyakang</a> 投稿）</p>

<p>6、<a href="https://github.com/wagoodman/dive">diving-rs</a></p>

<p>一个命令行工具，展示 docker 镜像内部的每一层文件列表。（<a href="https://github.com/ruanyf/weekly/issues/10037">@vicanso</a> 投稿）</p>

<p>7、<a href="https://github.com/nine19een/CanvasCast">CanvasCast</a></p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052401.webp" alt="" title=""></p>

<p>白板录制的网页应用，在浏览器中直接绘制、演示、录制白板风格的内容。（<a href="https://github.com/ruanyf/weekly/issues/10055">@Hao4Wang</a> 投稿）</p>

<p>8、<a href="https://github.com/echo-loop/Echo-Loop">Echo Loop</a></p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052704.webp" alt="" title=""></p>

<p>开源的英语听说训练 App。（<a href="https://github.com/ruanyf/weekly/issues/10082">@echo-loop</a> 投稿）</p>

<p>9、<a href="https://github.com/Simon-He95/vue-tui">Vue TUI</a></p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052705.webp" alt="" title=""></p>

<p>基于 Vue 的终端组件库，可以用来开发 agent。（<a href="https://github.com/ruanyf/weekly/issues/10083">@Simon-He95</a> 投稿）</p>

<p>10、<a href="https://github.com/pranshuparmar/witr">witr</a></p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202601/bg2026010313.webp" alt="" title=""></p>

<p>命令行工具，显示当前每个进程对应什么命令，可以用命令名或端口号查询。</p>

<h2>AI 相关</h2>

<p>1、<a href="https://github.com/esengine/DeepSeek-Reasonix">DeepSeek Reasonix</a></p>

<p>专为 DeepSeek 设计的终端 AI 编程 agent，充分利用了缓存机制，可以极大降低费用，只支持 DeepSeek 的付费 API。</p>

<p>2、<a href="https://github.com/modelscope/FunASR">FunASR</a></p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052402.webp" alt="" title=""></p>

<p>阿里通义实验室开源的工业级语音识别工具包，最近推出了桌面语音输入法工具。（<a href="https://github.com/ruanyf/weekly/issues/10056">@LauraGPT</a> 投稿）</p>

<p>另有两个基于它的衍生工具。</p>

<ul>
<li><a href="https://github.com/modelscope/FunClip">FunClip</a>：智能视频裁剪工具。输入关键词或句子，自动定位视频中对应的片段，一键裁剪导出。（<a href="https://github.com/ruanyf/weekly/issues/10057">@LauraGPT</a> 投稿）</li>
<li><a href="https://github.com/FunAudioLLM/SenseVoice">SenseVoice</a>：语音理解工具，可以识别语音、语种、情感、声音事件。（<a href="https://github.com/ruanyf/weekly/issues/10058">@LauraGPT</a> 投稿）</li>
</ul>

<p>3、<a href="https://github.com/SakuraByteCore/codexmate">Codex Mate</a></p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052706.webp" alt="" title=""></p>

<p>一站式本地 AI 编程智能体管理面板。统一管理 Codex、Claude Code、Gemini CLI、CodeBuddy、OpenClaw、Gemini CLI。（<a href="https://github.com/ruanyf/weekly/issues/10088">@ymkiux</a> 投稿）</p>

<h2>资源</h2>

<p>1、<a href="https://github.com/KeyAI/calculusmadeeasy-zh">微积分其实很容易</a></p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052407.webp" alt="" title=""></p>

<p>著名教材《Calculus Made Easy》非官方中文版，一本易读的微积分入门小书，可以<a href="https://keen-ginger-62hw.here.now/">在线阅读</a>。（<a href="https://github.com/ruanyf/weekly/issues/10065">@KeyAI</a> 投稿）</p>

<p>2、<a href="https://funes.world/apps/the-hanging-sculptures-of-the-xiaoxitian">小西天 3D 全景</a></p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052104.webp" alt="" title=""></p>

<p>山西省隰县小西天的网页 3D 全景导览。</p>

<p>3、<a href="https://stefansf.de/c-quiz/">C 语言小测验</a>（英文）</p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052304.webp" alt="" title=""></p>

<p>一组 C 语言的语法选择题。</p>

<h2>图片</h2>

<p>1、<a href="https://www.calculators.de/">袖珍计算器博物馆</a></p>

<p>德国有一个网上博物馆，专门收集各种袖珍计算器，里面有一些奇特的电子计算器。</p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052205.webp" alt="" title=""></p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052206.webp" alt="" title=""></p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052207.webp" alt="" title=""></p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052204.webp" alt="" title=""></p>

<p><img src="https://cdn.beekka.com/blogimg/asset/202605/bg2026052203.webp" alt="" title=""></p>

<h2>文摘</h2>

<p>1、<a href="https://www.sina.cn/news/detail/5279286413232198.html">行为经济学诱饵</a></p>

<p>行为经济学家丹·艾瑞里，有一天闲逛《经济学人》官网。</p>

<p>他在订阅页面上，看到了三个选项：</p>

<blockquote>
  <p>A. 电子版----59美元。
B. 纸质版----125美元。
C. 纸质版＋电子版----125美元。</p>
</blockquote>

<p>他愣住了。</p>

<p>B 和 C，价格一模一样。一个只给纸质版，一个纸质版加电子版全送。谁会选 B？</p>

<p>傻子都不会啊。但艾瑞里没有笑，马上意识到这是一个绝妙的设计。</p>

<p>他拿着这三个选项，走进了麻省理工学院（MIT）的课堂，做了一个实验，让100个学生对这三个选项进行选择。</p>

<p>结果：16%的学生选了 A，0%选了B，84%选了C。订阅费总收入：11,444美元。</p>

<p>跟预想的一样，没有一个人选 B。</p>

<p>然后艾瑞里做了一件小事：他把 B 删了，只留 A 和 C。</p>

<p>逻辑上，一个从来没人选的东西，删掉它不应该影响任何结果，对吧？</p>

<p>结果出来了：68%选了 A，32%选了 C。订阅费总收入暴跌到8,012美元。</p>

<p>这就是选项 B 的作用。它从来没人选，自己一份都没卖出去，却在暗中帮旁边的最贵的 C 套餐，多卖了52%。</p>

<p>仅仅因为它的"存在"，就让杂志社多赚了3,432美元。这就是行为经济学中著名的"诱饵效应"。</p>

<p>原理很简单：人类不擅长判断一个东西的"绝对价值"，但极其擅长做"相对比较"。</p>

<p>当只有59美元和125美元两个选项时，你的大脑在比较"便宜 vs 贵"，大多数人选便宜的。</p>

<p>但当"125美元只买纸质版"这个诱饵一出现，你的大脑就不比较 A 和 C 了，它开始比较 B 和 C。</p>

<p>同样的价格，C 多了一个电子版。天哪，这不是白捡的吗！于是你心满意足地选了 C。</p>

<p>浑然不知自己刚刚多花了66美元----买了一本可能一辈子都不会翻开的纸质杂志。</p>

<p>这个套路如今无处不在。咖啡店的中杯定价，只是为了让你觉得大杯"更划算"。视频网站的月卡，贵到让你觉得年卡"不买就亏"。</p>

<p>手机发布会上，永远有一款"高价低配"机型，它唯一的使命，就是让旁边那款旗舰机型看起来"性价比极高"。</p>

<p>当你觉得自己占了便宜的时候，多半是有人精心摆放了一个诱饵，让你心甘情愿走进了更贵的那扇门。</p>

<p>那个没人选的选项，才是全场真正的主角。</p>

<h2>言论</h2>

<p>1、</p>

<p>很多人看不到 AI 改变世界的潜力，原因在于他们不明白一切事物都是算法。</p>

<p>具体来说，他们没有意识到，社会和公司只不过是一系列算法的集合。</p>

<p>-- <a href="https://danielmiessler.com/blog/companies-graph-of-algorithms">《公司不过是算法图而已》</a></p>

<p>2、</p>

<p>为了应对"软件包投毒"，现在的流行做法是，新发布的软件包设置一个冷却时间，普通用户需要过了"冷却期"才能安装这个包。</p>

<p>这种机制可以有效抵御供应链攻击，但它有一个棘手的问题：它依赖于其他人先安装这个包。到哪里去找这些人，第一时间试用每个新发布的包呢？</p>

<p>-- <a href="https://illegalcode.net/rfcs/phased_rollouts.html">《软件包应该分阶段推出》</a></p>

<p>3、</p>

<p>AI 可以一对一的定制化教育，效果更好，大学对很多人将变得没有价值。</p>

<p>-- <a href="https://fortune.com/2025/07/24/sam-altman-college-not-working-great-stanford-dropout/">萨姆·奥特曼</a>（Sam Altman），OpenAI 公司首席执行官</p>

<p>4、</p>

<p>那些从未编写过一行代码的非技术型中层管理人员，现在感觉通往成功的最大障碍已经消失。</p>

<p>他们再也不用应付那些烦人的程序员了，不需要程序员就能更改网页样式和用户体验，自己实现某些功能。而且，AI 不会抱怨，不会组织工会，也不会抗议，只会服从任何命令。</p>

<p>-- <a href="https://pop.rdi.sh/where-does-next-token-prediction-leave-us/">《AI 将把我们引向何方》</a></p>

<p>5、</p>

<p>我喜欢 PHP 的一个理由是，它的变量使用美元符号（$）识别，这会提醒你，你使用它是为了什么。</p>

<p>-- <a href="https://flowtwo.io/post/php's-oddities">《PHP 的奇特之处》</a></p>

<h2>往年回顾</h2>

<p><a href="https://www.ruanyifeng.com/blog/2025/06/weekly-issue-351.html">GitHub Issues（几乎）是最好的笔记应用</a>（#351）</p>

<p><a href="https://www.ruanyifeng.com/blog/2024/05/weekly-issue-301.html">OpenAI 的图书馆工位</a>（#301）</p>

<p><a href="https://www.ruanyifeng.com/blog/2023/04/weekly-issue-251.html">国产单板机值得推荐</a>（#251）</p>

<p><a href="https://www.ruanyifeng.com/blog/2022/04/weekly-issue-201.html">中国需要成立半导体部</a>（#201）</p>

<p>（完）</p>

        <div><h3>文档信息</h3>
<ul>
<li>版权声明：自由转载-非商用-非衍生-保持署名（<a href="http://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh">创意共享3.0许可证</a>）</li>
<li>发表日期： <abbr class="published" title="2026-05-29T08:08:39+08:00">2026年5月29日</abbr></li>

</ul></div>        
        <div></div>
				<p><strong>您可能还对下面的文章感兴趣：</strong></p>
				<p><ol><li><a href="https://blogread.cn/it/article.php?id=8531" target="_blank">The “Bug-Free” Workforce: How AI Efficiency Is Subtly Disrupting The Interactions That Build Strong Teams</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8503" target="_blank">Notex：一个开源 NotebookLM 替代方案的实现</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8296" target="_blank">美好世界，源自不开心。 </a> [2020-02-01 15:14:13]</li><li><a href="https://blogread.cn/it/article.php?id=7558" target="_blank">百夫长：互联网时代公司的关键员工</a> [2015-11-02 22:30:08]</li><li><a href="https://blogread.cn/it/article.php?id=6857" target="_blank">朋友，不要再打听彼此薪水</a> [2014-04-29 22:35:15]</li><li><a href="https://blogread.cn/it/article.php?id=6731" target="_blank">微博的核心用户群：中V和小V</a> [2013-10-08 12:34:49]</li><li><a href="https://blogread.cn/it/article.php?id=6624" target="_blank">关键词推荐技术介绍</a> [2013-08-21 13:13:54]</li><li><a href="https://blogread.cn/it/article.php?id=6592" target="_blank">如何有效的进行道歉</a> [2013-08-08 23:43:47]</li><li><a href="https://blogread.cn/it/article.php?id=6532" target="_blank">失败的人生</a> [2013-07-26 13:32:27]</li><li><a href="https://blogread.cn/it/article.php?id=6489" target="_blank">与Google拼音的工程师聊聊中文滑行输入</a> [2013-07-07 17:56:41]</li><li><a href="https://blogread.cn/it/article.php?id=6475" target="_blank">浅谈翻译的两个基本问题</a> [2013-06-18 13:48:13]</li><li><a href="https://blogread.cn/it/article.php?id=5735" target="_blank">一条微博被恶搞所引起的思考</a> [2012-08-27 13:51:33]</li><li><a href="https://blogread.cn/it/article.php?id=5547" target="_blank">若无云，岂有风——词语语义相似度计算简介</a> [2012-07-09 23:09:38]</li><li><a href="https://blogread.cn/it/article.php?id=5546" target="_blank">检索结果聚类展望</a> [2012-07-09 23:08:56]</li><li><a href="https://blogread.cn/it/article.php?id=4725" target="_blank">我们其实在关心什么</a> [2012-01-02 20:46:24]</li><li><a href="https://blogread.cn/it/article.php?id=4440" target="_blank">闲谈翻译</a> [2011-10-04 18:09:02]</li><li><a href="https://blogread.cn/it/article.php?id=4089" target="_blank">WEB数据挖掘相关术语整理</a> [2011-07-30 21:54:23]</li><li><a href="https://blogread.cn/it/article.php?id=3837" target="_blank">一种生成事件脉络的方法</a> [2011-06-21 13:36:39]</li><li><a href="https://blogread.cn/it/article.php?id=3599" target="_blank">尽量提高网络流言分辨力</a> [2011-05-17 08:59:28]</li><li><a href="https://blogread.cn/it/article.php?id=3395" target="_blank">如何训练你的大脑去适应一种新语言</a> [2011-03-03 22:43:53]</li><li><a href="https://blogread.cn/it/article.php?id=2987" target="_blank">如何预测用户query意图</a> [2011-01-10 23:19:10]</li><li><a href="https://blogread.cn/it/article.php?id=2966" target="_blank">从狄仁杰的测字占卜到一淘网的Query分析之大结局</a> [2011-01-05 22:26:37]</li><li><a href="https://blogread.cn/it/article.php?id=2729" target="_blank">百度这个公司</a> [2010-11-22 21:17:57]</li><li><a href="https://blogread.cn/it/article.php?id=2620" target="_blank">读书笔记-壹百度:百度十年千倍的29条法则</a> [2010-10-31 23:22:30]</li><li><a href="https://blogread.cn/it/article.php?id=2609" target="_blank">论互联网的中国管理模式</a> [2010-10-30 08:02:52]</li><li><a href="https://blogread.cn/it/article.php?id=2562" target="_blank">存在就是真理-从一个关键字看百度和Google的产品体验</a> [2010-10-25 09:03:19]</li><li><a href="https://blogread.cn/it/article.php?id=2037" target="_blank">从细节看知识搜索</a> [2010-07-21 23:38:41]</li><li><a href="https://blogread.cn/it/article.php?id=1675" target="_blank">怎样翻译更地道：It is…that…句型谚语的翻译</a> [2010-06-01 00:00:04]</li><li><a href="https://blogread.cn/it/article.php?id=1557" target="_blank">怎样翻译更地道：译者一定要多走一步</a> [2010-05-19 13:49:57]</li><li><a href="https://blogread.cn/it/article.php?id=1520" target="_blank">怎样翻译更地道：and不是“和”</a> [2010-05-09 22:59:26]</li><li><a href="https://blogread.cn/it/article.php?id=1388" target="_blank">怎样翻译更地道：无生物主语的处理</a> [2010-04-15 09:53:29]</li><li><a href="https://blogread.cn/it/article.php?id=1265" target="_blank">三十分之一的梦想</a> [2010-03-29 08:49:59]</li><li><a href="https://blogread.cn/it/article.php?id=1192" target="_blank">怎样翻译更地道：“as somebody said…”的翻译</a> [2010-03-11 23:38:29]</li><li><a href="https://blogread.cn/it/article.php?id=694" target="_blank">怎样翻译更地道：so…that…的翻译</a> [2009-11-24 22:45:42]</li><li><a href="https://blogread.cn/it/article.php?id=401" target="_blank">自己做了个简繁转换的东西</a> [2009-11-02 12:27:54]</li><li><a href="https://blogread.cn/it/article.php?id=85" target="_blank">小心被互联网脑残定律降低了你的IQ/EQ</a> [2009-10-12 09:06:53]</li></ol></p>]]></description>
		<content><![CDATA[本期围绕 AI 编程的 Token 成本问题展开讨论。通过 OpenClaw 创始人每月消耗 6030 亿 Token、价值 130 万美元的案例，揭示了放开使用顶级 AI 模型的惊人开销。按此计算，单个程序员年费用可达数千万甚至上亿人民币，即便使用国内便宜模型也需数百万。文章指出，即便是 Uber 和微软等巨头也因费用过高而不得不限制 AI 使用，说明公司几乎必然会设置调用限制，这使得 AI 编程在大型项目中的成本远高于人工。由此得出结论：现阶段 AI 不会大规模替代程序员，除非未来 Token 费用大幅下降。

此外，文章还提及了漏洞赏金计划在 AI 时代面临的新挑战。由于大模型能快速生成低质量漏洞报告，项目如 Turso 不得不终止赏金计划，这引发了对传统安全激励机制在 AI 背景下有效性的思考。其他内容包括科技动态（如气温上升导致动物增重、人工蛋壳技术）、多篇推荐文章以及一系列新发布的开发工具和资源，覆盖了从内存市场趋势到哲学思辨的广泛话题。]]></content>
	</item>
	<item>
		<title>Algorithmic Theming Engines: Building Self-Correcting Color Systems With `contrast-color()`</title>
		<link>https://blogread.cn/it/article.php?id=8595</link>
		<author>Articles on Smashing Magazine — For Web Designers And Developers</author>
		<pubDate>2026-06-03 09:03:24</pubDate>
		<category domain="https://blogread.cn/it/category.php?id=7">前端</category>
		<guid>https://blogread.cn/it/article.php?id=8595</guid>
		<comments>https://blogread.cn/it/article.php?id=8595#comment</comments>
		<description><![CDATA[<p><strong>标签：</strong>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=contrast-color" target="_blank">contrast-color</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=WCAG" target="_blank">WCAG</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=%E4%B8%BB%E9%A2%98%E5%BC%95%E6%93%8E" target="_blank">主题引擎</a></p><p>The <a href="https://almanac.httparchive.org/">HTTP Archive Web Almanac</a> has been tracking color contrast failures for years. The numbers have barely moved. After half a decade of design system tooling, accessibility linters, and entire JavaScript libraries dedicated to computing readable text colors, <a href="https://almanac.httparchive.org/en/2025/accessibility#color-contrast">70% of websites still fail basic WCAG contrast checks in 2025</a>. The <a href="https://webaim.org/projects/million/">WebAIM Million</a> paints an even grimmer picture — 83.9% of homepages flagged for low contrast text in 2026, up from 79.1% in 2025. The rate improves by maybe a few percentage points per year on one benchmark and actually gets <em>worse</em> on another. That’s not progress — that’s proof that relying on runtime JavaScript for something this fundamental doesn’t scale across the open web. We didn’t need better libraries. We’ve needed better CSS.</p>
<p>The <code>contrast-color()</code> function is that better CSS. One declaration. The browser runs the contrast math during style computation, before the page paints, and hands you the right text color. No library, no build step, no hydration flash.</p>
<p><strong>Note</strong>: If you’ve seen it called <code>color-contrast()</code> in older articles and spec drafts — <a href="https://github.com/w3c/csswg-drafts/issues/7557">that name was changed</a>, and the old syntax no longer works in any browser.</p>
What It Does (And What It Doesn’t)
<p>The Level 5 version is simple. You give it a color. It gives you back <code>black</code> or <code>white</code>, whichever has more contrast against your input.</p>
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">.button {
  background-color: var(--brand-color);
  color: contrast-color(var(--brand-color));
}</code></pre>

<p>Change <code>--brand-color</code> to neon green, text goes black. Change it to midnight navy, text goes white. Swap themes at runtime via JavaScript and the text adapts instantly — no event listeners, no recalculation.</p>
<p>A few things to know about the current version:</p>
<ul>
<li>It returns a <code>&lt;color&gt;</code>, not a number. You get an actual color value (<code>black</code> or <code>white</code>), you can use anywhere CSS accepts a color.</li>
<li><strong>Black or white only</strong>, for now. Candidate color lists and target ratios are planned for Level 6.</li>
<li><strong>No keywords.</strong> If you’ve seen <code>max</code> in older blog posts, that was stripped from the spec. Using it will silently break your declaration.</li>
<li>As mentioned above, this function used to be called <code>color-contrast()</code> in early drafts. That name is dead — <a href="https://github.com/w3c/csswg-drafts/issues/7557">the CSSWG renamed it</a> to follow the convention that CSS functions are named for what they return. <code>color-mix()</code> returns a color. <code>contrast-color()</code> returns a color. The old <code>color-contrast()</code> name sounded like it returned a contrast <em>ratio</em> (a number like 4.5), which was misleading. Any tutorial from 2021–2023 showing <code>color-contrast()</code> syntax won’t work in current browsers.</li>
</ul>
The Spec Split: Level 5 Versus Level 6
<p>This function lives across two specifications. That’s unusual and worth understanding.</p>
<p><a href="https://www.w3.org/TR/css-color-5/#contrast-color"><strong>CSS Color Level 5</strong></a> defines what browsers ship today. One color in, black or white out. The algorithm is deliberately marked “UA-defined”, meaning the browser decides what math to use internally. Right now, every engine uses WCAG 2.x relative luminance. But that “UA-defined” label isn’t accidental — it’s a planned escape hatch.</p>
<p>You’ll see APCA (<strong>Accessible Perceptual Contrast Algorithm</strong>) mentioned a lot in this context. APCA models how human eyes actually perceive contrast, factoring in font weight, spatial frequency, and ambient light — a genuine improvement over the WCAG 2.x formula. By not locking <em>“use WCAG 2.x”</em> into the Level 5 spec, browser vendors <em>could</em> swap to APCA later without breaking any existing code. If the spec had shipped with a <code>wcag2()</code> keyword as the default, every site using it would’ve been stuck on the old math permanently.</p>
<p>But APCA’s future is far less certain than the hype suggests. Adrian Roselli’s “<a href="https://adrianroselli.com/2026/04/wcag3-contrast-as-of-april-2026.html">WCAG3 Contrast as of April 2026</a>” lays out the current situation clearly: APCA was pulled from the WCAG 3 working draft <a href="https://www.w3.org/TR/2023/WD-wcag-3.0-20230724/#color-and-contrast">in mid-2023</a> after failing to gain enough Working Group support. The WCAG 3 spec currently says the contrast algorithm is <em>“yet to be determined,”</em> and the standard itself <a href="https://www.w3.org/WAI/standards-guidelines/wcag/wcag3-intro/#timeline">may not be finalized until 2030 or later</a>. Roselli also <a href="https://issues.chromium.org/issues/341439947">filed a Chromium issue in May 2024</a> asking for the “Advanced Perceptual Contrast Algorithm” experiment flag to be removed from DevTools entirely, arguing that the implementation is outdated and risks misleading developers into thinking APCA is further along — or more official — than it actually is. That issue is still open.</p>
<p>None of this means APCA is dead. The research behind it is peer-reviewed and substantive, and its creator <a href="https://adrianroselli.com/2026/04/wcag3-contrast-as-of-april-2026.html#comment-408186">has noted</a> that colors passing APCA guidelines greatly exceed WCAG 2 minimums in the vast majority of cases. But right now, there is no guarantee APCA will be the algorithm that replaces WCAG 2.x — and that uncertainty matters for <code>contrast-color()</code>. If a different algorithm wins out, or if WCAG 3 adopts something entirely new, the “UA-defined” label means browsers can adapt without breaking your code. It also means the Level 6 features — candidate color lists, target ratios, the <code>tbd-fg</code>/<code>tbd-bg</code> keywords — are all designed around an algorithm that may or may not materialize in its current form.</p>
<p><strong>CSS Color Level 6</strong> adds the extended syntax — candidate color lists and target contrast ratios:</p>
<div>
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">/* Level 6 future syntax — not shipping yet */
color: contrast-color(var(--bg) tbd-bg wcag2(aa), #1a1a2e, #e2e8f0, #fbbf24);</code></pre>
</div>

<p>The browser would evaluate each candidate left to right and pick the first that meets the 4.5:1 AA threshold. The <code>tbd-fg</code> and <code>tbd-bg</code> keywords indicate whether the base color is foreground or background, which matters for directional contrast models like APCA. This is all Working Draft territory — doubly so given APCA’s uncertain status. Use the Level 5 version for now.</p>
Browser Support
<p>This one’s in better shape than most new CSS features. All three major engines have shipped it in stable releases: <a href="https://chromestatus.com/feature/40142548">Chrome 147</a> (April 2026), <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/contrast-color">Firefox 146</a>, and <a href="https://developer.apple.com/documentation/safari-release-notes/safari-26-release-notes">Safari 26.0</a>. It reached <a href="https://web.dev/baseline/">Baseline Newly Available</a> status in April 2026. Check <a href="https://caniuse.com/mdn-css_types_color_contrast-color">caniuse</a> for the full version matrix. All three engines pass the Web Platform Tests for <code>contrast-color()</code>, which means the edge cases (e.g., tie-breaking logic, color space conversion, syntax parsing) behave the same across browsers.</p>
<p>The raw global support percentage on caniuse looks low, but that mostly reflects enterprise browsers and people who never update. If you’re reading this, your browser almost certainly supports it already.</p>
<p>Progressive enhancement is straightforward using <code>@supports</code>:</p>
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">.card {
  background: var(--bg);
  color: #fff;
  text-shadow: 0 0 4px rgb(0 0 0 / 0.8);
}

@supports (color: contrast-color(red)) {
  .card {
    color: contrast-color(var(--bg));
    text-shadow: none;
  }
}</code></pre>

<p>Older browsers get white text with a dark shadow for legibility. Supporting browsers get the native calculation. Nobody sees broken text.</p>
<p>One thing to watch for: automated accessibility scanners (Lighthouse, Axe, etc.) can’t evaluate <code>text-shadow</code>. They only look at the computed <code>color</code> against <code>background-color</code>. So the fallback will still get flagged as a contrast failure in CI/CD pipelines, even if the shadow makes the text perfectly legible to human eyes. If your team runs automated a11y checks, you may need to allowlist that specific rule or add a comment explaining why the flag is a false positive.</p>
<blockquote><strong>A note on PostCSS</strong>:<br><br>There’s a plugin (<a href="https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-contrast-color-function"><code>@csstools/postcss-contrast-color-function</code></a>) that evaluates <code>contrast-color()</code> at build time. It works for static colors like <code>contrast-color(#ff0000)</code>. But the moment you use a custom property — <code>contrast-color(var(--bg))</code> — the plugin can’t help because it has no access to runtime values. If your theming is dynamic (which is the whole point of doing this), skip the polyfill and rely on <code>@supports</code>.</blockquote>



The Gotchas
<h3>It Doesn’t Guarantee Perceptual or AAA Compliance</h3>
<p>This can trip people up: <em>“I used the contrast function, so my site passes accessibility checks now, right?”</em></p>
<p>Mathematically? Usually yes. There is a persistent myth that for certain “mid-tone” backgrounds, both black and white fail the standard WCAG 4.5:1 AA ratio. That’s mathematically false. Under the WCAG 2.x relative luminance formula, there is absolutely no background color where both pure black and pure white fail AA. One (or both) will always pass.</p>
<p>Take <code>#2277d3</code> (a medium blue). It sits right on a mathematical knife-edge where both black and white actually pass AA (both hit roughly 4.58:1). <code>contrast-color()</code> will hand you whichever has the slight mathematical edge.</p>
<p>But here is the actual gotcha: the WCAG 2.x math has known perceptual blind spots. That same <code>#2277d3</code> with black text mathematically passes AA, but to human eyes, it can be incredibly difficult to read. <code>contrast-color()</code> gives you <em>mathematical</em> compliance, which is great for automated audits, but that doesn’t always equal <em>perceptual</em> accessibility. (This is exactly why APCA exists and why the spec was designed to let browsers swap algorithms later.)</p>
<p>Furthermore, if you’re aiming for the stricter WCAG AAA standard (7.0:1), a true dead zone <em>does</em> exist. For backgrounds with a luminance between roughly 10% and 30%, neither black nor white will hit 7:1. In those cases, <code>contrast-color()</code> can’t save you — it just hands you the “least bad” failing option.</p>
<h3>Transitions Snap, Not Fade</h3>
<p>If you’re animating a background from <code>white</code> to <code>black</code> on hover:</p>
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">.btn {
  background-color: #fff;
  color: contrast-color(#fff); /* black */
  transition: background-color 1s, color 1s;
}
.btn:hover {
  background-color: #000;
  color: contrast-color(#000); /* white */
}</code></pre>

<p>The background fades smoothly over one second. But because the Level 5 output is a <a href="https://www.w3.org/TR/css-transitions-1/#discrete">discrete value</a> (black or white), the text color can’t be interpolated. It snaps.</p>
<p>And here is the visual gotcha: the snap doesn’t happen halfway through. If you’ve been building themes for a while, you probably have muscle memory from the old Sass days, where we checked if <code>lightness($bg) &gt; 50%</code>. That relied on HSL lightness, where 50% is the geometric midpoint.</p>
<p>But WCAG 2.x relative luminance is a non-linear scale. Under the WCAG formula, the mathematical tipping point — where black and white have identical contrast against the background — actually occurs at approximately 18% relative luminance (specifically ~17.9%).</p>
<p>Because of that, the visual behavior during a white-to-black fade is heavily skewed. The text doesn’t snap in the middle. It stays black for the vast majority of the animation, only snapping to white at the very tail-end of the transition when the background gets extremely dark. It’s a jarring, late hard cut.</p>
<p>You might assume <a href="https://css-tricks.com/almanac/properties/t/transition/transition-behavior/"><code>transition-behavior: allow-discrete</code></a> fixes this. It doesn’t. <code>allow-discrete</code> does not fix the jarring visual experience because it cannot interpolate a binary output; it only shifts the timing of the hard snap to the 50% mark of the animation duration. If you need smooth text color transitions, you’ll have to layer <code>color-mix()</code> or manage the crossfade yourself.</p>
<h3>Tie Goes To White</h3>
<p>If the background is a perfect middle gray where both black and white produce identical contrast ratios, <a href="https://www.w3.org/TR/css-color-5/#contrast-color">the spec has a hardcoded tiebreaker</a>: white wins. Not a big deal in practice, but worth knowing if you’re debugging gray palettes and the text isn’t doing what you expect.</p>
<h3>Gradients And Images Are Out</h3>
<p>The function takes a flat <code>&lt;color&gt;</code> value. You can’t pass it a gradient or a <code>url()</code>. <code>contrast-color(linear-gradient(...))</code> is a parse error. If your background is a photo or a complex gradient, you still need JavaScript or manually color-pick for overlay text.</p>
<h3>Transparent Colors Are Composited First</h3>
<p>Pass a semi-transparent color, and the browser blends it against an assumed opaque canvas (usually white) before running the contrast math. It’s not ignoring your alpha channel — it’s compositing it. But the result might surprise you if you expected the function to “see through” to whatever’s actually behind the element.</p>
<h3>Windows High Contrast Mode</h3>
<p>If a user enables Windows High Contrast, the <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@media/forced-colors"><code>forced-colors: active</code></a> media query kicks in and the browser aggressively overwrites author-defined colors. <code>contrast-color()</code> bows out — <a href="https://www.w3.org/TR/css-color-adjust-1/#forced-colors-mode">forced system colors</a> like <code>CanvasText</code> take over completely. You don’t need to write manual media queries to undo your contrast logic; the browser handles the hierarchy.</p>
Combining It With Other Color Functions
<p>Black or white sounds limiting, but once you feed that output into other CSS color functions, you can build an entire component palette off a single custom property.</p>
<h3>Brand-Tinted Contrast With Relative Color Syntax</h3>
<p>Pure black text on a vibrant card looks fine. Pure white on a coral card can feel flat. What if the contrast text was a very dark or very light <em>tint</em> of the background color instead?</p>
<p>Kevin Hamer explored related territory in his CSS-Tricks piece “<a href="https://css-tricks.com/approximating-contrast-color-with-other-css-features/">Approximating contrast-color() With Other CSS Features</a>”, where he used OKLCH lightness and <code>round()</code> to approximate the black/white switch <em>without</em> <code>contrast-color()</code> — essentially <code>oklch(from &lt;color&gt; round(1.21 - l) 0 0)</code>. That’s a polyfill strategy: get the binary light/dark decision working in browsers that don’t support the native function yet. What we’re doing here is different — we <em>start</em> with <code>contrast-color()</code>’s native output and then enrich it by injecting the background’s own hue:</p>
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">.card {
  --bg-hue: 260; /* Indigo */
  --bg: oklch(0.6 0.1 var(--bg-hue));
  background: var(--bg);

  /* Pull L from the black/white contrast color,
     but inject subtle chroma and the background's hue */
  color: oklch(from contrast-color(var(--bg)) l 0.05 var(--bg-hue));
}</code></pre>

<p>When <code>contrast-color()</code> returns white, <code>l</code> is 1 (full lightness). When it returns black, <code>l</code> is 0. By pulling the background’s hue back in and adding a touch of chroma, you get text that reads as a deep dark indigo or a pale icy indigo instead of generic black/white. Hamer’s approach gives you the black/white decision without browser support; this one takes the decision the browser already made and gives it personality.</p>
<p><strong>Fair warning</strong>: By tweaking the lightness and chroma of the black/white output, you can push a borderline contrast ratio into failing territory. Always run your tinted output through an accessibility linter before shipping.</p>
<p><strong>Also worth noting</strong>: This example chains two very modern features — <code>contrast-color()</code> and <code>oklch(from ...)</code>. If either one isn’t supported, the entire declaration fails silently. Your <code>@supports</code> block needs to test for both:</p>
<div>
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">@supports (color: contrast-color(red)) and (color: oklch(from red l c h)) {
  /* Safe to use both */
}</code></pre>
</div>

<h3>Softened Contrast With <code>color-mix()</code></h3>
<p>Similar idea, simpler API. Mix the sharp black/white output back into the background to soften it:</p>
<div>
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">.alert {
  --bg: var(--alert-color);
  background: var(--bg);

  /* 80% contrast, 20% background = softer but readable */
  color: color-mix(in oklch, contrast-color(var(--bg)) 80%, var(--bg));

  /* 40% contrast for a subtle border */
  border: 1px solid
    color-mix(in oklch, contrast-color(var(--bg)) 40%, var(--bg));
}</code></pre>
</div>

<p>One custom property driving text, border, and potentially <code>box-shadow</code> or <code>outline</code>. Change <code>--alert-color</code> and the entire component recalculates.</p>
<p>This pattern also works well for <code>::placeholder</code> text, which is a common pain point in dynamic theming. Placeholder text should be readable but visually softer than the input’s main text — <code>color-mix()</code> with <code>contrast-color()</code> gets you there:</p>
<div>
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">input {
  --bg: var(--input-bg);
  background: var(--bg);
  color: contrast-color(var(--bg));
}

input::placeholder {
  color: color-mix(in oklch, contrast-color(var(--bg)) 50%, var(--bg));
}</code></pre>
</div>

<p><code>50%</code> mix gives you a muted but legible placeholder that adapts automatically to whatever background the input sits on.</p>
<h3>Theme-Aware Contrast With <code>light-dark()</code></h3>
<p>For apps that support system light/dark mode:</p>
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">:root {
  color-scheme: light dark;
  --surface: light-dark(#fff, #121212);
}

.component {
  background: var(--surface);
  color: contrast-color(var(--surface));
}</code></pre>

<p>When the operating system switches to dark mode, <code>--surface</code> resolves to <code>#121212</code>, and <code>contrast-color()</code> returns white. No media queries, no JavaScript theme detection. The whole chain resolves natively.</p>
What You Can Remove From Your Bundle
<p>The practical payoff: every one of these libraries existed because CSS couldn’t do contrast math. If you’re only using them for readable-text-color selection, you can pull them out of your runtime entirely:</p>
<table>
    <thead>
        <tr>
            <th>Library</th>
            <th>Size</th>
      <th>What it did</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>chroma-js</td>
            <td>~14 kB</td>
      <td>Color parsing, luminance calc, readable color selection</td>
        </tr>
        <tr>
            <td>polished</td>
            <td>~11 kB</td>
      <td><code>readableColor()</code> for styled-components</td>
        </tr>
        <tr>
            <td>tinycolor2</td>
            <td>~5 kB</td>
      <td>Hex parsing, WCAG contrast ratio math</td>
        </tr>
    </tbody>
</table>

<p>You might still need these for generating complex color scales, but the contrast-for-readability use case is now covered natively.</p>
<p>Beyond bundle size, there’s a performance angle that’s easy to overlook. Those JavaScript libraries don’t just cost you network bytes — they run on the main thread. Every time a theme changes or a component mounts with a dynamic background, your JS has to parse the color, compute luminance, decide black or white, and write the result back to the DOM. That’s main-thread work competing with layout, event handlers, and everything else your app is doing. <code>contrast-color()</code> moves all of that into the browser’s native style computation phase — heavily optimized C++ that runs before paint. For apps with lots of themed components, that’s a real difference in responsiveness.</p>
<p>There’s also a subtle bug that goes away: <strong>hydration flash</strong>. In React or Vue SSR apps, the server renders HTML without JavaScript. The client then hydrates, running JS to calculate contrast and inject the correct text color. For a brief window between initial paint and hydration, the text is either invisible or the wrong color. Moving contrast into CSS eliminates that entirely — the browser resolves the correct color during the initial paint, before JavaScript loads.</p>
What We Used To Do
<p>For context on what this replaces:</p>
<p><strong>Sass era.</strong> You’d write a function that checked <code>lightness($bg) &gt; 50%</code> and returned black or white at compile time. Worked for static themes. Completely useless for user-picked colors, CMS palettes, or dark mode, because the output was baked into the CSS file and could never change at runtime.</p>
<p><strong>The variable toggle hack.</strong> When CSS custom properties shipped, people got creative. GitHub used a version of this for their issue label picker — splitting colors into <code>--r</code>, <code>--g</code>, <code>--b</code> channels, calculating Rec.709 luminance inside <code>calc()</code>, multiplying by negative infinity, and clamping to <code>0</code> or <code>1</code>. It worked. It was also unreadable, unmaintainable, and would break silently if you got one parenthesis wrong. (Kevin Hamer’s <a href="https://css-tricks.com/approximating-contrast-color-with-other-css-features/">OKLCH-based approximation</a> is the most elegant version of this lineage — cleaner math, better perceptual alignment — but it’s still a workaround for a function that now ships natively.)</p>
<p><code>contrast-color()</code> replaces all of these approaches with a single function call. And because the spec lets browsers upgrade the underlying algorithm, your code won’t need to change if and when a successor to WCAG 2.x contrast math lands — whether that’s APCA or something else entirely.</p>
<p></p><hr><br><br><p></p>
<p>That <a href="https://almanac.httparchive.org/en/2025/accessibility#color-contrast">70% failure rate</a> was never about developers refusing to care about contrast. It was about the distance between caring and shipping — the library, the build step, the runtime calculation, the hydration flash, the one component someone forgot to wire up. Every gap in that chain was a spot where accessibility quietly dropped out.</p>
<p><code>contrast-color()</code> doesn’t make developers care more. It makes caring cost nothing.</p>
				<p><strong>您可能还对下面的文章感兴趣：</strong></p>
				<p><ol><li><a href="https://blogread.cn/it/article.php?id=8533" target="_blank">Session Timeouts: The Overlooked Accessibility Barrier In Authentication Design</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=7442" target="_blank">关于可访问性的 7 个地方（For 每个人）</a> [2015-04-26 22:25:13]</li><li><a href="https://blogread.cn/it/article.php?id=4511" target="_blank">朋友网无障碍优化实践</a> [2011-10-18 23:33:14]</li></ol></p>]]></description>
		<content><![CDATA[Web对比度问题长期存在，依赖JavaScript库无法规模化解决，CSS需要原生方案。CSS Color Level 5引入的`contrast-color()`函数直接在样式计算阶段解决这一问题：输入背景颜色，自动返回黑色或白色中对比度更高的文本颜色，无需运行时脚本或构建步骤。该函数当前版本（Level 5）输出黑白二元颜色，算法由浏览器定义，目前普遍采用WCAG 2.x相对亮度公式，但这种“UA定义”设计允许未来替换为更优算法（如APCA感知对比度算法），尽管APCA的标准化仍不确定。Level 6计划扩展支持候选颜色列表和目标对比度比率，但尚未实现。

浏览器支持方面，]]></content>
	</item>
	<item>
		<title>Revealing Text With CSS letter-spacing</title>
		<link>https://blogread.cn/it/article.php?id=8594</link>
		<author>Preethi</author>
		<pubDate>2026-06-03 09:03:24</pubDate>
		<category domain="https://blogread.cn/it/category.php?id=7">前端</category>
		<guid>https://blogread.cn/it/article.php?id=8594</guid>
		<comments>https://blogread.cn/it/article.php?id=8594#comment</comments>
		<description><![CDATA[<p><strong>标签：</strong>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=CSS" target="_blank">CSS</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=letter-spacing" target="_blank">letter-spacing</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=pseudo-elements" target="_blank">pseudo-elements</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=typography" target="_blank">typography</a></p><p class="wp-block-paragraph">Some text effects are relatively hard to pull in CSS, the main reason being <a href="https://css-tricks.com/spiral-scrollytelling-in-css-with-sibling-index/">we</a> <a href="https://css-tricks.com/spiral-scrollytelling-in-css-with-sibling-index/">are unable to target individual characters</a> (something many of us want <a href="https://css-tricks.com/using-nonexistent-nth-letter-selector-now/">in the form of <code>::nth-letter()</code></a>, although we have basis for it with <a href="https://css-tricks.com/almanac/pseudo-selectors/f/first-letter/"><code>::first-letter</code></a> that gives us access to a box element’s first glyph.</p>



<p class="wp-block-paragraph">But maybe there are a few things we can use today with what we already have.</p>







<p class="wp-block-paragraph">For example, the CSS <a href="https://css-tricks.com/almanac/properties/l/letter-spacing/"><code>letter-spacing</code></a> property adjusts the space between all characters in a block of text. <strong>Positive values add space</strong> to the right side of each glyph (in a left-to-right writing mode), and <strong>negative values shrink the width of the glyph box</strong>, causing letters to overlap and even move the other way.</p>



<div class="wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper">CodePen Embed Fallback</div>



<p class="wp-block-paragraph">The <code>letter-spacing</code> accepts length units, and percentage (relative to font size). It is animateable, and as we saw before, the negative values can shrink it down or reverse it. Which is something we can make use of.</p>



<h3 class="wp-block-heading">Overlapping and separating letters</h3>



<p class="wp-block-paragraph">It’s quite easy to completely overlap the characters as a starting point and setting it’s <code>color</code> to <code>transparent</code> to visually hide it.</p>



<pre class="blogread-code language-css" data-lang="css"><code class="language-css">label {
  letter-spacing: -1ch;
  color: transparent;
  /* etc. */
}</code></pre>



<p class="wp-block-paragraph">From there, we can reveal the text by animating that <code>letter-spacing</code> value to a positive value and updating the <code>color</code> to a visible value, like when a checkbox is <code>:checked</code>:</p>



<pre class="blogread-code language-css" data-lang="css"><code class="language-css">li:nth-of-type(2) label {
  text-align: center;
}
li:nth-of-type(3) label {
  text-align: right;
}
input:checked + label {
  letter-spacing: 0ch;
  color: black;
  transition: letter-spacing 0.6s, color 0.4s;
}</code></pre>



<div class="wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper">CodePen Embed Fallback</div>



<p class="is-style-explanation wp-block-paragraph"><strong>Note:</strong> The CSS <code>ch</code> unit is a <a href="https://css-tricks.com/css-length-units/#relative-units">relative length</a> representing the width of the zero (0) glyph.</p>



<p class="wp-block-paragraph">The labels go from negative <code>letter-spacing</code> to normal spacing and the <code>color</code> updates to <code>black</code>. Both these changes happen over a <code>transition</code>.</p>



<p class="wp-block-paragraph">The second and third labels are given center and right text alignments and thus when negative letter spacing is applied they bundle up at the given alignment position, center and right, respectively. When <code>letter``-``spacing</code> goes from negative to zero (or any positive value) the letters separate from that same alignment position.</p>



<p class="wp-block-paragraph">Thus, we get a text reveal effect! Let’s look at some more.</p>



<h3 class="wp-block-heading">Showing and hiding text</h3>



<p class="wp-block-paragraph">Check this out. We can toggle a checkbox label as a fun interactive UI touch:</p>



<div class="wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper">CodePen Embed Fallback</div>



<pre class="blogread-code language-markup" data-lang="markup"><code class="language-markup">&lt;!-- Simplified for brevity; additional accessibility considerations --&gt;
&lt;input type="checkbox" id="cb"&gt;
&lt;label for="cb"&gt;
  &lt;span&gt;Join the global club&lt;/span&gt;
  &lt;span&gt;You've begun your journey!&lt;/span&gt;
&lt;/label&gt;</code></pre>



<pre class="blogread-code language-css" data-lang="css"><code class="language-css">label {
  overflow: clip;
  /* etc. */
}

span {
  /* The first label */
  &amp;:nth-of-type(1) {
    /* Default spacing: letters are fully visible */
    letter-spacing: 0ch;
    /* When the checkbox is checked, target this text */
    :checked + * &amp; {
      /* collapse letters on top of each other, hiding them */
      letter-spacing: -2ch;
      text-indent: -1.5ch;
      /* Use a "bouncy" cubic-bezier for spacing */
      transition: 0.4s letter-spacing cubic-bezier(.8, -.5, .2, 1.4), 
                  0.1s text-indent;
    }
  }
  
  /* The second label */
  &amp;:nth-of-type(2) { 
    /* Initially collapsed (letters overlap) */
    letter-spacing: -1ch;
    color: transparent;
    /* When the checkbox is checked, target this text */
    :checked + * &amp; {
      /* Returns to normal spacing */
      letter-spacing: 0ch;
      color: black;
      /* Slightly delay the appearance so it starts after the first text begins to hide */
      transition:
        0.4s letter-spacing cubic-bezier(.8, -.5, .2, 1.4) 0.3s, 
        0.8s color 0.4s;
    }
  }
}</code></pre>



<p class="wp-block-paragraph">When the box is checked, a negative <code>letter-spacing</code> value (<code>-2ch</code>) and <code>text-indent</code> value (<code>-1.5ch</code>) is used on the first <code>&lt;span&gt;</code> to slide it out of the container box. We use <code>overflow: clip</code> to completely hide the text.</p>



<p class="wp-block-paragraph">Concurrently, the text in the second <code>&lt;span&gt;</code> text goes from a <code>letter-spacing</code> value of <code>-1ch</code> to <code>0ch</code>, which reveals it. To hide this overlapped text at <code>-1ch</code>, a <code>transparent</code> color was given that’s turned to <code>black</code> when the checkbox is checked.</p>



<h3 class="wp-block-heading">Using with other glyph box styling</h3>



<p class="wp-block-paragraph">Here’s another fun one. We can start with an acronym that reveal the full text on hover. Again, we have existing features to help us pull this off, including <code>::first-letter</code> and <a href="https://css-tricks.com/almanac/pseudo-selectors/f/first-line/"><code>::first-line</code></a>.</p>



<p class="wp-block-paragraph">We’ll start with this markup:</p>



<pre class="blogread-code language-markup" data-lang="markup"><code class="language-markup">&lt;!-- Simplified for brevity --&gt;
&lt;p id="acronym"&gt;
  &lt;span class="words"&gt;United&lt;/span&gt;
  &lt;span class="words"&gt;Nations&lt;/span&gt;
  &lt;span class="words"&gt;International&lt;/span&gt;
  &lt;span class="words"&gt;Children's&lt;/span&gt;
  &lt;span class="words"&gt;Emergency&lt;/span&gt;
  &lt;span class="words"&gt;Fund&lt;/span&gt;
&lt;/p&gt;</code></pre>



<pre class="blogread-code language-css" data-lang="css"><code class="language-css">.words {
  letter-spacing: -1ch;
  color: transparent;
  /* etc. */

  &amp;::first-letter {
    color: black;
  }

  figure:hover + #acronym &amp; {
    letter-spacing: 0ch;
    color: black;
    transition: letter-spacing 0.4s cubic-bezier(.8, -.5, .2, 1.4) /* etc. */;
  }
}</code></pre>



<p class="wp-block-paragraph">Each word in the UNICEF acronym initially has <code>letter-spacing: -1ch</code> to shrink the text, and <code>color: transparent</code> to keep the shrunk text hidden, except the <code>::first-letter</code> that has <code>color: black</code> so it remains visible even though the rest of the text is stacked beneath it.</p>



<p class="wp-block-paragraph">Now, we can target the image on <code>:hover</code> and select the entire text so that the <code>letter-spacing</code> value for each word decreases to <code>0ch</code> and <code>color: black</code> is applied, showing what’s remaining of the words:</p>



<div class="wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper">CodePen Embed Fallback</div>



<h3 class="wp-block-heading">What else can we do?</h3>



<p class="wp-block-paragraph">I don’t know! But that’s where you come in. Obviously, a hypothetical <code>::nth-letter</code> selector would be amazing for all kinds of text effects. But it’s neat that we can create some semblance of it today with existing features, like <code>letter-spacing</code>, <code>::first-letter</code>, and <code>::first-line</code>.</p>



<p class="wp-block-paragraph">What can you cook up knowing we have these constraints?</p>
<hr>
<p><small><a rel="nofollow" href="https://css-tricks.com/revealing-text-with-css-letter-spacing/">Revealing Text With CSS letter-spacing</a> originally handwritten and published with love on <a rel="nofollow" href="https://css-tricks.com/">CSS-Tricks</a>. You should really <a href="https://css-tricks.com/newsletters/">get the newsletter</a> as well.</small></p>
				<p><strong>您可能还对下面的文章感兴趣：</strong></p>
				<p><ol><li><a href="https://blogread.cn/it/article.php?id=8380" target="_blank">CSS 中的标点悬挂及其现状</a> [2026-05-17 14:50:00]</li><li><a href="https://blogread.cn/it/article.php?id=7635" target="_blank">简历的重点是抓人</a> [2016-02-06 23:44:07]</li><li><a href="https://blogread.cn/it/article.php?id=7511" target="_blank">给自己的字体课（一）——英文字体基础</a> [2015-07-21 23:30:56]</li><li><a href="https://blogread.cn/it/article.php?id=7281" target="_blank">文字编排的易读性</a> [2015-01-19 23:48:22]</li><li><a href="https://blogread.cn/it/article.php?id=6735" target="_blank">字体的性格</a> [2013-10-15 13:39:00]</li><li><a href="https://blogread.cn/it/article.php?id=6563" target="_blank">万般设计为阅读【译文】</a> [2013-07-30 13:46:42]</li><li><a href="https://blogread.cn/it/article.php?id=5939" target="_blank">浅析中英文基本字形的演变和发展</a> [2012-10-22 23:36:15]</li><li><a href="https://blogread.cn/it/article.php?id=5616" target="_blank">为什么要段首空两格</a> [2012-08-02 12:25:25]</li><li><a href="https://blogread.cn/it/article.php?id=5394" target="_blank">电影海报中的字体设计赏析</a> [2012-05-28 12:32:36]</li><li><a href="https://blogread.cn/it/article.php?id=4215" target="_blank">字体图形化设计小谈</a> [2011-08-22 12:20:03]</li><li><a href="https://blogread.cn/it/article.php?id=3936" target="_blank">执行力强心剂之一：字体特效篇</a> [2011-06-30 13:53:51]</li><li><a href="https://blogread.cn/it/article.php?id=3894" target="_blank">CSS排版: 基础</a> [2011-06-23 13:33:44]</li><li><a href="https://blogread.cn/it/article.php?id=3876" target="_blank">CSS排版：例子和工具</a> [2011-06-23 00:10:40]</li><li><a href="https://blogread.cn/it/article.php?id=3560" target="_blank">移动终端中的视觉引导</a> [2011-04-29 13:39:33]</li><li><a href="https://blogread.cn/it/article.php?id=2466" target="_blank">字体图形化设计</a> [2010-10-07 22:19:58]</li><li><a href="https://blogread.cn/it/article.php?id=2079" target="_blank">Banner中的字体结构分析</a> [2010-07-25 22:26:12]</li><li><a href="https://blogread.cn/it/article.php?id=1991" target="_blank">Google font api、web font与中文</a> [2010-07-19 22:47:35]</li><li><a href="https://blogread.cn/it/article.php?id=1832" target="_blank">汉字的几何中心</a> [2010-06-22 13:19:03]</li><li><a href="https://blogread.cn/it/article.php?id=1465" target="_blank">中文段首不需要空两格</a> [2010-04-28 15:36:05]</li><li><a href="https://blogread.cn/it/article.php?id=1174" target="_blank">为什么要段首空两格</a> [2010-03-09 13:15:16]</li></ol></p>]]></description>
		<content><![CDATA[CSS 的 letter-spacing 属性通常用于调整字符间距，但它在文本动态显示效果中展现了巧妙的创意应用。由于 CSS 目前缺乏像 ::nth-letter 这样的选择器来单独操作字符，开发者可以利用 letter-spacing 的正值和负值特性，结合颜色透明化与过渡动画，实现文字的揭示、隐藏与切换效果。

通过设置负 letter-spacing 值（如 -1ch），可使字符重叠并隐藏，配合 color: transparent 可完全隐藏文本；再将其动画过渡到正值（如 0ch），字符便逐渐分离并恢复可见颜色，形成从聚集到展开的视觉动画。这种方法适用于复选框切换文本、悬停展开缩写词等交互场景。文章进一步展示了如何结合 overflow: clip、text-indent 以及 ::first-letter 伪元素，实现更复杂的文本动态切换与布局控制，为纯 CSS 的文字动效提供了低成本且灵活的实现思路。]]></content>
	</item>
	<item>
		<title>AI Agent Orchestrator Landscape Report</title>
		<link>https://blogread.cn/it/article.php?id=8593</link>
		<author>kamus</author>
		<pubDate>2026-06-03 09:03:24</pubDate>
		<category domain="https://blogread.cn/it/category.php?id=4">AI</category>
		<guid>https://blogread.cn/it/article.php?id=8593</guid>
		<comments>https://blogread.cn/it/article.php?id=8593#comment</comments>
		<description><![CDATA[<p><strong>标签：</strong>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=Agent" target="_blank">Agent</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=AI" target="_blank">AI</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=Orchestrator" target="_blank">Orchestrator</a></p><blockquote><p>
调研日期: 2026-05-23<br>
调研范围: 9 个项目<br>
调研工具: GitHub API + Brave Search + Exa Web Fetch
</p></blockquote>
<hr>
<h2>1. 赛道概述</h2>
<p>AI Agent Orchestrator 是一类新兴基础设施，核心使命是：<strong>把多个 AI coding agent（Claude Code、Codex、Gemini CLI 等）编排成一支”虚拟团队”</strong>，实现任务分配、进度跟踪、成本控制、技能复用等管理能力。</p>
<p><strong>为什么火：</strong><br>
– 2025 下半年 Claude Code / Codex CLI 爆发，开发者开始同时开 10-20 个 agent 终端<br>
– 手动管理不可持续 → 需要”agent 项目经理”<br>
– “Zero-human company” 叙事驱动资本和社区关注<br>
– Stars 增速极快：头部项目 3 个月内从 0 到 50k+</p>
<p><strong>赛道分层：</strong><br>
– <strong>L1 编排层</strong>：管理 agent 的启动、停止、工作区隔离（1code, Agent of Empires）<br>
– <strong>L2 协作层</strong>：任务分配、进度跟踪、团队协作（Multica, MyClaude）<br>
– <strong>L3 公司层</strong>：组织架构、预算治理、目标对齐（Paperclip, LobeHub, Ruflo）</p>
<hr>
<h2>2. 项目总览</h2>
<table>
<thead>
<tr>
<th>#</th>
<th>项目</th>
<th>Stars</th>
<th>语言</th>
<th>License</th>
<th>创建时间</th>
<th>最近更新</th>
<th>最新版本</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>LobeHub</td>
<td>77,566</td>
<td>TS</td>
<td>LobeHub Community License</td>
<td>2023-05</td>
<td>2026-05-23</td>
<td>v2.2.1-canary.33</td>
</tr>
<tr>
<td>2</td>
<td>Paperclip</td>
<td>67,185</td>
<td>TS</td>
<td>MIT</td>
<td>2025-03</td>
<td>2026-05-22</td>
<td>v2026.517.0</td>
</tr>
<tr>
<td>3</td>
<td>Ruflo</td>
<td>54,246</td>
<td>TS</td>
<td>MIT</td>
<td>2025-06</td>
<td>2026-05-22</td>
<td>v3.7.0-alpha.76</td>
</tr>
<tr>
<td>4</td>
<td>Multica</td>
<td>31,543</td>
<td>TS+Go</td>
<td>Modified Apache 2.0</td>
<td>2026-01</td>
<td>2026-05-22</td>
<td>v0.3.6</td>
</tr>
<tr>
<td>5</td>
<td>1code</td>
<td>5,540</td>
<td>TS</td>
<td>Apache 2.0</td>
<td>2026-01</td>
<td>2026-02-24</td>
<td>v0.0.84</td>
</tr>
<tr>
<td>6</td>
<td>Golutra</td>
<td>3,549</td>
<td>Rust</td>
<td>BSL 1.1</td>
<td>2026-02</td>
<td>2026-05-12</td>
<td>v0.2.6</td>
</tr>
<tr>
<td>7</td>
<td>MyClaude</td>
<td>2,669</td>
<td>Go</td>
<td>AGPL v3</td>
<td>2025-07</td>
<td>2026-05-04</td>
<td>v6.8.2</td>
</tr>
<tr>
<td>8</td>
<td>Agent of Empires</td>
<td>2,365</td>
<td>Rust</td>
<td>MIT</td>
<td>2026-01</td>
<td>2026-05-22</td>
<td>v1.8.1</td>
</tr>
<tr>
<td>9</td>
<td>Agor</td>
<td>1,214</td>
<td>TS</td>
<td>BSL 1.1</td>
<td>2025-10</td>
<td>2026-05-22</td>
<td>v0.15.0</td>
</tr>
</tbody>
</table>
<hr>
<h2>3. 逐项深度分析</h2>
<h3>3.1 LobeHub</h3>
<p><strong>一句话定位：</strong> Chief Agent Operator — 你的 AI 团队的”首席运营官”</p>
<p><strong>核心功能：</strong><br>
– Agent Builder：自然语言描述即可创建 agent，自动配置<br>
– Agent Groups：多 agent 并行协作，像真实团队一样工作<br>
– 10,000+ Skills / MCP 插件生态<br>
– Personal Memory：agent 从你的工作习惯中学习<br>
– Schedule：定时任务，agent 自动执行<br>
– IM Gateway：在你已有的聊天工具中使用 agent</p>
<p><strong>技术架构：</strong><br>
– TypeScript (98.9%)，Next.js 全栈<br>
– 部署：Vercel / Docker / 阿里云 / Zeabur / Sealos<br>
– 生态成熟：lobe-ui, lobe-icons, lobe-tts 等配套库</p>
<p><strong>License 详细分析：</strong><br>
– LobeHub Community License（基于 Apache 2.0）<br>
– ✅ 可以商用（不改源码作为前端后端服务）<br>
– ❌ <strong>不能基于 LobeChat 开发和分发衍生作品</strong>（除非购买商业授权）<br>
– ⚠️ 贡献者协议：贡献者同意 producer 可调整协议严格程度<br>
– <strong>结论：做闭源 fork 不可行，做集成/嵌入需联系 hello@lobehub.com</strong></p>
<p><strong>社区活跃度：</strong><br>
– 330 contributors，2740 releases，每日更新<br>
– Discord 社区活跃，Product Hunt 上线<br>
– 主维护者：@arvinxx, @canisminor1990</p>
<p><strong>独特卖点：</strong><br>
– 最成熟的生态（从 2023 年就开始，不是跟风项目）<br>
– UI/UX 最佳，产品化程度最高<br>
– 从 ChatBot 演进到 Agent Operator，有清晰的产品路线</p>
<p><strong>已知风险：</strong><br>
– License 不完全开源，有随时收紧的风险<br>
– 功能膨胀（从 chatbot 到 agent platform 到协作平台），定位不够聚焦<br>
– Canary 分支为主开发分支，稳定性存疑</p>
<hr>
<h3>3.2 Paperclip</h3>
<p><strong>一句话定位：</strong> “Zero-human company” 编排平台 — 如果 OpenClaw 是员工，Paperclip 就是公司</p>
<p><strong>核心功能：</strong><br>
– Org Chart + 角色体系：CEO/CTO/工程师/设计师，agent 有汇报线<br>
– Goal Alignment：每个任务追溯到公司使命<br>
– Budget &amp; Cost Control：月度预算，超支自动暂停 agent<br>
– Heartbeat 调度：agent 定时唤醒、检查工作、自动行动<br>
– Governance &amp; Approvals：审批流程，config 变更可回滚<br>
– Multi-Company：一个部署运行多个公司，数据完全隔离<br>
– 移动端管理</p>
<p><strong>技术架构：</strong><br>
– TypeScript (97.6%)，Node.js + React<br>
– 嵌入式 PostgreSQL（开箱即用）<br>
– 外部适配器：Claude Code, Codex, Cursor, Bash, HTTP/Webhook</p>
<p><strong>License 详细分析：</strong><br>
– <strong>MIT License</strong> ✅<br>
– 随便用、改、卖、闭源 fork，只需保留版权声明<br>
– <strong>做商业闭源产品的最佳选择</strong></p>
<p><strong>社区活跃度：</strong><br>
– 87 contributors，8 releases<br>
– 每日更新，commit 非常活跃<br>
– 30k stars 在 3 周内达成（增长极快）</p>
<p><strong>独特卖点：</strong><br>
– 唯一真正做”公司治理”层的开源项目（预算、审批、审计）<br>
– MIT 协议，商用无障碍<br>
– “Clipmart”（即将推出）：一键下载整个公司模板</p>
<p><strong>已知风险：</strong><br>
– 项目非常新（2025-03 创建），成熟度待验证<br>
– 社区相对小（87 contributors vs LobeHub 的 330）<br>
– 嵌入式 Postgres 是开发便利但生产环境需自建</p>
<hr>
<h3>3.3 Ruflo</h3>
<p><strong>一句话定位：</strong> Claude 优先的 Swarm 智能编排平台</p>
<p><strong>核心功能：</strong><br>
– 多 agent swarm 协调<br>
– MCP 工具集成（300+ 声称）<br>
– 持久化记忆 + 向量存储<br>
– 背景 worker + 共识模式<br>
– 多 provider 路由（Claude, GPT, Gemini, Qwen）</p>
<p><strong>技术架构：</strong><br>
– TypeScript<br>
– 声称支持 WASM agent、安全层、插件市场</p>
<p><strong>License 详细分析：</strong><br>
– <strong>MIT License</strong> ✅<br>
– 协议本身无限制</p>
<p><strong>社区活跃度：</strong><br>
– 54k stars，但 <strong>社区争议极大</strong><br>
– Reddit 多个帖子质疑代码质量：”99% Fake / 1% Real”<br>
– GitHub Discussion #1666：”I didn’t notice any significant improvements”<br>
– 有评论认为 agent 实现质量差、大部分功能是表面文章</p>
<p><strong>独特卖点：</strong><br>
– Stars 数增长最快（但有刷星嫌疑）<br>
– 概念最前沿（swarm intelligence, WASM agents）</p>
<p><strong>已知风险：</strong><br>
– ⚠️ <strong>社区信任度低</strong>：多人发帖质疑实际效果与宣传不符<br>
– Alpha 版本（v3.7.0-alpha.76），稳定性未知<br>
– 功能声称过多过杂，有”feature factory”嫌疑<br>
– <strong>不建议作为商业产品基础</strong></p>
<hr>
<h3>3.4 Multica</h3>
<p><strong>一句话定位：</strong> 给 coding agent 做”项目管理”的开源平台</p>
<p><strong>核心功能：</strong><br>
– Agents as Teammates：agent 有 profile，出现在看板上，发评论，报告 blocker<br>
– Squads：agent 和人编组，leader 自动分配任务<br>
– Reusable Skills：每次解决方案变成团队可复用技能<br>
– Multi-Workspace：按团队隔离<br>
– 统一 Runtime 管理（本地 + 云端）</p>
<p><strong>技术架构：</strong><br>
– 前端 Next.js 16，后端 Go (Chi + WebSocket)<br>
– PostgreSQL 17 + pgvector<br>
– 本地 daemon 执行 agent CLI<br>
– 支持 11 种 agent CLI（Claude Code, Codex, Copilot, OpenClaw, OpenCode, Hermes, Gemini, Pi, Cursor, Kimi, Kiro）</p>
<p><strong>License 详细分析：</strong><br>
– Modified Apache 2.0<br>
– ✅ 组织内部使用免费<br>
– ❌ <strong>不能拿源码提供 SaaS / 托管服务 / 嵌入商业产品</strong>（除非买商业授权）<br>
– ❌ 不能移除前端 Logo 和版权信息<br>
– <strong>结论：做内部平台可行，做 SaaS 产品需商业授权</strong></p>
<p><strong>社区活跃度：</strong><br>
– 130 contributors，75 releases<br>
– 10k stars 时登上 GitHub Trending #5<br>
– v0.3.x 阶段，快速迭代</p>
<p><strong>独特卖点：</strong><br>
– 架构最扎实（Go 后端 + WS 实时通信 + pgvector）<br>
– “Agents as Teammates” 理念最彻底<br>
– 支持的 agent CLI 最多（11 种）</p>
<p><strong>已知风险：</strong><br>
– SaaS 限制意味着不能直接拿来做商业产品<br>
– v0.3.x 早期版本，API 可能不稳定<br>
– 需要 Docker + PostgreSQL 部署，运维成本高于纯 Node.js 方案</p>
<hr>
<h3>3.5 1code</h3>
<p><strong>一句话定位：</strong> 轻量级 coding agent 编排层</p>
<p><strong>核心功能：</strong><br>
– 为 Claude Code / Codex 提供编排抽象层<br>
– 轻量设计</p>
<p><strong>技术架构：</strong><br>
– TypeScript</p>
<p><strong>License 详细分析：</strong><br>
– <strong>Apache 2.0</strong> ✅（未修改）<br>
– 商用完全无障碍</p>
<p><strong>社区活跃度：</strong><br>
– 5.5k stars，但 <strong>最近更新停在 2026-02-24</strong>（3 个月没更新）<br>
– v0.0.84，非常早期</p>
<p><strong>独特卖点：</strong><br>
– 最轻量的选择<br>
– Apache 2.0，license 最干净</p>
<p><strong>已知风险：</strong><br>
– ⚠️ <strong>疑似已停更</strong>（3 个月无 commit）<br>
– 功能最少，文档最少<br>
– 不推荐作为长期依赖</p>
<hr>
<h3>3.6 Golutra</h3>
<p><strong>一句话定位：</strong> Rust 实现的多 agent 编排平台</p>
<p><strong>核心功能：</strong><br>
– 多 agent 并行执行<br>
– 任务编排 + 长期运行工作流<br>
– 桌面应用</p>
<p><strong>技术架构：</strong><br>
– <strong>Rust</strong>，性能好，二进制分发</p>
<p><strong>License 详细分析：</strong><br>
– <strong>BSL 1.1 (Business Source License)</strong> ❌<br>
– <strong>非生产用途可免费使用</strong><br>
– Change Date: 2030-02-25（届时变为 GPL 2.0）<br>
– Change License: GPL-2.0-or-later<br>
– <strong>结论：做商业产品完全不可行（2030 年前）</strong></p>
<p><strong>社区活跃度：</strong><br>
– 3.5k stars，51 open issues<br>
– 2026-05-12 最近更新，仍在活跃</p>
<p><strong>独特卖点：</strong><br>
– 唯一 Rust 实现，性能优势<br>
– 桌面应用形态</p>
<p><strong>已知风险：</strong><br>
– BSL 协议限制商业使用<br>
– Rust 生态意味着社区贡献门槛高<br>
– GPL change license 意味着 2030 年后也需要开源</p>
<hr>
<h3>3.7 MyClaude</h3>
<p><strong>一句话定位：</strong> Go 实现的多 agent 工作流编排</p>
<p><strong>核心功能：</strong><br>
– 支持 Claude Code, Codex, Gemini, OpenCode<br>
– Go 编译即用</p>
<p><strong>技术架构：</strong><br>
– <strong>Go</strong>，单二进制分发</p>
<p><strong>License 详细分析：</strong><br>
– <strong>AGPL v3</strong> ❌<br>
– 衍生作品必须开源<br>
– 提供网络服务也必须开源<br>
– <strong>结论：做商业闭源产品完全不可行</strong></p>
<p><strong>社区活跃度：</strong><br>
– 2.7k stars，7 open issues<br>
– 2026-05-04 最近更新</p>
<p><strong>独特卖点：</strong><br>
– Go 实现，部署简单<br>
– 轻量</p>
<p><strong>已知风险：</strong><br>
– AGPL 是最严格的开源协议之一<br>
– 社区小，bus factor 低</p>
<hr>
<h3>3.8 Agent of Empires</h3>
<p><strong>一句话定位：</strong> TUI + Web 双端 agent 管理器</p>
<p><strong>核心功能：</strong><br>
– 支持 Claude Code, Codex, Gemini CLI, OpenCode, Cursor, Copilot CLI, Factory Droid<br>
– TUI 终端界面 + Web 界面（支持手机管理）<br>
– 使用 tmux + git worktrees 隔离</p>
<p><strong>技术架构：</strong><br>
– <strong>Rust</strong><br>
– tmux session 管理<br>
– git worktree 隔离</p>
<p><strong>License 详细分析：</strong><br>
– <strong>MIT License</strong> ✅<br>
– 商用无障碍</p>
<p><strong>社区活跃度：</strong><br>
– 2.4k stars，79 open issues<br>
– 2026-05-22 最近更新，活跃开发</p>
<p><strong>独特卖点：</strong><br>
– 手机管理 agent（Web UI）<br>
– 支持的 agent CLI 种类最多之一<br>
– MIT 协议</p>
<p><strong>已知风险：</strong><br>
– 社区较小<br>
– 依赖 tmux，非跨平台（主要 macOS/Linux）<br>
– Rust 代码贡献门槛</p>
<hr>
<h3>3.9 Agor</h3>
<p><strong>一句话定位：</strong> 多人协作画布上的 agent 编排</p>
<p><strong>核心功能：</strong><br>
– 可视化画布管理 Claude Code, Codex, Gemini session<br>
– Git worktree 管理<br>
– AI 对话追踪<br>
– 实时团队可视化</p>
<p><strong>技术架构：</strong><br>
– TypeScript</p>
<p><strong>License 详细分析：</strong><br>
– <strong>BSL 1.1 (Business Source License)</strong> ❌<br>
– 非生产用途免费<br>
– Change Date: 2029-01-15（届时变为 Apache 2.0）<br>
– <strong>结论：做商业产品不可行（2029 年前）</strong></p>
<p><strong>社区活跃度：</strong><br>
– 1.2k stars，102 open issues<br>
– 2026-05-22 最近更新</p>
<p><strong>独特卖点：</strong><br>
– 唯一做”可视化画布”的方案<br>
– 由 Preset.io（Apache Superset 创始人）开发</p>
<p><strong>已知风险：</strong><br>
– BSL 协议限制商业使用<br>
– Stars 最少，生态最小</p>
<hr>
<h2>4. License 商用友好度排名</h2>
<blockquote><p>
场景：你想 fork 一个项目，包装成自己的商业闭源产品
</p></blockquote>
<table>
<thead>
<tr>
<th>排名</th>
<th>项目</th>
<th>License</th>
<th>可否闭源商用</th>
<th>具体限制</th>
</tr>
</thead>
<tbody>
<tr>
<td> 1</td>
<td><strong>Paperclip</strong></td>
<td>MIT</td>
<td>✅ 完全可以</td>
<td>仅需保留版权声明</td>
</tr>
<tr>
<td> 1</td>
<td><strong>Ruflo</strong></td>
<td>MIT</td>
<td>✅ 完全可以</td>
<td>仅需保留版权声明（但代码质量存疑）</td>
</tr>
<tr>
<td> 1</td>
<td><strong>Agent of Empires</strong></td>
<td>MIT</td>
<td>✅ 完全可以</td>
<td>仅需保留版权声明</td>
</tr>
<tr>
<td> 4</td>
<td><strong>1code</strong></td>
<td>Apache 2.0</td>
<td>✅ 可以</td>
<td>保留 NOTICE 文件（但已停更）</td>
</tr>
<tr>
<td> 5</td>
<td><strong>Multica</strong></td>
<td>Modified Apache 2.0</td>
<td>⚠️ 有限制</td>
<td>不能做 SaaS/托管服务，需买商业授权</td>
</tr>
<tr>
<td>6</td>
<td><strong>LobeHub</strong></td>
<td>Community License</td>
<td>⚠️ 有限制</td>
<td>不能做衍生作品分发，需买商业授权</td>
</tr>
<tr>
<td>7</td>
<td><strong>Golutra</strong></td>
<td>BSL 1.1</td>
<td>❌ 不可以</td>
<td>非生产用途免费，2030 年前不可商用</td>
</tr>
<tr>
<td>8</td>
<td><strong>Agor</strong></td>
<td>BSL 1.1</td>
<td>❌ 不可以</td>
<td>非生产用途免费，2029 年前不可商用</td>
</tr>
<tr>
<td>9</td>
<td><strong>MyClaude</strong></td>
<td>AGPL v3</td>
<td>❌ 不可以</td>
<td>衍生作品必须开源</td>
</tr>
</tbody>
</table>
<p><strong>结论：做商业闭源产品，Paperclip 是唯一兼具 MIT + 高质量代码 + 活跃社区的选择。</strong></p>
<hr>
<h2>5. 技术选型建议</h2>
<h3>场景 A：快速原型 / 个人项目</h3>
<p><strong>推荐：Agent of Empires 或 MyClaude</strong><br>
– 理由：轻量、快速上手、单二进制<br>
– 备选：1code（如果它恢复维护）</p>
<h3>场景 B：商业 SaaS 产品</h3>
<p><strong>推荐：Paperclip</strong><br>
– 理由：MIT 协议无障碍、功能最全面（治理/预算/审计）、增长快<br>
– 需自行解决：生产级数据库、部署运维</p>
<h3>场景 C：企业内部平台</h3>
<p><strong>推荐：Multica</strong><br>
– 理由：架构最扎实（Go 后端 + WS + pgvector）、支持 agent CLI 最多、内部使用不受 license 限制<br>
– 备选：LobeHub（如果需要成熟的 UI 和插件生态）</p>
<h3>场景 D：贡献者 / 社区参与</h3>
<p><strong>推荐：Paperclip 或 Multica</strong><br>
– 理由：活跃开发、贡献指南完善、社区友好<br>
– 避免：Ruflo（社区信任问题）、1code（已停更）</p>
<hr>
<h2>6. 赛道趋势与风险</h2>
<h3>6.1 增长轨迹</h3>
<table>
<thead>
<tr>
<th>项目</th>
<th>创建到 50k stars 用时</th>
<th>月均增长</th>
</tr>
</thead>
<tbody>
<tr>
<td>Paperclip</td>
<td>~3 个月</td>
<td>~22k/月</td>
</tr>
<tr>
<td>Ruflo</td>
<td>~6 个月</td>
<td>~9k/月</td>
</tr>
<tr>
<td>LobeHub</td>
<td>~30 个月</td>
<td>~2.5k/月</td>
</tr>
</tbody>
</table>
<p>Paperclip 和 Ruflo 的增长速度异常快，存在以下可能：<br>
– 真实需求爆发（agent 编排确实是刚需）<br>
– 社区营销 / HackerNews 效应<br>
– 部分 star 可能来自 bot（Ruflo 被社区质疑）</p>
<h3>6.2 整合风险</h3>
<p><strong>大厂可能吸收这个赛道：</strong><br>
– Anthropic 可能在 Claude Code 中内置编排功能<br>
– OpenAI 可能在 Codex 平台中加入团队管理<br>
– GitHub Copilot 已经在做 agent 协作（Copilot Workspace）<br>
– 这些项目可能在 1-2 年内被平台化功能替代</p>
<p><strong>但也有可能：</strong><br>
– 开源方案因为 vendor-neutral 而持续存在（类似 Kubernetes vs 各家容器服务）</p>
<h3>6.3 技术债信号</h3>
<ul>
<li><strong>Ruflo</strong>：功能声称过多，社区质疑实现质量，有 “feature factory” 风险</li>
<li><strong>1code</strong>：3 个月无更新，可能已被放弃</li>
<li><strong>LobeHub</strong>：从 chatbot 演进到 agent platform，代码包袱重</li>
<li><strong>Golutra/Agor</strong>：BSL 协议意味着社区贡献动力不足</li>
</ul>
<h3>6.4 社区碎片化</h3>
<p>这个赛道目前极度碎片化 — 9 个项目、5 种语言、4 种 license 类型。预计 2026 下半年会出现整合：<br>
– 停更的项目会被淘汰（1code 等）<br>
– 头部 2-3 个项目会形成生态壁垒<br>
– License 友好的项目更容易获得社区贡献</p>
<hr>
<h2>7. 附录</h2>
<h3>7.1 License 全文摘要</h3>
<p><strong>MIT (Paperclip, Ruflo, Agent of Empires):</strong></p>
<blockquote><p>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software… to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software.
</p></blockquote>
<p><strong>LobeHub Community License:</strong></p>
<blockquote><p>
LobeChat may be utilized commercially, including as a frontend and backend service without modifying the source code. A commercial license must be obtained from the producer if you want to develop and distribute a derivative work based on LobeChat.
</p></blockquote>
<p><strong>Modified Apache 2.0 (Multica):</strong></p>
<blockquote><p>
Unless explicitly authorized by Multica in writing, you may not use the Multica source code to provide a hosted service to third parties, or embed Multica as a component of a product or service that is sold, licensed, or otherwise commercially distributed to third parties.
</p></blockquote>
<p><strong>BSL 1.1 (Golutra, Agor):</strong></p>
<blockquote><p>
The Licensor hereby grants you the right to copy, modify, create derivative works, redistribute, and make non-production use of the Licensed Work.
</p></blockquote>
<p><strong>AGPL v3 (MyClaude):</strong></p>
<blockquote><p>
You must cause any work that you distribute or publish… to be licensed as a whole at no charge to all third parties under the terms of this License.
</p></blockquote>
<h3>7.2 外部讨论链接</h3>
<ul>
<li>Reddit: “Do not install Ruflo into your Claude Code workflow” — r/ClaudeAI</li>
<li>Reddit: “What orchestration platform to use?” — r/ClaudeCode（有人推荐 Ruflo 但也有质疑）</li>
<li>GitHub Discussion #1666: “Is Ruflo actually that powerful?” — 社区反馈偏负面</li>
<li>Augment Code: “9 Open-Source Agent Orchestrators for AI Coding (2026)”</li>
<li>CodePick: “2026 Agent Collaboration Platform Guide” — LobeHub 被评为最大平台</li>
<li>AgentConn: Multica review — “hit #5 on GitHub Trending”</li>
<li>Toolchew: “Running a 16-Agent Team on a €4.49/mo Server” — Multica 实测</li>
</ul>
<h3>7.3 关键数据快照</h3>
<div class="codehilite">
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">Stars 分布:  LobeHub(77k) &gt; Paperclip(67k) &gt; Ruflo(54k) &gt; Multica(31k) &gt; ... &gt; Agor(1.2k)
License:     MIT(3) &gt; Apache(1) &gt; Modified(2) &gt; BSL(2) &gt; AGPL(1)
语言:        TypeScript(6) &gt; Rust(2) &gt; Go(1)
活跃度:      全部每日更新（除 1code 停更 3 个月）</code></pre>
</div>
<hr>
<p><em>报告由 Hermes Agent 自动生成。数据基于 GitHub API 实时查询 + Brave/Exa Web 搜索。</em></p>
				<p><strong>您可能还对下面的文章感兴趣：</strong></p>
				<p><ol><li><a href="https://blogread.cn/it/article.php?id=8585" target="_blank">「置顶」我做了什么</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8584" target="_blank">SmartPerfetto 两周更新：从 Perfetto AI Assistant 到可复用的 Trace 分析平台</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8575" target="_blank">Lyra - AI Prompt Optimization Specialist</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8573" target="_blank">BEWARE SOFTWARE BRAIN</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8554" target="_blank">Rethinking “Pixel Perfect” Web Design</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8532" target="_blank">The UX Designer’s Nightmare: When “Production-Ready” Becomes A Design Deliverable</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8518" target="_blank">写给设计师：如何设计一份 AI 友好的设计规范</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8510" target="_blank">开启我的「人生 AI」计划</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8506" target="_blank">十倍性能优化！一次终端语法高亮库的 AI 折腾与收获</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8495" target="_blank">SmartPerfetto 开源：面向 Android Trace 分析的 Perfetto AI Assistant</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8493" target="_blank">全程用 Claude Code 搓了一个 macOS 原生应用：SkillDeck</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8485" target="_blank">中文 Markdown 强调标记的渲染问题</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8479" target="_blank">AI 时代下的技术博客、文档驱动开发与头脑风暴实践</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8446" target="_blank">Vibe Coding 的安全风险与应对策略</a> [2026-06-03 09:03:23]</li><li><a href="https://blogread.cn/it/article.php?id=8430" target="_blank">Android Weekly 2025-15 期</a> [2026-06-03 09:03:23]</li><li><a href="https://blogread.cn/it/article.php?id=8429" target="_blank">Android Weekly 2025-16 期</a> [2026-06-03 09:03:23]</li><li><a href="https://blogread.cn/it/article.php?id=7905" target="_blank">浅谈 WHR 全历史排名</a> [2016-03-16 23:36:14]</li><li><a href="https://blogread.cn/it/article.php?id=4763" target="_blank">祢衡这个人</a> [2012-01-08 22:14:24]</li><li><a href="https://blogread.cn/it/article.php?id=930" target="_blank">智能输入法软件的社会责任问题</a> [2010-01-05 13:57:29]</li></ol></p>]]></description>
		<content><![CDATA[AI Agent Orchestrator 赛道源于开发者需管理大量并行 AI 编码代理（如 Claude Code、Codex）的需求，旨在提供任务分配、成本控制等协作能力。报告将项目分为三层：L1编排层管理代理生命周期，L2协作层实现任务跟踪，L3公司层处理组织预算与对齐。

当前市场呈现九个项目竞争格局，技术栈以 TypeScript 为主。其中，LobeHub 生态最成熟但使用社区许可证，限制商业衍生；Paperclip 采用 MIT 协议，功能聚焦公司治理与预算，是构建商业产品的首选；Ruflo 虽增长迅速但遭社区质疑代码质量；Multica 架构扎实（Go 后端），支持最多代理类型但限制 SaaS 分发。

技术选型上，快速原型可考虑轻量级的 Agent of Empires；商业 SaaS 推荐 Paperclip；企业内部平台适合 Multica。报告同时指出，该领域面临大厂整合风险与技术债务问题（如部分项目停更或协议限制），且市场高度碎片化，预计将经历整合。核心建议是根据使用场景（商业、内部、原型）和许可证条款进行审慎选择。]]></content>
	</item>
	<item>
		<title>How to Set Up Homebrew Tap for Private CLI Tools: A Complete Guide</title>
		<link>https://blogread.cn/it/article.php?id=8592</link>
		<author>kamus</author>
		<pubDate>2026-06-03 09:03:24</pubDate>
		<category domain="https://blogread.cn/it/category.php?id=18">DevOps</category>
		<guid>https://blogread.cn/it/article.php?id=8592</guid>
		<comments>https://blogread.cn/it/article.php?id=8592#comment</comments>
		<description><![CDATA[<p><strong>标签：</strong>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=CLI" target="_blank">CLI</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=Homebrew" target="_blank">Homebrew</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=Tap" target="_blank">Tap</a></p><h1>如何为私有 CLI 工具提供 Homebrew 一键安装能力（完全指南）</h1>
<p>这份指南总结了如何为内部或半公开的 CLI 工具构建稳定、全自动且支持降级的 Homebrew Tap 分发流程。主要经验基于为 <code>mes-cli</code> 开发 <code>brew install</code> 功能的实践。</p>
<h2>1. 核心挑战与架构决策</h2>
<p>在实现 <code>brew install</code> 时，由于 CLI 源码及 Releases 是<strong>私有仓库 (Private Repository)</strong>，外部用户或内部员工在使用 <code>brew install</code> 下载时，如果在终端没有配置强权限的 <code>GITHUB_TOKEN</code>，会直接报 404 错误。</p>
<p><strong>我们的解决方案：脱离 GitHub Releases，使用公开的 OSS / CDN</strong><br>
1. <strong>源码编译与发布</strong>：CLI 仓库依然通过 GitHub Actions 完成编译跨平台包并生成 Releases。<br>
2. <strong>资产分发</strong>：流水线将生成的 ZIP 压缩包和 <code>checksums.txt</code> 同步推送到公开的阿里云 OSS（或 CDN）上。<br>
3. <strong>Formula 托管</strong>：建立一个<strong>公开</strong>的 <code>homebrew-tap</code> 仓库。流水线根据 OSS 上的资源，自动拼接出 Ruby 安装脚本（Formula），推送到该 Tap 仓库。<br>
4. <strong>客户端安装</strong>：用户的 <code>brew install</code> 会从公开的 Tap 仓库拉取脚本，并从公开的 OSS 高速下载压缩包，全程无权限阻碍。</p>
<hr>
<h2>2. 前期准备工作</h2>
<ol>
<li><strong>建立公开的 Tap 仓库</strong>：</li>
<li>命名规范：在你的组织下新建一个公开仓库，通常命名为 <code>homebrew-tap</code> 或 <code>homebrew-brew</code>。</li>
<li>这样用户可以使用 <code>brew tap org/tap</code> 引入。</li>
<li><strong>准备具有仓库读写权限的 Token</strong>：</li>
<li>在 GitHub 中创建一个具有访问目标 Tap 仓库推拉权限的 PAT (Personal Access Token)，或使用细粒度的 Token。</li>
<li>将该 Token 配置为 CLI 源码仓库的 Actions Secret（例如 <code>SKILLS_REPO_TOKEN</code>）。</li>
<li><strong>规范化打包产物</strong>：</li>
<li>确保你的打包脚本能生成跨平台的压缩包（例如 <code>cli-0.1.0-macOS-arm64.zip</code>）。</li>
<li>必须生成带有文件 SHA256 校验值的清单文件，如 <code>checksums.txt</code>，供后续提取使用。</li>
</ol>
<hr>
<h2>3. GitHub Actions 流水线自动化</h2>
<p>核心的魔法在于 CLI 源码仓库中的发布流水线（如 <code>.github/workflows/release.yml</code>）。它在每次打标签发布后，需要执行以下脚本去自动化生成 <code>.rb</code> 文件并提交。</p>
<h3>自动化脚本模板</h3>
<div class="codehilite">
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">  update-homebrew-tap:
    name: Update Homebrew Tap Formula
    runs-on: ubuntu-latest
    needs: upload-oss # 必须等你的产物上传到公共 OSS 之后执行
    steps:
      - name: Checkout tap repo
        uses: actions/checkout@v4
        with:
          repository: your-org/homebrew-tap
          token: ${{ secrets.SKILLS_REPO_TOKEN }}
          path: homebrew-tap

      - name: Generate Formula and update tap
        env:
          VERSION: ${{ github.ref_name }} # 比如 v0.4.9
          REPO: ${{ github.repository }}
        run: |
          VER_NUM=${VERSION#v}

          # 1. 直接从公共 OSS 下载 checksums.txt (避免 GitHub 私有权限问题)
          wget "https://your-public-oss.com/tools/cli/${VER_NUM}/checksums.txt" -O checksums.txt

          # 2. 从 checksums.txt 中精准提取各平台的 SHA256 
          SHA_MAC_ARM=(grep "cli-{VER_NUM}-macOS-arm64.zip" checksums.txt | awk '{print $1}')
          SHA_MAC_AMD=(grep "cli-{VER_NUM}-macOS-amd64.zip" checksums.txt | awk '{print $1}')
          SHA_LIN_ARM=(grep "cli-{VER_NUM}-linux-arm64.zip" checksums.txt | awk '{print $1}')
          SHA_LIN_AMD=(grep "cli-{VER_NUM}-linux-amd64.zip" checksums.txt | awk '{print $1}')

          OSS_URL="https://your-public-oss.com/tools/cli"

          mkdir -p homebrew-tap/Formula

          # 3. 生成无特殊字符的类名后缀 (解决 Ruby 类名规范：例如 0.4.9 变成 049)
          CLASS_SUFFIX=(echo "VER_NUM" | sed 's/[^a-zA-Z0-9]//g')

          # --------------------------------------------------------------------
          # 生成 1：永远指向最新的主 Formula (cli.rb)
          # --------------------------------------------------------------------
          cat &gt; homebrew-tap/Formula/cli.rb &lt;
          class Cli &lt; Formula
            desc "Your awesome CLI tools"
            homepage "https://github.com/$REPO"
            version "${VER_NUM}"

            if OS.mac? &amp;&amp; Hardware::CPU.arm?
              url "{OSS_URL}/{VER_NUM}/cli-${VER_NUM}-macOS-arm64.zip"
              sha256 "${SHA_MAC_ARM}"
            elsif OS.mac? &amp;&amp; Hardware::CPU.intel?
              url "{OSS_URL}/{VER_NUM}/cli-${VER_NUM}-macOS-amd64.zip"
              sha256 "${SHA_MAC_AMD}"
            elsif OS.linux? &amp;&amp; Hardware::CPU.arm?
              url "{OSS_URL}/{VER_NUM}/cli-${VER_NUM}-linux-arm64.zip"
              sha256 "${SHA_LIN_ARM}"
            elsif OS.linux? &amp;&amp; Hardware::CPU.intel?
              url "{OSS_URL}/{VER_NUM}/cli-${VER_NUM}-linux-amd64.zip"
              sha256 "${SHA_LIN_AMD}"
            end

            def install
              # 将二进制安装到系统 PATH
              bin.install "bin/cli"
              # 避坑点：如果有其他额外的目录或文件（如 skills/、assets/），必须显式复制到 prefix 下！
              prefix.install "skills"
            end

            def test
              system "#{bin}/cli", "--version"
            end
          end
          EOF

          # --------------------------------------------------------------------
          # 生成 2：带有版本号的防灾降级 Formula (cli@${VER_NUM}.rb)
          # --------------------------------------------------------------------
          # 代码完全同上，唯一区别是 Ruby 的类名必须加上 AT 版本号后缀
          cat &gt; homebrew-tap/Formula/cli@${VER_NUM}.rb &lt;
          class CliAT${CLASS_SUFFIX} &lt; Formula
            # 内容与上方一致...
          EOF

      - name: Commit and push formula
        run: |
          cd homebrew-tap
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git add Formula/
          if git diff --cached --quiet; then
            echo "No changes to commit."
          else
            git commit -m "chore: release formula for cli $VERSION"
            git push origin HEAD
          fi</code></pre>
</div>
<hr>
<h2>4. 关键经验与防坑指南</h2>
<h3>4.1 额外目录被 Homebrew 丢弃的问题</h3>
<p><strong>现象</strong>：用户执行 <code>brew install cli</code> 后，发现二进制和 <code>README.md</code> 都有了，但压缩包里的其它自定义目录（如 <code>skills/</code>）不见了。<br>
<strong>原因</strong>：Homebrew 默认只关心你在 <code>def install</code> 里指明的安装内容。<br>
<strong>对策</strong>：如果 ZIP 包里附带了需要长期存储的文件夹，你必须通过 <code>prefix.install "your-folder"</code> 将其强行放入 Homebrew 的 Cellar 根目录。</p>
<h3>4.2 提供“降版本”的后悔药机制</h3>
<p><strong>现象</strong>：如果最新发布的 CLI 携带了阻断性 Bug，CLI 自身的自动更新程序无法向下降级。而 Homebrew 原生的 <code>brew switch</code> 已经被官方弃用。<br>
<strong>对策</strong>：如上述自动化脚本中的“生成 2”，除了生成固定的 <code>cli.rb</code> 之外，必须针对每一次发布生成带有版本号的文件，如 <code>cli@0.4.9.rb</code>。<br>
<strong>Ruby 语法限制</strong>：文件名包含 <code>@</code> 与 <code>.</code> 时，Ruby 内部的 Class 名字必须去掉标点并转化为大驼峰。例如 <code>cli@0.4.9.rb</code> 内部类名必须叫 <code>CliAT049</code>，否则脚本报错。所以我们在流水线中加入了 <code>CLASS_SUFFIX=<span class="katex math inline">(echo "</span>VER_NUM" | sed 's/[^a-zA-Z0-9]//g')</code> 进行动态替换。</p>
<hr>
<h2>5. 最终暴露给用户的完美用法</h2>
<p>你只需要在文档中提供这段精简的指引即可：</p>
<p><strong>安装与更新：</strong></p>
<div class="codehilite">
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">brew tap your-org/tap
brew install cli
# 未来的更新（自动更新本体、附加目录和文档）
brew upgrade cli</code></pre>
</div>
<p><strong>回退稳定旧版本：</strong></p>
<div class="codehilite">
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext"># 假设最新版有问题，想要退回 0.4.9
brew install cli@0.4.9
brew unlink cli
brew link --overwrite cli@0.4.9</code></pre>
</div>
				<p><strong>您可能还对下面的文章感兴趣：</strong></p>
				<p><ol><li><a href="https://blogread.cn/it/article.php?id=8359" target="_blank">How to Install Native Homebrew on an Apple Silicon M1 Mac</a> [2021-06-13 22:52:09]</li></ol></p>]]></description>
		<content><![CDATA[本文针对私有CLI工具通过Homebrew分发时因权限导致的404问题，提供了一套完整解决方案。核心思路是解耦源码发布与资源分发：将编译后的二进制包与校验文件同步至公开的OSS/CDN，同时在公开的Tap仓库中托管自动维护的Ruby Formula。这确保了终端用户无需配置GitHub Token即可无缝安装与更新。方案详细阐述了前期准备（如Tap仓库创建、打包规范）、GitHub Actions自动化流水线的关键实现——该流水线能自动根据OSS上的资源生成指向最新版和特定旧版本的Formula脚本。文章还重点分享了若干实践经验：必须在`def install`阶段明确指定额外资源目录的安装路径，以避免文件被Homebrew丢弃；以及如何通过为每次发布生成带有版本号的Formula文件（如`cli@0.4.9.rb`），来建立可靠的版本降级“后悔药”机制。最终，用户可使用简洁的`brew tap`与`brew install`命令进行安装、更新与版本切换。]]></content>
	</item>
	<item>
		<title>Your Prototype Is Not Being Honest With Your Users (And Here’s How To Fix It)</title>
		<link>https://blogread.cn/it/article.php?id=8591</link>
		<author>Articles on Smashing Magazine — For Web Designers And Developers</author>
		<pubDate>2026-06-03 09:03:24</pubDate>
		<category domain="https://blogread.cn/it/category.php?id=13">设计</category>
		<guid>https://blogread.cn/it/article.php?id=8591</guid>
		<comments>https://blogread.cn/it/article.php?id=8591#comment</comments>
		<description><![CDATA[<p><strong>标签：</strong>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=ProtoPie" target="_blank">ProtoPie</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=%E4%BA%A4%E4%BA%92%E8%AE%BE%E8%AE%A1" target="_blank">交互设计</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=%E5%8E%9F%E5%9E%8B%E8%AE%BE%E8%AE%A1" target="_blank">原型设计</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=%E7%94%A8%E6%88%B7%E4%BD%93%E9%AA%8C" target="_blank">用户体验</a></p><p>This article is a sponsored by <a href="https://www.protopie.io/?utm_source=smashingmagazine&amp;utm_medium=referral&amp;utm_campaign=fintech_prototyping_tutorial">ProtoPie</a></p>
<p>There’s a moment in almost every usability session where a participant pauses at the login screen, types something, and glances up: checking whether they’re “doing it right.” That pause is a clear sign. They’ve already clocked that this isn’t a real app, and every data point collected after that moment is filtered through that awareness.</p>
<p>In financial product testing, the problem is sharper. Finance users are trained to notice when something feels off: a balance that doesn’t add up, a field that accepts anything. When a banking prototype skips real authentication, participants don’t just disengage; they stop mid-session to flag it. The team walks away with findings that reflect how users behave in a demonstration, not in a real product.</p>
<p>The fix is narrower than you’d think. Identify the moment where participant trust is established and make that interaction real. In a banking app, that moment is the login.</p>
<p>This tutorial builds it: credentials that validate, a live error state, and a biometric animation that feels native — no code required.</p>
What We’re Building: A Login That Behaves Like A Shipped Product
<p>The login flow, built around Pie Bank, a mobile banking prototype, includes functional text inputs, a masked password field, credential validation, a live error state, and a Face ID animation timed to feel indistinguishable from iOS.</p>
<p>What you’ll need:</p>
<ul>
<li>A login UI from Figma (or any supported design tool)</li>
<li><a href="https://www.protopie.io/download">ProtoPie Studio</a> — <strong>free to start</strong>, everything in this tutorial works on the free plan</li>
<li>A Lottie file for the Face ID animation (<a href="https://lottiefiles.com/free-animation/face-id-ios-checkmark-ui-animation-SAEU0Y3XHU">this one</a> is what we used)</li>
<li>The <a href="https://demo.protopie.cloud/p/606d44ace6d7ea8f41cf38ff">finished Pie Bank prototype file</a> — download it to follow alongside, or use it as a reference after you build</li>
</ul>
<img src="https://files.smashing.media/articles/prototype-users-fix-protopie/Intro_fintech-tutorial-login-usecases-preview.gif">

Step 1: Import From Figma Choose Scene, Not Flattened
<p>In Figma, open the ProtoPie plugin with your login frame selected and choose <strong>Scene</strong> when exporting. Flattened collapses everything into a single image; Scene preserves your layer hierarchy so every element arrives in ProtoPie as a separate, targetable layer.</p>
<p>Before moving on: rename every layer meaningfully. “Input Username” not “Rectangle 14”. You’ll reference these names in formulas: vague names compound into real time lost.</p>
<img src="https://files.smashing.media/articles/prototype-users-fix-protopie/Step%201_fintech-tutorial-design-import.gif">

Step 2: Swap Static Fields For Inputs That Actually Accept Text
<p>ProtoPie’s native <strong>Input</strong> layer accepts real keyboard entry: participants type actual text, not tap a placeholder. Go to <code>Text</code>  → <code>Input</code>, drag an Input layer onto your canvas, and nest it inside your username field group. Match it visually: placeholder text <strong>Username</strong>, background fill and font to match your design.</p>
<p>Hit preview. Click the field. Type. That’s the prototype starting to behave like an app rather than depicting one.</p>
<p>Rename this layer <strong>Input Username</strong>, duplicate it, and nest the copy inside your password field group.</p>
Step 3: One Property Change Masks The Password
<p>On the duplicated layer, change placeholder text to <strong>Password</strong> and set <strong>Type</strong> to <strong>Text Password</strong>. ProtoPie handles the masking: no custom logic needed.</p>
<p>Preview both fields: username shows text, password shows dots. It already feels real, and you haven’t written a single condition.</p>
<p><img src="https://files.smashing.media/articles/prototype-users-fix-protopie/Step%203_fintech-tutorial-password.png"></p>
Step 4: Build The Destination Scene Before Wiring Navigation
<p>Add a new scene, even a blank one. The most common sequencing mistake in ProtoPie is trying to wire a navigation response before a destination exists. Create it first.</p>
Step 5: Wire The Button: It Works, But It Still Lets Everyone Through
<p>Select <strong>Log In</strong>, add a <strong>Tap</strong> trigger, set response to <strong>Jump</strong>, target your dashboard scene, transition <strong>Slide in from right to left</strong>.</p>
<p>Preview and tap. It navigates: but for any input, including nothing. The prototype is still lying. The next two steps are the fix.</p>
<img src="https://files.smashing.media/articles/prototype-users-fix-protopie/Step%205_fintech-tutorial-login-button.gif">

Step 6: Add Variables So The Prototype Remembers What Was Typed
<p>At the bottom-left of ProtoPie, add two <strong>Text</strong> type variables: <code>username</code> and <code>password</code>. Bind each to its input layer with a formula:</p>
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">input("Input Username").text
input("Input Password").text</code></pre>

<p>Enable the debug icons: green overlays will show live variable values as you type. When you see your keystrokes appear in real time, the binding is confirmed.</p>
<p><img src="https://files.smashing.media/articles/prototype-users-fix-protopie/Step%206_fintech-tutorial_varibales.png"></p>
Step 7: Add A Condition So Only Valid Credentials Get Through
<p>Go back to the <strong>Tap</strong> trigger on the login button. Add a <strong>Condition</strong> with two rules, both must be true:</p>
<ul>
<li><code>username</code> equals <a href="mailto:%60alex.c@gmail.com">`alex.c@gmail.com</a>`</li>
<li><code>password</code> equals <code>ABC123</code></li>
</ul>
<p>Move the <strong>Jump</strong> response inside this condition. Wrong credentials, empty fields, wrong format: none get through. Participants now have to actually log in. That single constraint changes the texture of every test session that follows.</p>
<img src="https://files.smashing.media/articles/prototype-users-fix-protopie/Step%207_fintech-tutorial-condition.gif">

Step 8: Build The Error State, The Interaction Most Prototypes Skip
<p>Find your error message layer, rename it <strong>Error Text</strong>, set initial opacity to <strong>0</strong>. Add a second condition (the inverse of the first), and inside it, a <strong>Change Property</strong> response setting <strong>Error Text</strong> opacity to <strong>100</strong>.</p>
<p>Wrong credentials: error appears. Correct credentials: dashboard. Two outcomes: which is what makes this testable, not just demonstrable.</p>
Step 9: Add the Face ID Animation, The Detail That Makes Testers Ask “Is This Real”
<p>Go to <strong>Media</strong>, drag a <strong>Lottie</strong> layer onto canvas, load your Face ID file, and position it off-screen above the iPhone frame. On your <strong>Login with Face ID</strong> button, add a <strong>Tap</strong> trigger (rename it <strong>Tap Face ID</strong>) with four responses in sequence:</p>
<ul>
<li><strong>Move</strong>: Lottie container to <code>Y: 60</code></li>
<li><strong>Playback</strong>: Seek: time <code>0s</code> (resets so it always plays from the start)</li>
<li><strong>Playback: Play</strong>: Lottie file</li>
<li><strong>Jump</strong>: to dashboard</li>
</ul>
Step 10: Stagger The Timing, This Is What Makes It Feel Native
<p>Without delays, all four responses fire at once and the scene jumps before the animation plays. Add offsets:</p>
<table>
  <thead>
    <tr>
      <th>Response</th>
      <th>Delay</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Move</td>
      <td>0s</td>
    </tr>
    <tr>
      <td>Seek</td>
      <td>0s</td>
    </tr>
    <tr>
      <td>Play</td>
      <td>0.5s</td>
    </tr>
    <tr>
      <td>Jump</td>
      <td>1s</td>
    </tr>
  </tbody>
</table>

<p>Enable <strong>Reset selected scenes</strong> on Jump: without it, navigating back leaves the animation stuck at <code>Y: 60</code>.</p>
<p>Preview: tap Face ID, animation drops in, plays, screen transitions. A biometric login indistinguishable from the real thing.</p>
<img src="https://files.smashing.media/articles/prototype-users-fix-protopie/Step%2010_fintech-tutorial-faceID.gif">You can download <a href="https://demo.protopie.cloud/p/606d44ace6d7ea8f41cf38ff">Pie Bank, Chapter 1: Login Flow</a> and explore it freely.

A Login This Real Changes What You Can Learn From Your Prototype
<p>When authentication actually works, the error state becomes a genuine research touchpoint: do users understand the message, do they retry, do they reach for Face ID instead? These are questions a faked login can’t answer.</p>
<p>In stakeholder reviews, the flow speaks for itself. In engineering handoff, the interaction panel documents the behavior (conditional logic, variable bindings, timing) so engineers see intent, not interpretation.</p>
<p>This is why FinTech teams invest in login fidelity even when the login isn’t the feature being tested. It’s where participant trust is established. Get it right, and everything downstream produces better signal.</p>
<hr>


<p><em>This tutorial is part of the <a href="https://www.protopie.io/blog/fintech-prototyping-with-protopie">FinTech Prototyping with ProtoPie</a> series on the ProtoPie blog. The series builds Pie Bank from the ground up across four chapters, covering the dashboard, money transfer logic, and camera integration. If this tutorial was useful, the rest of the series goes further.</em></p>
				<p><strong>您可能还对下面的文章感兴趣：</strong></p>
				<p><ol><li><a href="https://blogread.cn/it/article.php?id=8548" target="_blank">Building Digital Trust: An Empathy-Centred UX Framework For Mental Health Apps</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8157" target="_blank">智能手机让人类专注力下降为8秒 比金鱼少1秒</a> [2017-09-21 17:40:51]</li><li><a href="https://blogread.cn/it/article.php?id=7753" target="_blank">为什么要段首空两格</a> [2016-02-16 20:55:30]</li><li><a href="https://blogread.cn/it/article.php?id=7529" target="_blank">产品设计之尊重常识</a> [2015-09-04 21:42:55]</li><li><a href="https://blogread.cn/it/article.php?id=7360" target="_blank">产品经理都是潜伏在公司里的创业者</a> [2015-02-03 21:56:55]</li><li><a href="https://blogread.cn/it/article.php?id=7311" target="_blank">在大公司和小公司做产品的区别</a> [2015-01-22 23:27:38]</li><li><a href="https://blogread.cn/it/article.php?id=7307" target="_blank">我的 Sublime Text 2 笔记</a> [2015-01-21 23:44:49]</li><li><a href="https://blogread.cn/it/article.php?id=7161" target="_blank">用吐槽的方式生产内容</a> [2014-12-06 20:05:35]</li><li><a href="https://blogread.cn/it/article.php?id=6987" target="_blank">打造舒适的阅读空间—云阅读iPad3.0设计总结交互篇</a> [2014-11-23 21:07:41]</li><li><a href="https://blogread.cn/it/article.php?id=6961" target="_blank">侧边栏交互的利弊</a> [2014-11-20 23:47:26]</li><li><a href="https://blogread.cn/it/article.php?id=6890" target="_blank">高效输出移动app产品原型</a> [2014-07-15 23:02:58]</li><li><a href="https://blogread.cn/it/article.php?id=6828" target="_blank">心智模型学习：如何探究Y里的why</a> [2014-04-07 22:41:48]</li><li><a href="https://blogread.cn/it/article.php?id=6750" target="_blank">进行用户研究的五步法【译】</a> [2013-10-17 12:29:30]</li><li><a href="https://blogread.cn/it/article.php?id=6647" target="_blank">移动用户体验设计新要素</a> [2013-08-28 22:19:28]</li><li><a href="https://blogread.cn/it/article.php?id=6628" target="_blank">普通设计师与顶级设计师的区别是什么？</a> [2013-08-21 13:19:21]</li><li><a href="https://blogread.cn/it/article.php?id=6617" target="_blank">谈谈“需求场景”的重要性</a> [2013-08-15 12:58:06]</li><li><a href="https://blogread.cn/it/article.php?id=6598" target="_blank">如何跨岗位盯人</a> [2013-08-12 13:38:52]</li><li><a href="https://blogread.cn/it/article.php?id=6591" target="_blank">APP「返回键」的进化</a> [2013-08-08 23:42:42]</li><li><a href="https://blogread.cn/it/article.php?id=6530" target="_blank">关于交互Demo设计的一些建议</a> [2013-07-26 13:29:32]</li><li><a href="https://blogread.cn/it/article.php?id=6466" target="_blank">有趣的下拉刷新</a> [2013-06-09 13:18:17]</li><li><a href="https://blogread.cn/it/article.php?id=6382" target="_blank">给产品提意见</a> [2013-05-13 14:00:28]</li><li><a href="https://blogread.cn/it/article.php?id=6350" target="_blank">iOS设备上高效演示APP原型的方法总结</a> [2013-05-01 18:30:54]</li><li><a href="https://blogread.cn/it/article.php?id=6294" target="_blank">设计产品的两种思路</a> [2013-03-10 23:50:08]</li><li><a href="https://blogread.cn/it/article.php?id=6283" target="_blank">选3本书推荐给新入行的PM</a> [2013-03-05 13:22:27]</li><li><a href="https://blogread.cn/it/article.php?id=6163" target="_blank">随侃设计师的个人素养</a> [2013-01-08 13:11:06]</li><li><a href="https://blogread.cn/it/article.php?id=6115" target="_blank">界面设计速成</a> [2012-12-19 13:33:52]</li><li><a href="https://blogread.cn/it/article.php?id=6060" target="_blank">可用性测试好助手——Morae软件的应用</a> [2012-12-07 23:51:46]</li><li><a href="https://blogread.cn/it/article.php?id=5812" target="_blank">深度解读网站用户体验三要素（1）：别让我等</a> [2012-09-12 23:07:58]</li><li><a href="https://blogread.cn/it/article.php?id=5664" target="_blank">好朋友【阿木】谈极简风格在设计中的运用</a> [2012-08-10 00:02:23]</li><li><a href="https://blogread.cn/it/article.php?id=5631" target="_blank">随记：关于职业规划，交互设计及写博客</a> [2012-08-05 22:42:56]</li><li><a href="https://blogread.cn/it/article.php?id=5564" target="_blank">Web导航设计二三事</a> [2012-07-12 23:24:30]</li><li><a href="https://blogread.cn/it/article.php?id=5488" target="_blank">产品经理的杂念</a> [2012-06-17 17:53:16]</li><li><a href="https://blogread.cn/it/article.php?id=5467" target="_blank">编程珠玑番外篇 -M. 软件工具的设计哲学1</a> [2012-06-10 22:12:23]</li><li><a href="https://blogread.cn/it/article.php?id=5444" target="_blank">浅谈Mobile Site优化</a> [2012-06-07 00:20:47]</li><li><a href="https://blogread.cn/it/article.php?id=5416" target="_blank">儿童移动应用的界面设计基础知识</a> [2012-06-03 14:06:30]</li><li><a href="https://blogread.cn/it/article.php?id=5408" target="_blank">豆瓣东西上线,及谈谈签到、评论等产品的设计</a> [2012-05-28 13:25:50]</li><li><a href="https://blogread.cn/it/article.php?id=5401" target="_blank">走进工具型网站——释义及典型案例</a> [2012-05-28 13:19:34]</li><li><a href="https://blogread.cn/it/article.php?id=5316" target="_blank">无逻辑，不产品。</a> [2012-05-12 22:18:32]</li><li><a href="https://blogread.cn/it/article.php?id=5267" target="_blank">忘记技术原理，关注用户心智</a> [2012-05-02 23:49:42]</li><li><a href="https://blogread.cn/it/article.php?id=5175" target="_blank">信息架构的模式</a> [2012-04-07 21:45:42]</li><li><a href="https://blogread.cn/it/article.php?id=5166" target="_blank">何为产品的“喂养野兽”模式</a> [2012-04-07 15:02:38]</li><li><a href="https://blogread.cn/it/article.php?id=5154" target="_blank">产品原则，还是用户习惯？</a> [2012-04-07 14:32:59]</li><li><a href="https://blogread.cn/it/article.php?id=5139" target="_blank">怎样做符合用户预期的设计</a> [2012-03-31 23:38:02]</li><li><a href="https://blogread.cn/it/article.php?id=5129" target="_blank">读者来信回复模版</a> [2012-03-31 22:42:33]</li><li><a href="https://blogread.cn/it/article.php?id=5097" target="_blank">可读性:优化文本长度</a> [2012-03-25 21:00:16]</li><li><a href="https://blogread.cn/it/article.php?id=5096" target="_blank">从滚动条消失看细节设计</a> [2012-03-25 20:59:22]</li><li><a href="https://blogread.cn/it/article.php?id=5036" target="_blank">如何写一份交互说明文档</a> [2012-03-11 22:10:29]</li><li><a href="https://blogread.cn/it/article.php?id=5021" target="_blank">什么是互联网产品经理</a> [2012-03-04 20:39:48]</li><li><a href="https://blogread.cn/it/article.php?id=5003" target="_blank">为触屏手机而设计系列1——拇指操作的“热区/死角”与“控件尺寸”</a> [2012-03-04 17:46:58]</li><li><a href="https://blogread.cn/it/article.php?id=4993" target="_blank">浅析产品新手引导设计</a> [2012-03-04 17:38:15]</li><li><a href="https://blogread.cn/it/article.php?id=4915" target="_blank">注意力与交互设计</a> [2012-02-01 18:00:19]</li><li><a href="https://blogread.cn/it/article.php?id=4890" target="_blank">iPad游戏体验之差异化设计</a> [2012-01-29 20:34:57]</li><li><a href="https://blogread.cn/it/article.php?id=4882" target="_blank">知心怪蜀黍NO.6 设计与运营的思维差异，兼谈知乎</a> [2012-01-29 20:23:02]</li><li><a href="https://blogread.cn/it/article.php?id=4846" target="_blank">过度设计的判定</a> [2012-01-27 18:16:21]</li><li><a href="https://blogread.cn/it/article.php?id=4751" target="_blank">产品的气质和设计的沉淀</a> [2012-01-03 23:47:45]</li><li><a href="https://blogread.cn/it/article.php?id=4748" target="_blank">创造优雅的交互设计</a> [2012-01-03 23:46:22]</li><li><a href="https://blogread.cn/it/article.php?id=4732" target="_blank">为信息设计</a> [2012-01-03 23:22:26]</li><li><a href="https://blogread.cn/it/article.php?id=4730" target="_blank">知心怪蜀黍NO.4 交互设计师的吐槽</a> [2012-01-03 23:18:08]</li><li><a href="https://blogread.cn/it/article.php?id=4713" target="_blank">谈交互设计的经验积累</a> [2011-12-22 22:26:00]</li><li><a href="https://blogread.cn/it/article.php?id=4700" target="_blank">知心怪蜀黍NO.2 产品经理如何修炼内功</a> [2011-12-22 22:01:26]</li><li><a href="https://blogread.cn/it/article.php?id=4696" target="_blank">互联网用户常见心理特征</a> [2011-12-21 00:03:32]</li><li><a href="https://blogread.cn/it/article.php?id=4629" target="_blank">如何设计新手用户引导</a> [2011-11-21 00:18:58]</li><li><a href="https://blogread.cn/it/article.php?id=4496" target="_blank">取代点击操作</a> [2011-10-17 22:17:15]</li><li><a href="https://blogread.cn/it/article.php?id=4455" target="_blank">交互设计那些事儿</a> [2011-10-12 00:18:35]</li><li><a href="https://blogread.cn/it/article.php?id=4443" target="_blank">交互设计如何提高专业能力</a> [2011-10-11 23:49:32]</li><li><a href="https://blogread.cn/it/article.php?id=4439" target="_blank">产品感悟</a> [2011-10-04 18:07:40]</li><li><a href="https://blogread.cn/it/article.php?id=4409" target="_blank">从IE 9的广告说起</a> [2011-09-25 13:41:28]</li><li><a href="https://blogread.cn/it/article.php?id=4300" target="_blank">从社区常识说起</a> [2011-09-07 23:08:18]</li><li><a href="https://blogread.cn/it/article.php?id=4272" target="_blank">由产品经理招人难想到的</a> [2011-09-04 22:29:25]</li><li><a href="https://blogread.cn/it/article.php?id=4270" target="_blank">90%的人不知道使用 CTRL + F</a> [2011-09-04 14:22:58]</li><li><a href="https://blogread.cn/it/article.php?id=4264" target="_blank">绘制交互流程图</a> [2011-08-30 23:57:01]</li><li><a href="https://blogread.cn/it/article.php?id=4263" target="_blank">桌面管理软件那点事</a> [2011-08-30 23:41:59]</li><li><a href="https://blogread.cn/it/article.php?id=4250" target="_blank">产品用户体验质量的模糊评价（1）――灰色关联分析</a> [2011-08-26 22:23:58]</li><li><a href="https://blogread.cn/it/article.php?id=4219" target="_blank">首页大屏广告交互设计探讨</a> [2011-08-22 12:24:10]</li><li><a href="https://blogread.cn/it/article.php?id=4209" target="_blank">心理学在沟通中的应用</a> [2011-08-22 12:16:26]</li><li><a href="https://blogread.cn/it/article.php?id=4207" target="_blank">过度设计：有所为有所不为</a> [2011-08-21 10:51:13]</li><li><a href="https://blogread.cn/it/article.php?id=4181" target="_blank">Web设计师能从游戏中学到些什么</a> [2011-08-19 22:58:56]</li><li><a href="https://blogread.cn/it/article.php?id=4163" target="_blank">推特与微博的信息架构说</a> [2011-08-14 16:22:27]</li><li><a href="https://blogread.cn/it/article.php?id=4161" target="_blank">邮箱投放问卷时影响用户响应问卷与填答问卷的要素</a> [2011-08-14 16:21:38]</li><li><a href="https://blogread.cn/it/article.php?id=4074" target="_blank">确认框的设计</a> [2011-07-30 21:16:39]</li><li><a href="https://blogread.cn/it/article.php?id=4047" target="_blank">iPad用户体验暨UI设计―如何设计出优秀的用户界面</a> [2011-07-24 14:54:44]</li><li><a href="https://blogread.cn/it/article.php?id=3998" target="_blank">设计要注意火候</a> [2011-07-15 00:06:40]</li><li><a href="https://blogread.cn/it/article.php?id=3974" target="_blank">阻碍创新的两种抄袭</a> [2011-07-09 22:41:21]</li><li><a href="https://blogread.cn/it/article.php?id=3967" target="_blank">不靠谱的互动驱动因素</a> [2011-07-09 22:27:29]</li><li><a href="https://blogread.cn/it/article.php?id=3901" target="_blank">产品经理你伤不起</a> [2011-06-23 13:40:43]</li><li><a href="https://blogread.cn/it/article.php?id=3889" target="_blank">Web表单设计:表单结构</a> [2011-06-23 13:27:48]</li><li><a href="https://blogread.cn/it/article.php?id=3873" target="_blank">给想转行做产品经理的同学</a> [2011-06-22 00:26:39]</li><li><a href="https://blogread.cn/it/article.php?id=3847" target="_blank">用户的地图需求分析</a> [2011-06-21 13:44:50]</li><li><a href="https://blogread.cn/it/article.php?id=3796" target="_blank">产品的成功学</a> [2011-06-14 13:44:13]</li><li><a href="https://blogread.cn/it/article.php?id=3778" target="_blank">服务设计小笔记</a> [2011-06-10 14:05:16]</li><li><a href="https://blogread.cn/it/article.php?id=3764" target="_blank">浅析摄影与WEB设计中的构图</a> [2011-06-02 23:23:35]</li><li><a href="https://blogread.cn/it/article.php?id=3608" target="_blank">让界面更加清爽</a> [2011-05-17 09:17:54]</li><li><a href="https://blogread.cn/it/article.php?id=3547" target="_blank">简析 IOS 程序图标的设计</a> [2011-04-28 13:23:51]</li><li><a href="https://blogread.cn/it/article.php?id=3480" target="_blank">说说Stack Overflow和Quora</a> [2011-03-29 00:07:46]</li><li><a href="https://blogread.cn/it/article.php?id=3464" target="_blank">浅谈白社会交互设计的创新(三)</a> [2011-03-27 23:46:20]</li><li><a href="https://blogread.cn/it/article.php?id=3463" target="_blank">浅谈白社会交互设计的创新(二)</a> [2011-03-27 23:45:24]</li><li><a href="https://blogread.cn/it/article.php?id=3462" target="_blank">浅谈白社会交互设计的创新(一)</a> [2011-03-27 23:44:06]</li><li><a href="https://blogread.cn/it/article.php?id=3457" target="_blank">交互规范实例――白社会Dialog规范</a> [2011-03-27 23:41:07]</li><li><a href="https://blogread.cn/it/article.php?id=3431" target="_blank">工具型产品的设计感想</a> [2011-03-21 00:14:53]</li><li><a href="https://blogread.cn/it/article.php?id=3366" target="_blank">Android那些事儿（二）安卓手机交互特性</a> [2011-03-01 22:45:50]</li><li><a href="https://blogread.cn/it/article.php?id=3357" target="_blank">WindowsPhone7初体验</a> [2011-02-28 23:21:56]</li><li><a href="https://blogread.cn/it/article.php?id=3343" target="_blank">浅谈认知心理学与产品设计的结合</a> [2011-02-27 22:58:05]</li><li><a href="https://blogread.cn/it/article.php?id=3339" target="_blank">读《Web 表单设计》</a> [2011-02-27 22:51:12]</li><li><a href="https://blogread.cn/it/article.php?id=3322" target="_blank">网站内容决定网站的前途</a> [2011-02-23 22:18:10]</li><li><a href="https://blogread.cn/it/article.php?id=3267" target="_blank">产品经理能力模型解说―把控</a> [2011-02-14 22:41:13]</li><li><a href="https://blogread.cn/it/article.php?id=3217" target="_blank">触摸屏手机输入法的一些思考</a> [2011-02-11 22:50:02]</li><li><a href="https://blogread.cn/it/article.php?id=3201" target="_blank">为自己打造良好的文章阅读体验</a> [2011-02-10 22:21:44]</li><li><a href="https://blogread.cn/it/article.php?id=3194" target="_blank">关于理论和术语</a> [2011-02-09 22:27:44]</li><li><a href="https://blogread.cn/it/article.php?id=3190" target="_blank">从创业的时髦说起</a> [2011-02-09 22:09:42]</li><li><a href="https://blogread.cn/it/article.php?id=3139" target="_blank">Web交互设计优化的简易Check list</a> [2011-01-30 18:53:02]</li><li><a href="https://blogread.cn/it/article.php?id=3117" target="_blank">等级制度及成长体系</a> [2011-01-29 19:23:19]</li><li><a href="https://blogread.cn/it/article.php?id=3101" target="_blank">导航设计中的信息结构</a> [2011-01-26 21:20:56]</li><li><a href="https://blogread.cn/it/article.php?id=3093" target="_blank">更多的限制，更简单的设计</a> [2011-01-26 21:10:00]</li><li><a href="https://blogread.cn/it/article.php?id=3080" target="_blank">在淘宝大半年的零散体会</a> [2011-01-24 23:04:32]</li><li><a href="https://blogread.cn/it/article.php?id=3069" target="_blank">更宽广的交互更高效的产品</a> [2011-01-23 22:39:12]</li><li><a href="https://blogread.cn/it/article.php?id=3047" target="_blank">投影――信息架构中物理到虚拟的一致性</a> [2011-01-20 22:15:34]</li><li><a href="https://blogread.cn/it/article.php?id=2988" target="_blank">产品思考：分众</a> [2011-01-10 23:23:09]</li><li><a href="https://blogread.cn/it/article.php?id=2981" target="_blank">产品五问</a> [2011-01-09 22:56:05]</li><li><a href="https://blogread.cn/it/article.php?id=2931" target="_blank">舒服：Aardvark邮件沟通的用语艺术</a> [2010-12-29 09:12:39]</li><li><a href="https://blogread.cn/it/article.php?id=2918" target="_blank">对错与行动</a> [2010-12-28 00:23:12]</li><li><a href="https://blogread.cn/it/article.php?id=2872" target="_blank">博客导航 -- 网址导航网站的垂直延续</a> [2010-12-15 22:48:06]</li><li><a href="https://blogread.cn/it/article.php?id=2812" target="_blank">格式塔：转动视觉的魔方</a> [2010-12-07 21:30:56]</li><li><a href="https://blogread.cn/it/article.php?id=2811" target="_blank">网站的本质和要素</a> [2010-12-07 21:28:27]</li><li><a href="https://blogread.cn/it/article.php?id=2797" target="_blank">垂直门户网站的内容层次</a> [2010-12-05 22:54:06]</li><li><a href="https://blogread.cn/it/article.php?id=2790" target="_blank">手机UI设计检测要素</a> [2010-12-05 21:35:31]</li><li><a href="https://blogread.cn/it/article.php?id=2770" target="_blank">细说魅力属性</a> [2010-11-30 22:44:02]</li><li><a href="https://blogread.cn/it/article.php?id=2767" target="_blank">信息闭环设计小谈</a> [2010-11-29 22:52:28]</li><li><a href="https://blogread.cn/it/article.php?id=2738" target="_blank">我的十年，交互之外的那些事</a> [2010-11-24 00:10:10]</li><li><a href="https://blogread.cn/it/article.php?id=2735" target="_blank">个人学习经验之谈</a> [2010-11-22 21:24:14]</li><li><a href="https://blogread.cn/it/article.php?id=2710" target="_blank">Icon设计要点――信息传达的准确度（一）</a> [2010-11-14 22:32:08]</li><li><a href="https://blogread.cn/it/article.php?id=2632" target="_blank">读书笔记-应需而变：设计的力量</a> [2010-11-01 19:58:37]</li><li><a href="https://blogread.cn/it/article.php?id=2625" target="_blank">流程管理与用户研究</a> [2010-10-31 23:34:07]</li><li><a href="https://blogread.cn/it/article.php?id=2579" target="_blank">我们需要培养用户的使用习惯</a> [2010-10-26 22:04:01]</li><li><a href="https://blogread.cn/it/article.php?id=2554" target="_blank">做产品前六问自己</a> [2010-10-24 19:28:09]</li><li><a href="https://blogread.cn/it/article.php?id=2541" target="_blank">态度的重量</a> [2010-10-21 08:57:29]</li><li><a href="https://blogread.cn/it/article.php?id=2530" target="_blank">漫话产品设计</a> [2010-10-19 00:29:55]</li><li><a href="https://blogread.cn/it/article.php?id=2489" target="_blank">姐要的视频广告</a> [2010-10-12 08:38:59]</li><li><a href="https://blogread.cn/it/article.php?id=2480" target="_blank">SEO对网站性能的解决方法以及影响</a> [2010-10-10 08:40:03]</li><li><a href="https://blogread.cn/it/article.php?id=2476" target="_blank">上海航空网站注册表单优化方案</a> [2010-10-10 08:35:25]</li><li><a href="https://blogread.cn/it/article.php?id=2456" target="_blank">手机客户端首页设计</a> [2010-10-07 08:19:51]</li><li><a href="https://blogread.cn/it/article.php?id=2453" target="_blank">产品经理的素质</a> [2010-10-07 08:15:48]</li><li><a href="https://blogread.cn/it/article.php?id=2443" target="_blank">基于黄金分割率的Twitter新版页面布局探究</a> [2010-09-30 03:11:43]</li><li><a href="https://blogread.cn/it/article.php?id=2427" target="_blank">产品经理之聆听用户的声音</a> [2010-09-27 08:48:29]</li><li><a href="https://blogread.cn/it/article.php?id=2407" target="_blank">与用户交互的核心――读《Web表单设计》</a> [2010-09-26 08:54:21]</li><li><a href="https://blogread.cn/it/article.php?id=2314" target="_blank">把项目当做产品来做</a> [2010-08-24 09:35:07]</li><li><a href="https://blogread.cn/it/article.php?id=2269" target="_blank">巧用任务流进行产品设计</a> [2010-08-17 23:24:32]</li><li><a href="https://blogread.cn/it/article.php?id=2268" target="_blank">产品经理进化史</a> [2010-08-17 23:20:50]</li><li><a href="https://blogread.cn/it/article.php?id=2229" target="_blank">网页设计中美女视线的影响</a> [2010-08-13 09:54:47]</li><li><a href="https://blogread.cn/it/article.php?id=2215" target="_blank">产品经理，你用多少时间来思考</a> [2010-08-12 23:25:23]</li><li><a href="https://blogread.cn/it/article.php?id=2213" target="_blank">思维和语言随笔 2</a> [2010-08-12 09:22:52]</li><li><a href="https://blogread.cn/it/article.php?id=2187" target="_blank">抵抗天赋的诱惑</a> [2010-08-10 04:33:01]</li><li><a href="https://blogread.cn/it/article.php?id=2090" target="_blank">中国式产品经理</a> [2010-07-26 23:41:00]</li><li><a href="https://blogread.cn/it/article.php?id=2089" target="_blank">浅述各平台系统交互设计的不同关注点</a> [2010-07-26 23:38:59]</li><li><a href="https://blogread.cn/it/article.php?id=1975" target="_blank">设计上的小细节（二）</a> [2010-07-19 10:04:59]</li><li><a href="https://blogread.cn/it/article.php?id=1969" target="_blank">好产品的简洁之道</a> [2010-07-18 23:35:24]</li><li><a href="https://blogread.cn/it/article.php?id=1954" target="_blank">尊重是自己给的</a> [2010-07-16 00:08:59]</li><li><a href="https://blogread.cn/it/article.php?id=1953" target="_blank">富媒体广告投放的一些经验</a> [2010-07-16 00:08:41]</li><li><a href="https://blogread.cn/it/article.php?id=1917" target="_blank">120个优秀的水平导航设计</a> [2010-07-12 23:29:05]</li><li><a href="https://blogread.cn/it/article.php?id=1894" target="_blank">手机软件交互设计经验分享</a> [2010-07-06 23:28:28]</li><li><a href="https://blogread.cn/it/article.php?id=1826" target="_blank">解读iPhone平台的一些优秀设计思路</a> [2010-06-22 13:11:58]</li><li><a href="https://blogread.cn/it/article.php?id=1818" target="_blank">设计上的小细节</a> [2010-06-20 23:45:32]</li><li><a href="https://blogread.cn/it/article.php?id=1804" target="_blank">NPR简介</a> [2010-06-18 13:32:26]</li><li><a href="https://blogread.cn/it/article.php?id=1802" target="_blank">简洁的是最好的吗？</a> [2010-06-18 13:15:57]</li><li><a href="https://blogread.cn/it/article.php?id=1790" target="_blank">原型: 新浪微博客户端 </a> [2010-06-16 23:51:21]</li><li><a href="https://blogread.cn/it/article.php?id=1789" target="_blank">设计从整理开始</a> [2010-06-12 18:02:59]</li><li><a href="https://blogread.cn/it/article.php?id=1769" target="_blank">创造一个可理解的世界</a> [2010-06-12 09:56:11]</li><li><a href="https://blogread.cn/it/article.php?id=1758" target="_blank">信息扁平化</a> [2010-06-07 13:06:49]</li><li><a href="https://blogread.cn/it/article.php?id=1744" target="_blank">如何让“没兴趣的人”也来用你的产品</a> [2010-06-05 11:41:43]</li><li><a href="https://blogread.cn/it/article.php?id=1741" target="_blank">深泽直人：无意识设计</a> [2010-06-05 11:37:07]</li><li><a href="https://blogread.cn/it/article.php?id=1737" target="_blank">再议手机交互设计原则</a> [2010-06-04 14:52:22]</li><li><a href="https://blogread.cn/it/article.php?id=1657" target="_blank">交互行为量化方法之GOMS击键层模型</a> [2010-05-28 09:36:33]</li><li><a href="https://blogread.cn/it/article.php?id=1636" target="_blank">以用户为中心的“精于心，简于型”</a> [2010-05-26 09:46:00]</li><li><a href="https://blogread.cn/it/article.php?id=1597" target="_blank">烂大街的用户体验</a> [2010-05-23 21:46:50]</li><li><a href="https://blogread.cn/it/article.php?id=1568" target="_blank">个人知识管理</a> [2010-05-20 13:21:26]</li><li><a href="https://blogread.cn/it/article.php?id=1550" target="_blank">安慰你的用户</a> [2010-05-14 14:00:07]</li><li><a href="https://blogread.cn/it/article.php?id=1548" target="_blank">什么时候使用什么用研究方法？</a> [2010-05-14 13:53:25]</li><li><a href="https://blogread.cn/it/article.php?id=1545" target="_blank">设计提升满意度</a> [2010-05-13 13:49:49]</li><li><a href="https://blogread.cn/it/article.php?id=1540" target="_blank">我来做淘宝商城的首页设计</a> [2010-05-12 13:26:47]</li><li><a href="https://blogread.cn/it/article.php?id=1525" target="_blank">互联网产品的“打通”问题</a> [2010-05-10 14:54:55]</li><li><a href="https://blogread.cn/it/article.php?id=1507" target="_blank">页面表达常用方式</a> [2010-05-05 12:39:10]</li><li><a href="https://blogread.cn/it/article.php?id=1483" target="_blank">门户、论坛、博客、SNS，网站模式的辨析</a> [2010-04-29 23:29:46]</li><li><a href="https://blogread.cn/it/article.php?id=1472" target="_blank">互联网产品经理，全方位入门，图书推荐</a> [2010-04-28 15:43:30]</li><li><a href="https://blogread.cn/it/article.php?id=1454" target="_blank">触摸未来的QQ概念版设计</a> [2010-04-27 13:44:11]</li><li><a href="https://blogread.cn/it/article.php?id=1451" target="_blank">空行不空格式排版组织原理</a> [2010-04-27 13:39:02]</li><li><a href="https://blogread.cn/it/article.php?id=1432" target="_blank">激发新用户使用SNS网络应用的一般方法</a> [2010-04-22 18:22:21]</li><li><a href="https://blogread.cn/it/article.php?id=1409" target="_blank">越简单越丰富――极简网页设计视觉呈现技巧</a> [2010-04-16 13:27:57]</li><li><a href="https://blogread.cn/it/article.php?id=1404" target="_blank">交互设计实用指南系列(8)―深广度平衡</a> [2010-04-16 09:24:05]</li><li><a href="https://blogread.cn/it/article.php?id=1403" target="_blank">交互设计实用指南系列(9)―一次点击</a> [2010-04-16 09:23:41]</li><li><a href="https://blogread.cn/it/article.php?id=1392" target="_blank">视觉设计前瞻实用性研究（PNVD） 第五期</a> [2010-04-15 13:46:18]</li><li><a href="https://blogread.cn/it/article.php?id=1379" target="_blank">不一样的交互组件（上）</a> [2010-04-14 13:41:56]</li><li><a href="https://blogread.cn/it/article.php?id=1365" target="_blank">读书（一）</a> [2010-04-14 09:18:40]</li><li><a href="https://blogread.cn/it/article.php?id=1252" target="_blank">互联网产品经理必读书目</a> [2010-03-26 14:24:36]</li><li><a href="https://blogread.cn/it/article.php?id=1119" target="_blank">[游戏笔记]游戏创新新十年</a> [2010-03-02 13:56:25]</li><li><a href="https://blogread.cn/it/article.php?id=1092" target="_blank">WEB注册表单的设计</a> [2010-03-01 09:19:58]</li><li><a href="https://blogread.cn/it/article.php?id=1013" target="_blank">用户习惯那点事</a> [2010-01-26 10:25:31]</li><li><a href="https://blogread.cn/it/article.php?id=997" target="_blank">视觉注意力―解剖设计的根源</a> [2010-01-23 16:15:40]</li><li><a href="https://blogread.cn/it/article.php?id=990" target="_blank">标签明晰、有效</a> [2010-01-19 09:19:06]</li><li><a href="https://blogread.cn/it/article.php?id=881" target="_blank">如果我们用这样的心态做产品</a> [2009-12-24 15:08:09]</li><li><a href="https://blogread.cn/it/article.php?id=862" target="_blank">更真实的理解用户</a> [2009-12-22 14:19:34]</li><li><a href="https://blogread.cn/it/article.php?id=801" target="_blank">交互设计实用指南系列（1）――“有效性”之“操作入口明确”</a> [2009-12-11 22:55:15]</li><li><a href="https://blogread.cn/it/article.php?id=763" target="_blank">轻设计，让网站灵敏轻便的6个技巧</a> [2009-12-03 21:34:39]</li><li><a href="https://blogread.cn/it/article.php?id=708" target="_blank">产品的情商</a> [2009-11-26 22:22:30]</li><li><a href="https://blogread.cn/it/article.php?id=693" target="_blank">谈谈眼动研究的一些作用</a> [2009-11-24 09:23:53]</li><li><a href="https://blogread.cn/it/article.php?id=511" target="_blank">用户体验的时间尺度</a> [2009-11-09 13:35:15]</li><li><a href="https://blogread.cn/it/article.php?id=415" target="_blank">产品设计理念杂谈问题之Caoz的解析</a> [2009-11-02 21:25:28]</li><li><a href="https://blogread.cn/it/article.php?id=402" target="_blank">什么是产品人才</a> [2009-11-02 12:28:45]</li><li><a href="https://blogread.cn/it/article.php?id=394" target="_blank">他们不需要产品</a> [2009-11-01 22:51:56]</li><li><a href="https://blogread.cn/it/article.php?id=280" target="_blank">初窥交互设计</a> [2009-10-21 22:41:14]</li><li><a href="https://blogread.cn/it/article.php?id=278" target="_blank">背着包袱跳着走</a> [2009-10-21 22:39:39]</li><li><a href="https://blogread.cn/it/article.php?id=243" target="_blank">马化腾在腾讯产品峰会上关于产品设计和开发的内部讲座</a> [2009-10-20 22:21:15]</li><li><a href="https://blogread.cn/it/article.php?id=231" target="_blank">看看各个网站的404错误处理</a> [2009-10-19 23:32:51]</li><li><a href="https://blogread.cn/it/article.php?id=136" target="_blank">淘UCD心得</a> [2009-10-13 23:04:25]</li><li><a href="https://blogread.cn/it/article.php?id=134" target="_blank">基础体验决定上层应用</a> [2009-10-13 23:02:29]</li><li><a href="https://blogread.cn/it/article.php?id=133" target="_blank">有效降低产品门槛</a> [2009-10-13 23:01:31]</li><li><a href="https://blogread.cn/it/article.php?id=132" target="_blank">网络广告互动体验设计</a> [2009-10-13 23:00:53]</li><li><a href="https://blogread.cn/it/article.php?id=131" target="_blank">互联网产品交互事件分析</a> [2009-10-13 22:59:02]</li></ol></p>]]></description>
		<content><![CDATA[这篇文章聚焦于提升交互原型在可用性测试中的真实性，核心论点是用户对原型的信任度直接影响测试数据质量，尤其在金融等高敏感领域。文章指出，当用户察觉原型缺乏真实认证机制时，其行为会偏离真实场景，导致团队收集到无效的测试洞察。针对这一问题，解决方案是重点打造登录环节的交互保真度。

教程以使用ProtoPie构建一个功能完备的银行登录界面为例，逐步演示了关键技术实现：将设计工具中的静态图层转换为可实际输入的文本字段；通过变量实时捕获用户输入；设置条件逻辑以验证特定凭证（如用户名和密码），仅允许正确登录；创建动态的错误状态反馈。此外，教程详细说明了如何集成Lottie动画模拟Face ID生物识别流程，并通过精细的时间轴编排使其体验原生化。

这些步骤共同将一个演示性界面转变为一个行为真实的应用模型。当登录流程可信时，测试就能有效评估用户对错误信息的理解、重试行为以及对替代认证方式的偏好等关键交互细节，从而为产品决策提供高质量的用户信号。]]></content>
	</item>
	<item>
		<title>Cross-Document View Transitions: Scaling Across Hundreds of Elements</title>
		<link>https://blogread.cn/it/article.php?id=8590</link>
		<author>Durgesh Rajubhai Pawar</author>
		<pubDate>2026-06-03 09:03:24</pubDate>
		<category domain="https://blogread.cn/it/category.php?id=7">前端</category>
		<guid>https://blogread.cn/it/article.php?id=8590</guid>
		<comments>https://blogread.cn/it/article.php?id=8590#comment</comments>
		<description><![CDATA[<p><strong>标签：</strong>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=CSS" target="_blank">CSS</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=DOM" target="_blank">DOM</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=JavaScript" target="_blank">JavaScript</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=View%20Transitions" target="_blank">View Transitions</a></p><p>In <a href="https://css-tricks.com/cross-document-view-transitions-part-1/">Part 1</a>, we covered the gotchas that bite you first: the deprecated meta tag that silently does nothing, the 4-second timeout that kills transitions without telling you, the image distortion that turns every aspect ratio change into silly putty, and the <code>pagereveal</code>/<code>pageswap</code> events that give you hooks into the transition lifecycle.</p>



<p>All of that gets you from “nothing works” to “one element transitioning nicely between two pages.” Which feels great. For about five minutes. Then you try to build a product listing page with 48 cards that each need to morph into a detail view, and you realize the tutorials left out the hard part.</p>



<p>This is where it gets real. Let’s scale this thing.</p>







<div class="wp-block-group ticss-ad1a3c1b"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<h4 class="wp-block-heading">Cross-Document View Transitions Series</h4>



<ol class="wp-block-list">
<li><strong><a href="https://css-tricks.com/cross-document-view-transitions-part-1/">The Gotchas Nobody Mentions</a></strong></li>



<li><strong>Scaling View Transitions Across Hundreds of Elements</strong> <em>(You are here!)</em></li>
</ol>
</div></div>



<h3 class="wp-block-heading">The Dream: One Line, Infinite Names</h3>



<p>In a perfect world, you’d solve the scaling problem with pure CSS. No JavaScript. No server-side loops. Just this:</p>



<pre class="blogread-code language-css" data-lang="css"><code class="language-css">.card {
  /* Generates card-1, card-2, card-3, etc. automatically */
  view-transition-name: ident("card-" sibling-index());
}</code></pre>



<p>That’s <a href="https://www.bram.us/2024/12/18/the-future-of-css-construct-custom-idents-and-dashed-idents-with-ident/" rel="noopener"><code>ident()</code></a> — a CSS function <a href="https://github.com/w3c/csswg-drafts/issues/9141" rel="noopener">proposed by Bramus</a> (who works on Chrome) to the CSS Working Group. It takes strings, integers, or other identifiers, concatenates them, and spits out a valid CSS name. Pair it with <code>sibling-index()</code>, which returns an element’s position among its siblings (1, 2, 3…), and you get auto-generated unique names for every element in a list. One rule. Works for 10 cards or 10,000. The CSS doesn’t care.</p>



<p>And it’s not just view transitions. The same pattern works for <code>scroll-timeline-name</code>, <code>container-name</code>, <code>view-timeline-name</code> — anywhere you need unique identifiers at scale. You could even pull names from HTML attributes with <code>attr()</code> instead of <code>sibling-index()</code>, constructing identifiers like <code>ident("--item-" attr(id) "-tl")</code>. The flexibility is real.</p>



<p>Here’s the thing: half of this equation already exists. <code>sibling-index()</code> shipped in Chrome 138 — you can use it today for things like staggered animations and calculated styles. The missing piece is <code>ident()</code>. There’s a <a href="https://chromestatus.com/feature/6230159413477376" rel="noopener">Chrome Intent to Prototype</a> from May 2025, which means it’s on the radar. But “on the radar” and “in your browser” are very different things. No browser ships <code>ident()</code> yet, and there’s no timeline for when it’ll land.</p>



<p>So we can’t use it yet. But it’s worth knowing about because once <code>ident()</code> ships, a huge chunk of the complexity you’re about to see just… evaporates. Until then, here’s how you solve the same problem efficiently today — with the tools that actually exist in browsers right now.</p>



<h2 class="wp-block-heading">100 Products, 100 Names, 1 Nightmare</h2>



<p>Here’s what happens when you follow a tutorial that shows one hero image transitioning between two pages and try to apply that pattern to a grid:</p>



<pre class="blogread-code language-css" data-lang="css"><code class="language-css">/*  THE NIGHTMARE - one rule per item, forever */
::view-transition-group(card-1),
::view-transition-group(card-2),
::view-transition-group(card-3),
::view-transition-group(card-4),
::view-transition-group(card-5),
::view-transition-group(card-6),
::view-transition-group(card-7),
::view-transition-group(card-8)
/* ... imagine 92 more of these */ {

  animation-duration: 0.35s;
  animation-timing-function: ease-out;
}

::view-transition-old(card-1),
::view-transition-old(card-2),
::view-transition-old(card-3)
/* kill me */ {
  object-fit: cover;
}</code></pre>



<p>That’s what you end up with if you follow the tutorials that only show one or two named elements. They assign <code>view-transition-name: hero</code> to one image and call it a day. Cool. Now try building a product grid.</p>



<p>Every <code>view-transition-name</code> on a page must be unique. That’s a hard rule — if two elements share a name, the browser doesn’t know which one maps to which on the next page, so it throws the whole transition out. On a listing page with 48 products, you need 48 unique names. On a photo gallery with 200 thumbnails, you need 200. The names aren’t the problem — you can generate those. The problem is that every pseudo-element selector in your CSS targets a <em>specific name</em>, so your animation styles explode into an unmanageable wall of selectors.</p>



<p>This is where you need to understand the difference between two properties that sound like they do the same thing but absolutely do not.</p>



<h3 class="wp-block-heading">Name vs. Class: The Distinction That Changes Everything</h3>



<p>And yeah, the naming here is confusing. I’ll be honest: the first time I saw <a href="https://css-tricks.com/almanac/properties/v/view-transition-name/"><code>view-transition-name</code></a> and <a href="https://css-tricks.com/almanac/properties/v/view-transition-class/"><code>view-transition-class</code></a> next to each other, I thought they were interchangeable. They’re not, and the difference matters.</p>



<p><strong>Name = identity.</strong> It answers: “Which element on Page A is the <em>same element</em> on Page B?” When you give a thumbnail <code>view-transition-name: card-7</code> on the grid page and give the hero image <code>view-transition-name: card-7</code> on the detail page, you’re telling the browser those are the same thing and to animate between them. Names must be unique per page. Two elements can’t both be <code>card-7</code> or the whole thing breaks.</p>



<p><strong>Class = styling hook.</strong> It answers: “How should the animation <em>look</em>?” When fifty elements all have <code>view-transition-class: card</code>, you can write one CSS rule that controls the duration, easing, and <code>object-fit</code> for all of them. It’s the same mental model as CSS classes on regular elements — <code>.btn</code> doesn’t identify a specific button, it says “style me like a button.”</p>



<p>Think of it like a database. The <code>name</code> is the primary key — unique, identifies one specific row. The <code>class</code> is a category column — groups rows together so you can run a query across all of them at once.</p>



<p>Here’s what that looks like in practice:</p>



<div class="wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper">CodePen Embed Fallback</div>



<p>There it is. Six cards, six unique names, but exactly <em>three</em> CSS rules handling all the animation behavior. Could be sixty cards. Could be six hundred. The CSS doesn’t change.</p>



<p>The key line is that selector: <code>::view-transition-group(*.card)</code>. The asterisk is a wildcard for the name, and <code>.card</code> matches the <code>view-transition-class</code>. It reads as “any view transition group whose element has <code>view-transition-class: card</code>, regardless of what its specific name is.”</p>



<p>For cross-document multi-page application (MPA) transitions, the pattern is the same but you generate the names on the server:</p>



<pre class="blogread-code language-markup" data-lang="markup"><code class="language-markup">&lt;!-- Page A --&gt;
&lt;div class="grid"&gt;

  &lt;!-- ... --&gt;

  &lt;a
    href="/product/42"
    class="card"
    style="view-transition-name: product-42; view-transition-class: card"
  &gt;
    &lt;img src="/images/42-thumb.jpg" alt="Widget" /&gt;
  &lt;/a&gt;
  &lt;a
    href="/product/43"
    class="card"
    style="view-transition-name: product-43; view-transition-class: card"
  &gt;
    &lt;img src="/images/43-thumb.jpg" alt="Gadget" /&gt;
  &lt;/a&gt;
&lt;/div&gt;</code></pre>



<pre class="blogread-code language-markup" data-lang="markup"><code class="language-markup">&lt;!-- Page B --&gt;
&lt;div
  class="product-hero"
  style="view-transition-name: product-42; view-transition-class: card"
&gt;
  &lt;img src="/images/42-hero.jpg" alt="Widget" /&gt;
&lt;/div&gt;</code></pre>



<pre class="blogread-code language-css" data-lang="css"><code class="language-css">/* ONE stylesheet, shared by all pages, handles every product */
@view-transition {
  navigation: auto;
}

::view-transition-group(*.card) {
  animation-duration: 0.35s;
  animation-timing-function: cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

::view-transition-old(*.card),
::view-transition-new(*.card) {
  object-fit: cover;
}</code></pre>



<p>That’s the entire animation stylesheet for a site with thousands of products. Three rules. No matter how many items you have in the database, you never add another line of transition CSS.</p>



<p>Before <code>view-transition-class</code> existed, people were doing horrifying things — looping through items in JavaScript to generate <code>&lt;style&gt;</code> blocks with hundreds of selectors, or using CSS preprocessors to spit out every possible name permutation at build time. It worked, technically, the same way duct-taping a car bumper works technically.</p>



<p><code>view-transition-class</code> is the spec authors acknowledging that the original API just didn’t scale, and fixing it the right way.</p>



<p>One gotcha: <code>view-transition-class</code> was added to the spec later to fix these exact scaling issues. The property landed in Chrome 125 and is now in Chrome, Edge, and Safari 18.2+. Older Chromium versions and Firefox won’t recognize it yet. The transitions will still <em>work</em>, they’ll just use the default fade animation instead of your custom timing. Not the worst fallback.</p>




<baseline-status class="wp-block-css-tricks-baseline-status" featureid="view-transition-class"></baseline-status>



<p>You can also assign multiple classes to a single element, just like regular CSS classes. Something like <code>view-transition-class: card featured</code> is valid, and you can target it with either <code>::view-transition-group(*.card)</code> or <code>::view-transition-group(*.featured)</code>. Handy when you want most products to transition the same way but need a few to stand out with a different animation style.</p>



<h2 class="wp-block-heading">Don’t Name Everything Upfront</h2>



<p>Everything so far has had <code>view-transition-name</code> sitting right there in the HTML or CSS from the moment the page loads. That works. But it has a cost that’s not obvious until you hit real-world scale.</p>



<div class="wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper">CodePen Embed Fallback</div>



<p>Look at the CSS for both pages. Zero <code>view-transition-name</code> declarations. None. Every card in the grid is anonymous until the exact moment the user clicks one.</p>



<p>Here’s why that matters. When you put <code>view-transition-name</code> on an element in your stylesheet — just sitting there in CSS, assigned from page load — you’re telling the browser, “This element participates in every transition that happens on this page.” Every single navigation. The browser has to snapshot it, calculate its position, and set up the pseudo-element tree for it. For one hero image, who cares? For a grid of 48 product cards, that’s 48 elements being individually captured, diffed, and animated when the user only clicked <em>one</em> of them. The other 47 snapshots are pure waste.</p>



<p>On a fast machine you might not notice. On a mid-range Android phone loading a grid of product images over LTE? You’ll feel it. The transition stutters or the browser just skips it entirely because it can’t set everything up fast enough.</p>



<p>The fix is to treat <code>view-transition-name</code> like a just-in-time thing. Assign it at the moment of interaction, not at page load.</p>



<p>The lifecycle goes like this:</p>



<ol class="wp-block-list">
<li>User clicks a card on the listing page.</li>



<li>Browser starts navigating — <code>pageswap</code> fires on the old page.</li>



<li>Your <code>pageswap</code> handler looks at <code>event.activation.entry.url</code> to figure out <em>where</em> the user is going, finds the clicked card, slaps <code>view-transition-name: product-42</code> on it.</li>



<li>Browser snapshots that one named element (plus the default <code>root</code> transition).</li>



<li>Navigation happens, new page loads.</li>



<li><code>pagereveal</code> fires on the incoming page.</li>



<li>Your <code>pagereveal</code> handler reads the URL, finds the hero element, assigns the matching <code>view-transition-name: product-42</code>.</li>



<li>Browser sees matching names on old and new snapshots — morphs between them.</li>



<li>Transition finishes, your <code>.finished</code> promise resolves, you clear the names.</li>
</ol>



<p>That’s it. One element named, one element transitioned, zero waste.</p>



<p>The <code>event.activation</code> object is your best friend here. On the outgoing page, <code>event.activation.entry.url</code> tells you where the navigation is headed. On the incoming page, you just read <code>window.location</code>. Between the two, you have everything you need to figure out which element to name without any global state, no <code>sessionStorage</code> tricks, no query parameter gymnastics beyond what your app already uses.</p>



<p>And about that cleanup step, removing the name after <code>.finished</code> resolves? It’s not just tidiness. If the user navigates back to the listing page and clicks a <em>different</em> card, you don’t want the old card still carrying a name from the previous transition. Stale names cause duplicate-name conflicts (instant transition death) or wrong-element matching (the new page morphs from the wrong card). Clean up after yourself.</p>



<p>This pattern is basically what <a href="https://docs.astro.build/en/guides/view-transitions/#naming-a-transition" rel="noopener">Astro’s <code>transition:name</code></a> directive does under the hood. Same with <a href="https://nuxt.com/docs/3.x/getting-started/transitions" rel="noopener">Nuxt’s view transition support</a>. They dynamically assign and remove names around the navigation lifecycle. The frameworks just hide the <code>pageswap</code>/<code>pagereveal</code> wiring behind a component attribute. You’re doing the same thing, just without the abstraction layer. Fewer moving parts, same result.</p>



<h3 class="wp-block-heading">Practical Patterns for Real Content</h3>



<p>The product grid example covers the most common case, but let’s run through a couple of other patterns you’ll hit in the wild.</p>



<h4 class="wp-block-heading">Photo Galleries with Mixed Aspect Ratios</h4>



<p>Galleries are tricky because every thumbnail might have a different aspect ratio, and the full-size view definitely will. The taffy fix from the Part 1 article is essential here, but you also want the transition to feel intentional rather than chaotic.</p>



<pre class="blogread-code language-css" data-lang="css"><code class="language-css">/* Gallery items get their own class for targeted animation */
::view-transition-group(*.gallery-item) {
  animation-duration: 0.5s;
  animation-timing-function: cubic-bezier(0.2, 0, 0, 1);
}

::view-transition-old(*.gallery-item),
::view-transition-new(*.gallery-item) {
  object-fit: cover;
  overflow: hidden;
}

/* Lightbox-style overlay - fade the background separately */
::view-transition-group(*.lightbox-bg) {
  animation-duration: 0.3s;
}</code></pre>



<p>The trick with galleries is assigning the <code>view-transition-name</code> to the <code>&lt;img&gt;</code> itself rather than the surrounding card or container. You want the browser to morph the image from thumbnail size to lightbox size, not the card’s background, padding, and caption along with it. Name the image. Style the card. Keep them separate.</p>



<p>For the lightbox background (that dark overlay), give it its own <code>view-transition-name</code> and <code>view-transition-class</code>. It’ll fade in independently while the image morphs. Two transitions running in parallel, each with their own timing. Looks polished, and it’s just two names.</p>



<h4 class="wp-block-heading">Tab or Section Transitions Within a Page</h4>



<p>Not everything is a grid-to-detail pattern. Sometimes you’re transitioning between sections on the same page, e.g., dashboard tabs, multi-step forms, content panels. Same-document view transitions work great here, and the <code>view-transition-class</code> approach scales the same way.</p>



<pre class="blogread-code language-css" data-lang="css"><code class="language-css">/* Shared header that persists across tabs */
::view-transition-group(*.persistent) {
  animation-duration: 0s; /* don't animate - it should feel anchored */
}

/* Tab content that swaps */
::view-transition-group(*.tab-content) {
  animation-duration: 0.25s;
}

::view-transition-old(*.tab-content) {
  animation: slide-out-left 0.25s ease-in;
}

::view-transition-new(*.tab-content) {
  animation: slide-in-right 0.25s ease-out;
}

@keyframes slide-out-left {
  to {
    transform: translateX(-100%);
    opacity: 0;
  }
}

@keyframes slide-in-right {
  from {
    transform: translateX(100%);
    opacity: 0;
  }
}</code></pre>



<p>The <code>animation-duration: 0s</code> on persistent elements is worth calling out. If your site header has a <code>view-transition-name</code> (so it stays in place instead of participating in the default root cross-fade), you probably don’t want it animating at all. Zero-duration makes it snap to its new position instantly, which feels like it never moved. That’s the point — stable landmarks make the transitioning content feel grounded.</p>



<h4 class="wp-block-heading">Dynamic Content and Infinite Scroll</h4>



<p>Here’s a pattern that catches people off guard. You’ve got a product grid with infinite scroll, loading new items as the user scrolls down. Each new batch arrives via <code>fetch()</code> and gets appended to the DOM. Do those new items need <code>view-transition-name</code>?</p>



<p>No. Not until someone clicks one.</p>



<p>With the just-in-time pattern, it doesn’t matter whether an element existed at page load or was added dynamically five minutes later. The <code>pageswap</code> handler queries the DOM at the moment of navigation. If the element is there, it finds it, names it, done. Your infinite scroll items work identically to your initial page load items without any extra setup.</p>



<p>The one thing to watch out for: make sure your <code>data-id</code> attributes (or whatever you’re using to match elements) are unique across all loaded batches. If your API returns items with IDs and you’re using those for the <code>view-transition-name</code>, you’re already fine. If you’re generating IDs client-side, make sure they don’t collide when new batches load.</p>



<h3 class="wp-block-heading">Don’t Make People Sick</h3>



<pre class="blogread-code language-css" data-lang="css"><code class="language-css">/* The responsible way to set up view transitions */
@view-transition {
  navigation: auto;
}

/* All your animation customizations go INSIDE this media query */
@media (prefers-reduced-motion: no-preference) {
  ::view-transition-group(*.card) {
    animation-duration: 0.35s;
    animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  }

  ::view-transition-old(*.card),
  ::view-transition-new(*.card) {
    object-fit: cover;
  }

  /* Custom keyframes, staggered delays, the fun stuff - all in here */
  ::view-transition-old(root) {
    animation: fade-out 0.2s ease-in;
  }

  ::view-transition-new(root) {
    animation: fade-in 0.3s ease-out;
  }
}

/* If the user HAS requested reduced motion: instant cut, no animation */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation-duration: 0s !important;
  }
}

@keyframes fade-out {
  to {
    opacity: 0;
  }
}

@keyframes fade-in {
  from {
    opacity: 0;
  }
}</code></pre>



<p>This isn’t a nice-to-have. I need to be blunt about that.</p>



<p>People with vestibular disorders — and there are a lot more of them than most developers realize — can get physically nauseous from unexpected motion on screen. Not “mildly annoyed.” Nauseous. Dizzy. Migraines that last hours. The <a href="https://css-tricks.com/almanac/rules/m/media/prefers-reduced-motion/"><code>prefers-reduced-motion</code></a> media query exists because real people checked a box in their OS settings that says “please stop making me sick.” Ignoring it is the accessibility equivalent of removing a wheelchair ramp because stairs look cleaner.</p>



<p>The <a href="https://css-tricks.com/almanac/rules/v/view-transition/"><code>@view-transition</code></a> opt-in can stay outside the media query. That’s fine, it just tells the browser, “I want cross-document transitions enabled.” The browser will still do an instant cut between pages, which is visually identical to a normal navigation. It’s the animation customizations that need to be gated: the durations, the easing curves, the custom keyframes. Wrap all of that in <code>prefers-reduced-motion: no-preference</code> and you’re covered.</p>



<p>That <code>prefers-reduced-motion: reduce</code> block at the bottom is a belt-and-suspenders thing. Even if you miss wrapping some animation rule, forcing <code>animation-duration: 0s</code> on all the transition pseudo-elements ensures nothing actually moves. <a href="https://css-tricks.com/alternatives-to-the-important-keyword/#when-using-important-does-make-sense">The <code>!important</code> is ugly but justified here.</a> you genuinely want this to override everything, no exceptions.</p>



<p>You already saw the conditional opt-in pattern back in Part 1:</p>



<pre class="blogread-code language-css" data-lang="css"><code class="language-css">/* You can also just disable transitions entirely for reduced-motion users */
@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
  }
}</code></pre>



<p>Either approach works. Wrapping the whole <code>@view-transition</code> rule means the browser won’t even attempt the transition – it’s a normal navigation, full stop. Keeping <code>@view-transition</code> active but killing the animation durations means the transition technically fires but completes instantly, which can matter if you have <code>pagereveal</code> logic that depends on <code>event.viewTransition</code> existing. Pick whichever fits your setup. Just don’t ship animated transitions without checking.</p>



<p>A thing worth considering here: <a href="https://css-tricks.com/nuking-motion-with-prefers-reduced-motion/">“reduced motion” doesn’t necessarily mean “no motion.”</a> Some users with vestibular sensitivities are fine with fades but not with sliding or zooming. You could offer a gentler alternative instead of killing all animation entirely.</p>



<pre class="blogread-code language-css" data-lang="css"><code class="language-css">@media (prefers-reduced-motion: reduce) {
  /* Instead of zero duration, use a quick crossfade only */
  ::view-transition-group(*) {
    animation-duration: 0.15s !important;
    animation-timing-function: linear !important;
  }

  ::view-transition-old(*) {
    animation: fade-out 0.15s linear !important;
  }

  ::view-transition-new(*) {
    animation: fade-in 0.15s linear !important;
  }
}</code></pre>



<p>This is a judgment call. A fast, subtle cross-fade is less likely to trigger symptoms than a <code>400ms</code> morphing animation with easing curves. But the safest option is always zero motion, and if you’re not sure, go with <code>animation-duration: 0s</code>. You can always add a gentler alternative later once you’ve tested it with actual users who rely on the setting.</p>



<h3 class="wp-block-heading">Handle Old Browsers (By Doing Basically Nothing)</h3>



<pre class="blogread-code language-css" data-lang="css"><code class="language-css">/* Feature detection, if you need it */
@supports (view-transition-name: none) {
  .card {
    /* maybe you want contain: paint for better snapshotting */
    contain: paint;
  }
}</code></pre>



<pre class="blogread-code language-javascript" data-lang="javascript"><code class="language-javascript">// JS-side feature detection
if (document.startViewTransition) {
  // same-document transition API exists
}

// For cross-document transitions, there's no direct JS check -
// the browser either supports @view-transition in CSS or ignores it.
// That's... actually fine.</code></pre>



<p>Here’s the thing though: you probably don’t even need that <code>@supports</code> check.</p>



<p>View transitions are progressive enhancement in the purest sense of the term. If a browser doesn’t understand <code>@view-transition { navigation: auto; }</code>, it ignores the rule. That’s how CSS works. The user clicks a link, the browser navigates normally, the new page loads. No animation, no morphing, no cross-fade. Just a regular page load. Which is exactly what every website on the internet did for the first 25 years of the web. It’s fine.</p>



<p>Nothing breaks. No JavaScript errors. No layout shifts. No fallback code to write. The <code>view-transition-name</code> properties get ignored. The <code>::view-transition-*</code> pseudo-element selectors match nothing. Your <code>pageswap</code> and <code>pagereveal</code> event listeners either don’t fire or <code>event.viewTransition</code> is <code>null</code> and your guard clause returns early. The whole feature is designed to be invisible when it’s absent.</p>



<p>That’s the beauty of this API, honestly. It’s one of the rare web platform features where you don’t have to write a single line of fallback code. Firefox doesn’t support it yet? Fine — Firefox users get normal navigation. Safari’s working on it but hasn’t shipped? Cool, Safari users click links and pages load. Nobody gets an error. Nobody gets a broken layout. Nobody loses anything. They just don’t get the fancy animation, and most of them will never notice it was supposed to be there.</p>



<p>Worth noting where things actually stand today: Chrome and Edge have full support for cross-document view transitions, including view-transition-class. Safari also ships full cross-document support as of Safari 18.2. The momentum is clearly toward universal support, even though Firefox still holds it behind a flag for now.</p>



<p>The only time <code>@supports</code> matters is if you’re adding styles that <em>only</em> make sense in the context of view transitions — like <code>contain: paint</code> on elements to improve snapshot quality, or hiding some loading state that the transition would normally cover. Gate those behind <code>@supports (view-transition-name: none)</code> so non-supporting browsers don’t get the side effects without the payoff.</p>



<p>Failure is invisible. That’s the whole point.</p>



<h3 class="wp-block-heading">Ship It</h3>



<p>Look, I’ve been building websites for a long time, and there’s always been this unspoken trade-off: you want smooth, app-like transitions, you adopt a framework and a client-side router and a build step and a hydration strategy and suddenly you’re maintaining a small aircraft carrier just so a card can animate into a hero image.</p>



<p>That trade-off is dissolving.</p>



<p>Cross-document view transitions let an <code>&lt;a href&gt;</code> feel like a native app navigation. Two HTML files. Some CSS. Maybe a little JavaScript for the fancy stuff. The browser does the rest. That’s not a small thing – it changes which projects <em>need</em> a framework and which ones just <em>assumed</em> they did.</p>



<p>The spec is young. It’s Chromium-only right now. The rough edges are real – you’ve seen them across both parts of this series. But the API is designed so well that when it’s not supported, nothing breaks. Your site just works the way sites have always worked. And when it <em>is</em> supported, it feels like magic that came free.</p>



<p>Here’s a quick cheat sheet to take with you:</p>



<ul class="wp-block-list">
<li><strong>Opt in with CSS</strong>, not the deprecated meta tag: <code>@view-transition { navigation: auto; }</code>.</li>



<li><strong>Both pages</strong> must opt in or no transition happens.</li>



<li><strong>4-second timeout</strong> starts at navigation, not at render – use <code>pagereveal</code> to catch <code>TimeoutError</code>.</li>



<li><strong>Images stretch</strong> during transitions because pseudo-elements default to <code>object-fit: fill</code> – fix it with <code>object-fit: cover</code> on <code>::view-transition-old</code> and <code>::view-transition-new</code>.</li>



<li><strong><code>view-transition-name</code></strong> = identity (unique per page), <strong><code>view-transition-class</code></strong> = styling hook (shared across elements).</li>



<li><strong>Don’t name elements upfront</strong> – use <code>pageswap</code> and <code>pagereveal</code> to assign names just-in-time. But keep your <code>pageswap</code> logic fast — the browser gives you a narrow window (10-50ms) before snapshots.</li>



<li><strong>Clean up names</strong> after <code>viewTransition.finished</code> resolves to avoid stale conflicts.</li>



<li><strong>Gate animations</strong> behind <code>prefers-reduced-motion: no-preference</code> — this is not optional.</li>



<li><strong>Progressive enhancement</strong> is built in — unsupported browsers just get normal page loads</li>
</ul>



<p>The best animations are the ones you don’t have to maintain a framework to get.</p>



<div class="wp-block-group ticss-ad1a3c1b"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<h4 class="wp-block-heading">Cross-Document View Transitions Series</h4>



<ol class="wp-block-list">
<li><strong><a href="https://css-tricks.com/cross-document-view-transitions-part-1/">The Gotchas Nobody Mentions</a></strong></li>



<li><strong>Scaling View Transitions Across Hundreds of Elements</strong> <em>(You are here!)</em></li>
</ol>
</div></div>
<hr>
<p><small><a rel="nofollow" href="https://css-tricks.com/cross-document-view-transitions-part-2/">Cross-Document View Transitions: Scaling Across Hundreds of Elements</a> originally handwritten and published with love on <a rel="nofollow" href="https://css-tricks.com/">CSS-Tricks</a>. You should really <a href="https://css-tricks.com/newsletters/">get the newsletter</a> as well.</small></p>
				<p><strong>您可能还对下面的文章感兴趣：</strong></p>
				<p><ol><li><a href="https://blogread.cn/it/article.php?id=8558" target="_blank">Cross-Document View Transitions: The Gotchas Nobody Mentions</a> [2026-06-03 09:03:24]</li></ol></p>]]></description>
		<content><![CDATA[跨文档视图转换（Cross-Document View Transitions）在从简单示例扩展到包含数百个元素的实际产品页面时，面临显著挑战。核心难题在于每个视图转换名称必须唯一，导致为每个元素单独编写动画样式的CSS规则呈爆炸式增长，难以维护。文章探讨了两种高效解决方案。其一是利用`view-transition-class`属性为同类元素分组，配合通配符选择器（如`::view-transition-group(*.card)`）用寥寥数行CSS统一控制所有同类元素的动画，无论数量多少。其二是采用“按需分配”策略，不在页面加载时为所有元素预设名称，而是通过`pageswap`和`pagereveal`事件，在用户交互（如点击）的精确时刻为涉及的元素动态添加与移除视图转换名称。这种方式避免了浏览器为未参与过渡的数十个元素进行无用快照和计算，显著提升了中低端设备上的性能。文章还提及了一个理想的纯CSS方案（使用`ident()`函数），但指出其尚未被浏览器支持，因此上述基于现有标准的模式是当前实现规模化过渡的实用路径。]]></content>
	</item>
	<item>
		<title>1分钟速度了解text-align match-parent声明</title>
		<link>https://blogread.cn/it/article.php?id=8589</link>
		<author>张 鑫旭</author>
		<pubDate>2026-06-03 09:03:24</pubDate>
		<category domain="https://blogread.cn/it/category.php?id=7">前端</category>
		<guid>https://blogread.cn/it/article.php?id=8589</guid>
		<comments>https://blogread.cn/it/article.php?id=8589#comment</comments>
		<description><![CDATA[<p><strong>标签：</strong>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=CSS" target="_blank">CSS</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=match-parent" target="_blank">match-parent</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=text-align" target="_blank">text-align</a></p><p>by <a href="https://www.zhangxinxu.com/">zhangxinxu</a> from <a href="https://www.zhangxinxu.com/wordpress/?p=12196">https://www.zhangxinxu.com/wordpress/?p=12196</a><br>
本文可全文转载，但需要保留原作者、出处以及文中链接，AI抓取保留原文地址，任何网站均可摘要聚合，商用请联系授权。</p>
<h3>一、直接进入正题</h3>
<p><code>text-align:match-parent</code>声明的作用就是使用和父元素一样的对齐方式。</p>
<p>可仔细一想，这个属性值就很奇怪，<code>text-align</code>本身就具有继承特性，为何还要多此一举设计一个<code>match-parent</code>呢？</p>
<p>因为现实开发中存在一个极为罕见的使用场景。</p>
<p>且看案例：</p>
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">&lt;div class="box"&gt;
  &lt;p id="p"&gt;我的对齐是？&lt;/p&gt;
&lt;/div&gt;</code></pre>
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">.box {
  text-align: end;
}</code></pre>
<p>此时，如果我们想要得知<code>&lt;p&gt;</code>元素的textAlign计算值，得到的结果会是 <code>end</code>。</p>
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">console.log(getComputedStyle(p).textAlign);
// 结果是 'end'</code></pre>
<p><code>end</code>? any problem?</p>
<p>这不很正常吗，不是理所当然的吗？</p>
<p>非也非也!</p>
<p>比方说下图所示的对称布局：</p>
<p><img fetchpriority="high" decoding="async" src="https://image.zhangxinxu.com/image/blog/202605/2026-5-25_160256.png" width="478" height="324" alt="对称布局示意" class="alignnone size-medium"></p>
<p>最简单高效的实现就是使用CSS逻辑属性，外加direction属性控制方向。</p>
<p><code>text-align:end</code>就是逻辑属性。</p>
<p>下面问题来了，我们我希望知道布局列表中的元素是左对齐还是右对齐，会发现运行<code>getComputedStyle(p).textAlign</code>这行代码是无效的。</p>
<p>因为无论哪个方位，返回的都是<code>end</code>，而不是<code>left</code>或者<code>right</code>。</p>
<p>正是由于这样的场景存在，于是设计了<code>match-parent</code>。</p>
<p>比方说，我们把上面的CSS代码换成：</p>
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">.box {
  text-align: end;
  p {
    text-align: -webkit-match-parent;
    text-align: match-parent;
  }
}</code></pre>
<p>此时，默认情况下，<code>&lt;p&gt;</code>元素的textAlign计算值就是<code>right</code>.</p>
<pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">console.log(getComputedStyle(p).textAlign);
// 结果是 'right'</code></pre>
<p>如果此时<code>&lt;p&gt;</code>元素的上下文处于 <code>direction: rtl</code> 环境中，那么返回的textAlign计算值则回是 <code>left</code>。</p>
<p>这就是<code>text-align:match-parent</code>声明的唯一作用，可以返回当前元素精确对齐方向left/right，而不是含糊其辞的start/end。</p>
<hr>
<h3>二、注定很少使用的特性</h3>
<p><code>direction</code>属性本身就很少使用，毕竟属于CSS布局高级技巧。</p>
<p>加上需要获取<code>textAlign</code>计算值的场景本身就很小众。</p>
<p>所以，在实际生产环境需要用到<code>match-parent</code>的概率近乎是0.</p>
<p>可以说就是一个玩具特性，大家了解下有这么个东西就好了。</p>
<p>最后看下其兼容性，出乎意料，虽然作用鸡肋，但是兼容性却出奇的好，全都支持，就是Chrome浏览器还需要加<code>-webkit-</code>私有前缀。</p>
<p><img decoding="async" src="https://image.zhangxinxu.com/image/blog/202605/2026-5-25_161221.png" width="646" height="256" alt="text-align: match-parent兼容性" class="alignnone size-medium"></p>
<p><strong>装逼作用</strong></p>
<p>如果抛开<code>match-parent</code>原本的作用，我们不是不可以在生产环境使用，不如这样，所有需要使用 <code>text-align:inherit</code> 代码的地方，全部替换成 <code>text-align:match-parent</code>，虽然渲染效果是一样的，但是装逼效果天差地别，同事一看你写的代码，顿时高山仰止，“望其项背”，爽！</p>
<p><img decoding="async" src="https://image.zhangxinxu.com/image/blog/202605/2026-5-25_161725.webp" width="149" height="143" alt="爽表情包" class="alignnone size-medium"></p>
<p>本文为原创文章，会经常更新知识点以及修正一些错误，因此转载请保留原出处，方便溯源，避免陈旧错误知识的误导，同时有更好的阅读体验。<br>
本文地址：<a href="https://www.zhangxinxu.com/wordpress/?p=12196">https://www.zhangxinxu.com/wordpress/?p=12196</a></p>
<p>（本篇完）</p>
				<p><strong>您可能还对下面的文章感兴趣：</strong></p>
				<p><ol><li><a href="https://blogread.cn/it/article.php?id=8597" target="_blank">新特性速递：focus()行为新增focusVisible控制</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8594" target="_blank">Revealing Text With CSS letter-spacing</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8590" target="_blank">Cross-Document View Transitions: Scaling Across Hundreds of Elements</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8570" target="_blank">光标的形状也能设置了，就是CSS caret-shape属性</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8569" target="_blank">Fixed-Height Cards: More Fragile Than They Look</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8568" target="_blank">Making Zigzag CSS Layouts With a Grid + Transform Trick</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8567" target="_blank">A Scrollytelling Gift for Mum on Mother’s Day 2026</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8566" target="_blank">Using CSS corner-shape For Folded Corners</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8564" target="_blank">rotate()</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8563" target="_blank">rotateZ()</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8562" target="_blank">rotateY()</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8561" target="_blank">rotateX()</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8560" target="_blank">Computing and Displaying Discounted Prices in CSS</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8559" target="_blank">What’s !important #11: 3D Voxel Scenes, Flying Focus, CSS Syntaxes, and More</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8558" target="_blank">Cross-Document View Transitions: The Gotchas Nobody Mentions</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8556" target="_blank">The State of CSS Centering in 2026</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8555" target="_blank">Smashing Animations Part 8: Theming Animations Using CSS Relative Colour</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8554" target="_blank">Rethinking “Pixel Perfect” Web Design</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8553" target="_blank">Unstacking CSS Stacking Contexts</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8550" target="_blank">CSS @scope: An Alternative To Naming Conventions And Heavy Abstractions</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8509" target="_blank">CSS corner-shape与背景底纹技术</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8445" target="_blank">CSS field-sizing属性简介</a> [2026-06-03 09:03:23]</li><li><a href="https://blogread.cn/it/article.php?id=8444" target="_blank">CSS reading-flow和reading-order属性简介</a> [2026-06-03 09:03:23]</li><li><a href="https://blogread.cn/it/article.php?id=8443" target="_blank">CSS锚点定位实战-鼠标跟随交互效果</a> [2026-06-03 09:03:23]</li><li><a href="https://blogread.cn/it/article.php?id=8404" target="_blank">TailwindCSS v4 全新颜色系统与主题切换</a> [2026-06-03 09:03:23]</li><li><a href="https://blogread.cn/it/article.php?id=8380" target="_blank">CSS 中的标点悬挂及其现状</a> [2026-05-17 14:50:00]</li><li><a href="https://blogread.cn/it/article.php?id=8375" target="_blank">如何使用CSS判断鼠标从哪个方向进入元素？</a> [2026-05-07 14:28:05]</li><li><a href="https://blogread.cn/it/article.php?id=8115" target="_blank">降低样式计算的范围和复杂度</a> [2016-12-22 23:17:28]</li><li><a href="https://blogread.cn/it/article.php?id=8102" target="_blank">在公众号中优雅地呈现代码</a> [2016-07-17 23:55:04]</li><li><a href="https://blogread.cn/it/article.php?id=8099" target="_blank">谈谈我这三年在技术上的成长</a> [2016-07-11 23:33:33]</li><li><a href="https://blogread.cn/it/article.php?id=8081" target="_blank">一个 GUI 系统的组成部分</a> [2016-05-12 12:52:32]</li><li><a href="https://blogread.cn/it/article.php?id=8020" target="_blank">好用的CSS模块化打包工具CSS-Combo</a> [2016-04-02 13:18:32]</li><li><a href="https://blogread.cn/it/article.php?id=8006" target="_blank">CSS Gradient详解</a> [2016-03-30 13:59:30]</li><li><a href="https://blogread.cn/it/article.php?id=7993" target="_blank">网页布局中对全局字体的最佳控制</a> [2016-03-23 17:52:22]</li><li><a href="https://blogread.cn/it/article.php?id=7989" target="_blank">我是如何从装修转到前端</a> [2016-03-23 17:01:39]</li><li><a href="https://blogread.cn/it/article.php?id=7987" target="_blank">滚动定位在移动端的研究</a> [2016-03-23 15:39:08]</li><li><a href="https://blogread.cn/it/article.php?id=7909" target="_blank">给HTML初学者的30条最佳实践</a> [2016-03-17 00:02:35]</li><li><a href="https://blogread.cn/it/article.php?id=7904" target="_blank">12个很少被人知道的CSS事实</a> [2016-03-16 00:00:20]</li><li><a href="https://blogread.cn/it/article.php?id=7892" target="_blank">使用 Sass (Using Sass)-插件，缓存，配置选项，语法选择及编码格式</a> [2016-03-15 22:35:29]</li><li><a href="https://blogread.cn/it/article.php?id=7891" target="_blank">用CSS代码写出的各种形状图形的方法</a> [2016-03-14 23:59:22]</li><li><a href="https://blogread.cn/it/article.php?id=7860" target="_blank">浅析line-height和vertical</a> [2016-03-09 12:58:41]</li><li><a href="https://blogread.cn/it/article.php?id=7854" target="_blank">《web前端最佳实践》—高维护性css</a> [2016-03-07 23:49:07]</li><li><a href="https://blogread.cn/it/article.php?id=7853" target="_blank">《web前端最佳实践》—高性能css</a> [2016-03-07 23:48:37]</li><li><a href="https://blogread.cn/it/article.php?id=7852" target="_blank">图片以及其他替换元素的空隙问题</a> [2016-03-07 23:48:02]</li><li><a href="https://blogread.cn/it/article.php?id=7839" target="_blank">前端编码规范（4）—— CSS 和 Sass (SCSS) 规范</a> [2016-03-02 23:54:42]</li><li><a href="https://blogread.cn/it/article.php?id=7831" target="_blank">小叙透明</a> [2016-03-01 23:53:24]</li><li><a href="https://blogread.cn/it/article.php?id=7798" target="_blank">小谈inline-block的那点空隙</a> [2016-02-21 22:44:07]</li><li><a href="https://blogread.cn/it/article.php?id=7787" target="_blank">小tip:中文或英文左右padding一致两端对齐实现</a> [2016-02-20 14:27:39]</li><li><a href="https://blogread.cn/it/article.php?id=7777" target="_blank">margin那些事儿</a> [2016-02-20 11:38:02]</li><li><a href="https://blogread.cn/it/article.php?id=7772" target="_blank">z-index和zoom这哥俩</a> [2016-02-18 23:53:30]</li><li><a href="https://blogread.cn/it/article.php?id=7767" target="_blank">-webkit-margin-start 属性</a> [2016-02-16 22:21:04]</li><li><a href="https://blogread.cn/it/article.php?id=7762" target="_blank">你不该忽视的小问题之margin叠加篇</a> [2016-02-16 22:07:59]</li><li><a href="https://blogread.cn/it/article.php?id=7761" target="_blank">IE7浏览器下CSS属性选择器二三事</a> [2016-02-16 21:19:34]</li><li><a href="https://blogread.cn/it/article.php?id=7757" target="_blank">视觉调整－设计师 vs. 逻辑</a> [2016-02-16 21:08:14]</li><li><a href="https://blogread.cn/it/article.php?id=7745" target="_blank">CSS 样式规则的匹配算法实现</a> [2016-02-16 20:38:37]</li><li><a href="https://blogread.cn/it/article.php?id=7735" target="_blank">CSS1-CSS3 &lt;color&gt;颜色知识知多少？</a> [2016-02-13 23:56:30]</li><li><a href="https://blogread.cn/it/article.php?id=7732" target="_blank">轻松入门css3之border-image</a> [2016-02-13 23:41:05]</li><li><a href="https://blogread.cn/it/article.php?id=7729" target="_blank">解读CSS布局之-水平垂直居中</a> [2016-02-13 23:11:47]</li><li><a href="https://blogread.cn/it/article.php?id=7728" target="_blank">再谈怎样更好的写css</a> [2016-02-13 23:08:49]</li><li><a href="https://blogread.cn/it/article.php?id=7727" target="_blank">初谈怎样更好的去规划CSS</a> [2016-02-13 23:06:48]</li><li><a href="https://blogread.cn/it/article.php?id=7726" target="_blank">导航类“不定宽水平居中”的几种思路</a> [2016-02-13 23:05:39]</li><li><a href="https://blogread.cn/it/article.php?id=7719" target="_blank">移动端自适应方案</a> [2016-02-12 17:53:12]</li><li><a href="https://blogread.cn/it/article.php?id=7709" target="_blank">了解CSS中的@ AT规则</a> [2016-02-11 23:07:39]</li><li><a href="https://blogread.cn/it/article.php?id=7687" target="_blank">JavaScript初体验 </a> [2016-02-11 14:54:11]</li><li><a href="https://blogread.cn/it/article.php?id=7656" target="_blank">说说基本的布局观</a> [2016-02-07 14:48:29]</li><li><a href="https://blogread.cn/it/article.php?id=7646" target="_blank">小tips: zoom和transform:scale的区别</a> [2016-02-07 14:14:34]</li><li><a href="https://blogread.cn/it/article.php?id=7644" target="_blank">word-break:break-all和word-wrap:break-word的区别</a> [2016-02-07 14:09:54]</li><li><a href="https://blogread.cn/it/article.php?id=7642" target="_blank">小tips: CSS或JS实现gif动态图片的停止与播放</a> [2016-02-07 14:06:53]</li><li><a href="https://blogread.cn/it/article.php?id=7632" target="_blank">小tip: 如何让contenteditable元素只能输入纯文本</a> [2016-02-06 23:30:38]</li><li><a href="https://blogread.cn/it/article.php?id=7627" target="_blank">深入理解CSS中的层叠上下文和层叠顺序</a> [2016-02-06 13:53:11]</li><li><a href="https://blogread.cn/it/article.php?id=7611" target="_blank">CSS font关键字属性值的简单研究</a> [2016-01-27 22:35:05]</li><li><a href="https://blogread.cn/it/article.php?id=7606" target="_blank">基于原生HTML的UI组件开发</a> [2016-01-26 23:53:04]</li><li><a href="https://blogread.cn/it/article.php?id=7589" target="_blank">CSS中的margin外边距折叠现象</a> [2015-11-08 22:19:49]</li><li><a href="https://blogread.cn/it/article.php?id=7575" target="_blank">用CSS绘制各种角度的三角形</a> [2015-11-08 21:50:23]</li><li><a href="https://blogread.cn/it/article.php?id=7562" target="_blank">写 CSS 时要避免的几个地方</a> [2015-11-02 22:37:03]</li><li><a href="https://blogread.cn/it/article.php?id=7528" target="_blank">CSS深入理解vertical-align和line-height的基友关系</a> [2015-09-04 21:40:50]</li><li><a href="https://blogread.cn/it/article.php?id=7512" target="_blank">-webkit-border-radius圆角属性</a> [2015-07-21 23:36:13]</li><li><a href="https://blogread.cn/it/article.php?id=7506" target="_blank">使用yuicompressor.jar实现对js、css文件的代码压缩</a> [2015-06-04 10:25:43]</li><li><a href="https://blogread.cn/it/article.php?id=7501" target="_blank">小tip: 了解CSS text-decoration新特性新表现</a> [2015-06-04 09:49:32]</li><li><a href="https://blogread.cn/it/article.php?id=7481" target="_blank">HTML页面布局基础</a> [2015-06-01 09:56:42]</li><li><a href="https://blogread.cn/it/article.php?id=7474" target="_blank">iframe大小自适应</a> [2015-05-29 20:10:08]</li><li><a href="https://blogread.cn/it/article.php?id=7473" target="_blank">BFC(Block formatting contexts)初探</a> [2015-05-29 20:09:14]</li><li><a href="https://blogread.cn/it/article.php?id=7452" target="_blank">小tip: 纯CSS实现视差滚动效果</a> [2015-04-26 22:57:26]</li><li><a href="https://blogread.cn/it/article.php?id=7408" target="_blank">CSS中height:100%和height:inherit的异同</a> [2015-02-26 22:30:04]</li><li><a href="https://blogread.cn/it/article.php?id=7384" target="_blank">CSS深入理解流体特性和BFC特性下多栏自适应布局</a> [2015-02-14 14:05:14]</li><li><a href="https://blogread.cn/it/article.php?id=7382" target="_blank">table-cell的手机应用场景</a> [2015-02-08 23:30:56]</li><li><a href="https://blogread.cn/it/article.php?id=7377" target="_blank">小tip:纯CSS让overflow:auto页面滚动条出现时不跳动</a> [2015-02-06 22:16:24]</li><li><a href="https://blogread.cn/it/article.php?id=7366" target="_blank">小tip:CSS计数器+伪类实现数值动态计算与呈现</a> [2015-02-03 22:17:55]</li><li><a href="https://blogread.cn/it/article.php?id=7358" target="_blank">table-cell的手机应用场景</a> [2015-02-03 21:53:10]</li><li><a href="https://blogread.cn/it/article.php?id=7349" target="_blank">小tips: 使用等空格实现最小成本中文对齐</a> [2015-01-27 22:26:42]</li><li><a href="https://blogread.cn/it/article.php?id=7339" target="_blank">再说iconfont和font-face</a> [2015-01-24 23:46:35]</li><li><a href="https://blogread.cn/it/article.php?id=7334" target="_blank">网页字体排印指南</a> [2015-01-24 23:38:58]</li><li><a href="https://blogread.cn/it/article.php?id=7313" target="_blank">10条影响CSS渲染速度的写法与建议</a> [2015-01-22 23:29:37]</li><li><a href="https://blogread.cn/it/article.php?id=7309" target="_blank">高效jQuery的奥秘</a> [2015-01-21 23:46:20]</li><li><a href="https://blogread.cn/it/article.php?id=7304" target="_blank">重温CSS：Border属性</a> [2015-01-21 23:42:04]</li><li><a href="https://blogread.cn/it/article.php?id=7272" target="_blank">解决IOS点击链接触发的颜色块</a> [2015-01-17 00:07:51]</li><li><a href="https://blogread.cn/it/article.php?id=7265" target="_blank">函数式 CSS</a> [2015-01-14 13:38:23]</li><li><a href="https://blogread.cn/it/article.php?id=7259" target="_blank">引入css外部样式表</a> [2015-01-13 22:56:38]</li><li><a href="https://blogread.cn/it/article.php?id=7257" target="_blank">关于webapp中的文字单位的一些捣腾</a> [2015-01-12 22:54:34]</li><li><a href="https://blogread.cn/it/article.php?id=7245" target="_blank">Github 的 CSS 风格指南</a> [2015-01-11 23:41:02]</li><li><a href="https://blogread.cn/it/article.php?id=7244" target="_blank">消除疑问：CSS动画 VS JavaScript</a> [2015-01-11 23:39:59]</li><li><a href="https://blogread.cn/it/article.php?id=7240" target="_blank">css透明度的一些兼容测试</a> [2015-01-11 23:24:03]</li><li><a href="https://blogread.cn/it/article.php?id=7165" target="_blank">CSS 设计理念</a> [2014-12-06 20:39:06]</li><li><a href="https://blogread.cn/it/article.php?id=7123" target="_blank">邮件制作过程中需要注意的事项</a> [2014-12-02 00:06:10]</li><li><a href="https://blogread.cn/it/article.php?id=7030" target="_blank">浏览器特性检测工具：Modernizr</a> [2014-11-26 22:59:34]</li><li><a href="https://blogread.cn/it/article.php?id=6916" target="_blank">Print —— 被埋没的Media Type</a> [2014-09-17 13:43:45]</li><li><a href="https://blogread.cn/it/article.php?id=6910" target="_blank">IE开始支持部分webkit私有属性</a> [2014-09-17 12:31:35]</li><li><a href="https://blogread.cn/it/article.php?id=6887" target="_blank">网页适配手机移动版的CSS</a> [2014-07-15 22:45:45]</li><li><a href="https://blogread.cn/it/article.php?id=6789" target="_blank">网页重构应该避免的10大 CSS 糟糕用法</a> [2013-11-21 23:18:46]</li><li><a href="https://blogread.cn/it/article.php?id=6746" target="_blank">使用CSS和DataURI来添加杂色滤镜效果</a> [2013-10-16 22:35:44]</li><li><a href="https://blogread.cn/it/article.php?id=6722" target="_blank">2014网易前端开发笔试题笔记</a> [2013-10-08 12:14:44]</li><li><a href="https://blogread.cn/it/article.php?id=6633" target="_blank">程序员眼里IE浏览器是什么样的</a> [2013-08-21 13:30:53]</li><li><a href="https://blogread.cn/it/article.php?id=6618" target="_blank">关于z-index的那些事儿</a> [2013-08-15 13:15:49]</li><li><a href="https://blogread.cn/it/article.php?id=6567" target="_blank">如何成为一名优秀的web前端工程师（前端攻城师）？</a> [2013-07-31 12:53:05]</li><li><a href="https://blogread.cn/it/article.php?id=6546" target="_blank">合理设置响应式设计的响应点【译】</a> [2013-07-28 15:45:50]</li><li><a href="https://blogread.cn/it/article.php?id=6491" target="_blank">IE10 CSS Hack（顺便聊聊IE11的CSS Hack）</a> [2013-07-07 17:59:07]</li><li><a href="https://blogread.cn/it/article.php?id=6481" target="_blank">浏览器的渲染原理简介</a> [2013-06-19 23:36:50]</li><li><a href="https://blogread.cn/it/article.php?id=6451" target="_blank">开发者调试工具Chrome Workspace</a> [2013-06-02 20:19:05]</li><li><a href="https://blogread.cn/it/article.php?id=6375" target="_blank">如何成为一名优秀的前端工程师</a> [2013-05-08 13:47:33]</li><li><a href="https://blogread.cn/it/article.php?id=6372" target="_blank">CSS选择器</a> [2013-05-08 13:39:04]</li><li><a href="https://blogread.cn/it/article.php?id=6370" target="_blank">一览CSS布局标准</a> [2013-05-05 09:14:00]</li><li><a href="https://blogread.cn/it/article.php?id=6273" target="_blank">你需要知道的三个CSS技巧</a> [2013-03-04 14:22:44]</li><li><a href="https://blogread.cn/it/article.php?id=6255" target="_blank">CSS技巧荟萃：了解CSS页面布局和加载流程</a> [2013-03-03 23:05:26]</li><li><a href="https://blogread.cn/it/article.php?id=6232" target="_blank">Web前端工程师编程能力飞升之路</a> [2013-02-28 23:22:40]</li><li><a href="https://blogread.cn/it/article.php?id=6225" target="_blank">改变文章的字号大小</a> [2013-02-19 12:00:35]</li><li><a href="https://blogread.cn/it/article.php?id=6185" target="_blank">web开发设计人员不可不用的在线web工具和应用</a> [2013-01-16 13:48:45]</li><li><a href="https://blogread.cn/it/article.php?id=6183" target="_blank">CSS Sprites的原理</a> [2013-01-10 22:50:47]</li><li><a href="https://blogread.cn/it/article.php?id=6182" target="_blank">CSS布局中一个简单的应用BFC的例子</a> [2013-01-10 22:48:47]</li><li><a href="https://blogread.cn/it/article.php?id=6180" target="_blank">overflow:hidden真的失效了吗</a> [2013-01-10 22:44:52]</li><li><a href="https://blogread.cn/it/article.php?id=6168" target="_blank">如何判断自己是否到了该辞职的时候</a> [2013-01-10 22:14:10]</li><li><a href="https://blogread.cn/it/article.php?id=6133" target="_blank">CSS基线之道</a> [2012-12-23 23:02:45]</li><li><a href="https://blogread.cn/it/article.php?id=6112" target="_blank">IE BUG相关文章集合</a> [2012-12-19 13:30:03]</li><li><a href="https://blogread.cn/it/article.php?id=6111" target="_blank">关于前端开发</a> [2012-12-18 23:25:27]</li><li><a href="https://blogread.cn/it/article.php?id=6065" target="_blank">谈产品经理的转行</a> [2012-12-08 23:02:32]</li><li><a href="https://blogread.cn/it/article.php?id=6055" target="_blank">是时候使用filter:drop-shadow了</a> [2012-12-07 23:42:48]</li><li><a href="https://blogread.cn/it/article.php?id=6054" target="_blank">非响应式设计的viewport</a> [2012-12-07 23:42:02]</li><li><a href="https://blogread.cn/it/article.php?id=6053" target="_blank">标签？ID？还是CLASS？</a> [2012-12-07 23:40:13]</li><li><a href="https://blogread.cn/it/article.php?id=6028" target="_blank">IE10 CSS hack</a> [2012-12-05 13:08:04]</li><li><a href="https://blogread.cn/it/article.php?id=5942" target="_blank">60多个超炫的视差滚动效果网站设计欣赏</a> [2012-10-26 00:25:29]</li><li><a href="https://blogread.cn/it/article.php?id=5918" target="_blank">颜色的代码表达式</a> [2012-10-22 13:18:27]</li><li><a href="https://blogread.cn/it/article.php?id=5903" target="_blank">响应式Web设计</a> [2012-10-14 22:27:00]</li><li><a href="https://blogread.cn/it/article.php?id=5870" target="_blank">网站性能评测点</a> [2012-09-20 13:53:54]</li><li><a href="https://blogread.cn/it/article.php?id=5867" target="_blank">IE 颜色 Hack全收集</a> [2012-09-20 13:51:54]</li><li><a href="https://blogread.cn/it/article.php?id=5823" target="_blank">position:sticky介绍</a> [2012-09-17 23:13:53]</li><li><a href="https://blogread.cn/it/article.php?id=5805" target="_blank">三角形变形记之纯css实现的分布导航条效果</a> [2012-09-10 23:34:25]</li><li><a href="https://blogread.cn/it/article.php?id=5803" target="_blank">简单js+css实现模拟自定义select样式</a> [2012-09-10 23:29:05]</li><li><a href="https://blogread.cn/it/article.php?id=5788" target="_blank">使用jQuery开发一个带有密码强度检验的超酷注册页面</a> [2012-09-06 23:42:16]</li><li><a href="https://blogread.cn/it/article.php?id=5698" target="_blank">inline-blcok 前世今生</a> [2012-08-17 13:18:47]</li><li><a href="https://blogread.cn/it/article.php?id=5624" target="_blank">阅读好体验的准则：100% Easy-2-Read</a> [2012-08-02 23:57:38]</li><li><a href="https://blogread.cn/it/article.php?id=5617" target="_blank">display属性和display属性对SEO的影响</a> [2012-08-02 12:26:16]</li><li><a href="https://blogread.cn/it/article.php?id=5614" target="_blank">《精通CSS+DIV》学习笔记</a> [2012-08-02 12:23:19]</li><li><a href="https://blogread.cn/it/article.php?id=5481" target="_blank">css样式修改神器cssUpdater的使用方法</a> [2012-06-14 13:59:49]</li><li><a href="https://blogread.cn/it/article.php?id=5446" target="_blank">响应式设计的5个CSS实用技巧</a> [2012-06-07 23:03:59]</li><li><a href="https://blogread.cn/it/article.php?id=5438" target="_blank">Web设计师需要编程知识吗？</a> [2012-06-07 00:10:27]</li><li><a href="https://blogread.cn/it/article.php?id=5334" target="_blank">OverFlow – 一个秘密武器</a> [2012-05-14 22:30:18]</li><li><a href="https://blogread.cn/it/article.php?id=5306" target="_blank">CSS雪碧图会占用太多浏览器内存吗？</a> [2012-05-10 23:53:01]</li><li><a href="https://blogread.cn/it/article.php?id=5251" target="_blank">如何制作chrome扩展程序</a> [2012-04-26 23:36:39]</li><li><a href="https://blogread.cn/it/article.php?id=5244" target="_blank">Tip中的指示箭头实现</a> [2012-04-22 15:04:42]</li><li><a href="https://blogread.cn/it/article.php?id=5207" target="_blank">初识PhoneGap</a> [2012-04-12 13:34:32]</li><li><a href="https://blogread.cn/it/article.php?id=5184" target="_blank">理解css中的长度单位</a> [2012-04-09 12:16:48]</li><li><a href="https://blogread.cn/it/article.php?id=5125" target="_blank">设计师也需要了解的一些前端知识</a> [2012-03-31 22:39:03]</li><li><a href="https://blogread.cn/it/article.php?id=5096" target="_blank">从滚动条消失看细节设计</a> [2012-03-25 20:59:22]</li><li><a href="https://blogread.cn/it/article.php?id=5095" target="_blank">神奇的CSS形状</a> [2012-03-25 20:53:58]</li><li><a href="https://blogread.cn/it/article.php?id=5065" target="_blank">一个独立程序员对自己近九个月工作生活的回顾</a> [2012-03-12 23:53:17]</li><li><a href="https://blogread.cn/it/article.php?id=5045" target="_blank">为细节设计</a> [2012-03-11 22:38:53]</li><li><a href="https://blogread.cn/it/article.php?id=5032" target="_blank">迁户口实录(深圳集体户到杭州个户)</a> [2012-03-11 22:04:39]</li><li><a href="https://blogread.cn/it/article.php?id=5007" target="_blank">LOFTER轻博模板设计</a> [2012-03-04 17:52:23]</li><li><a href="https://blogread.cn/it/article.php?id=5001" target="_blank">自定义webkit搜索框样式</a> [2012-03-04 17:45:38]</li><li><a href="https://blogread.cn/it/article.php?id=4938" target="_blank">javascript插入样式</a> [2012-02-05 23:06:38]</li><li><a href="https://blogread.cn/it/article.php?id=4928" target="_blank">js和css的顺序关系</a> [2012-02-05 15:30:22]</li><li><a href="https://blogread.cn/it/article.php?id=4858" target="_blank">抛弃 CSS Hacks 后的浏览器兼容方案</a> [2012-01-27 18:46:12]</li><li><a href="https://blogread.cn/it/article.php?id=4840" target="_blank">设置样式方法setStyle</a> [2012-01-27 18:04:32]</li><li><a href="https://blogread.cn/it/article.php?id=4822" target="_blank">拒绝平庸――浅谈WEB登录页面设计</a> [2012-01-24 13:52:15]</li><li><a href="https://blogread.cn/it/article.php?id=4782" target="_blank">user-select介绍</a> [2012-01-15 23:53:29]</li><li><a href="https://blogread.cn/it/article.php?id=4756" target="_blank">CSS中的z-index属性</a> [2012-01-03 23:51:51]</li><li><a href="https://blogread.cn/it/article.php?id=4750" target="_blank">经验分享-导航鼠标悬停状态小效果</a> [2012-01-03 23:47:27]</li><li><a href="https://blogread.cn/it/article.php?id=4697" target="_blank">知心怪蜀黍NO.1 网站编辑怎样转内容运营</a> [2011-12-21 00:17:21]</li><li><a href="https://blogread.cn/it/article.php?id=4655" target="_blank">Web开发中需要了解的东西</a> [2011-12-11 15:38:12]</li><li><a href="https://blogread.cn/it/article.php?id=4633" target="_blank">如何用jQuery创建很酷的动态菜单</a> [2011-11-23 23:46:45]</li><li><a href="https://blogread.cn/it/article.php?id=4619" target="_blank">抛弃 CSS Hacks 后的浏览器兼容方案</a> [2011-11-21 00:10:14]</li><li><a href="https://blogread.cn/it/article.php?id=4608" target="_blank">将小型、现代的产品主页由psd转换成XHTML/CSS模板</a> [2011-11-20 23:59:38]</li><li><a href="https://blogread.cn/it/article.php?id=4607" target="_blank">用Photoshop设计一个小型、现代的产品主页</a> [2011-11-20 23:59:06]</li><li><a href="https://blogread.cn/it/article.php?id=4566" target="_blank">我做前端一年半</a> [2011-11-13 21:11:21]</li><li><a href="https://blogread.cn/it/article.php?id=4535" target="_blank">响应式网页设计</a> [2011-11-04 22:19:17]</li><li><a href="https://blogread.cn/it/article.php?id=4506" target="_blank">细节魔鬼与精简团队</a> [2011-10-18 23:29:39]</li><li><a href="https://blogread.cn/it/article.php?id=4492" target="_blank">javascript获取隐藏dom的宽高</a> [2011-10-14 14:01:24]</li><li><a href="https://blogread.cn/it/article.php?id=4487" target="_blank">我的防身暗器-网页设计应急小技巧</a> [2011-10-14 13:54:53]</li><li><a href="https://blogread.cn/it/article.php?id=4466" target="_blank">新版微博体验</a> [2011-10-13 14:05:19]</li><li><a href="https://blogread.cn/it/article.php?id=4449" target="_blank">行内元素vertical-align:middle在html5和xhtml1.0及以下版本中的表现差异</a> [2011-10-12 00:11:23]</li><li><a href="https://blogread.cn/it/article.php?id=4425" target="_blank">div+css+js无缝滚动代码</a> [2011-09-26 23:28:14]</li><li><a href="https://blogread.cn/it/article.php?id=4418" target="_blank">淘宝商城实习三月记：产品经理做什么</a> [2011-09-26 23:16:17]</li><li><a href="https://blogread.cn/it/article.php?id=4399" target="_blank">css 透明度完全兼容的写法</a> [2011-09-21 23:19:40]</li><li><a href="https://blogread.cn/it/article.php?id=4389" target="_blank">为什么招不到人</a> [2011-09-21 13:36:24]</li><li><a href="https://blogread.cn/it/article.php?id=4337" target="_blank">瀑布流布局浅析</a> [2011-09-16 00:05:55]</li><li><a href="https://blogread.cn/it/article.php?id=4294" target="_blank">[正则优化] CSS选择符匹配</a> [2011-09-04 23:37:56]</li><li><a href="https://blogread.cn/it/article.php?id=4292" target="_blank">[正则优化] CSS属性选择符的匹配</a> [2011-09-04 23:33:04]</li><li><a href="https://blogread.cn/it/article.php?id=4222" target="_blank">CSS的未来：明智的布局工具终于到来</a> [2011-08-22 12:28:26]</li><li><a href="https://blogread.cn/it/article.php?id=4147" target="_blank">19UED前端CSS代码规范 V1.0</a> [2011-08-14 15:47:47]</li><li><a href="https://blogread.cn/it/article.php?id=4053" target="_blank">前端设计中的浏览器CSS Hack汇总</a> [2011-07-24 14:57:30]</li><li><a href="https://blogread.cn/it/article.php?id=3977" target="_blank">Javascript和CSS浏览器兼容总结</a> [2011-07-09 22:44:14]</li><li><a href="https://blogread.cn/it/article.php?id=3948" target="_blank">推荐三十款CSS样式选择器代码</a> [2011-07-05 23:15:06]</li><li><a href="https://blogread.cn/it/article.php?id=3922" target="_blank">CSS排版：技术与最佳实践</a> [2011-06-24 14:02:27]</li><li><a href="https://blogread.cn/it/article.php?id=3894" target="_blank">CSS排版: 基础</a> [2011-06-23 13:33:44]</li><li><a href="https://blogread.cn/it/article.php?id=3889" target="_blank">Web表单设计:表单结构</a> [2011-06-23 13:27:48]</li><li><a href="https://blogread.cn/it/article.php?id=3877" target="_blank">使用CSS框架的优点和缺点</a> [2011-06-23 00:14:07]</li><li><a href="https://blogread.cn/it/article.php?id=3876" target="_blank">CSS排版：例子和工具</a> [2011-06-23 00:10:40]</li><li><a href="https://blogread.cn/it/article.php?id=3875" target="_blank">JavaScript，只有你想不到</a> [2011-06-23 00:08:33]</li><li><a href="https://blogread.cn/it/article.php?id=3861" target="_blank">十年以前，我想做个网站！</a> [2011-06-22 00:01:17]</li><li><a href="https://blogread.cn/it/article.php?id=3829" target="_blank">前端设计类书籍推荐</a> [2011-06-21 13:27:01]</li><li><a href="https://blogread.cn/it/article.php?id=3813" target="_blank">CSS 忍者：安全的 CSS hacks 秘籍</a> [2011-06-20 13:36:51]</li><li><a href="https://blogread.cn/it/article.php?id=3742" target="_blank">CSS图片替换</a> [2011-06-02 13:39:50]</li><li><a href="https://blogread.cn/it/article.php?id=3716" target="_blank">CSS圆角制作</a> [2011-06-02 13:15:02]</li><li><a href="https://blogread.cn/it/article.php?id=3712" target="_blank">CSS两列流式布局</a> [2011-06-02 00:13:47]</li><li><a href="https://blogread.cn/it/article.php?id=3686" target="_blank">圆角头像的重构优化</a> [2011-06-01 23:37:47]</li><li><a href="https://blogread.cn/it/article.php?id=3600" target="_blank">重置还是不重置-这是个CSS问题</a> [2011-05-17 09:00:46]</li><li><a href="https://blogread.cn/it/article.php?id=3565" target="_blank">CSS中变化Fixed的实现</a> [2011-05-03 23:36:43]</li><li><a href="https://blogread.cn/it/article.php?id=3548" target="_blank">CSS利用背景图做等高列</a> [2011-04-28 13:24:52]</li><li><a href="https://blogread.cn/it/article.php?id=3524" target="_blank">有条件的添加Hover样式</a> [2011-04-02 14:17:02]</li><li><a href="https://blogread.cn/it/article.php?id=3510" target="_blank">理解响应网页设计元素</a> [2011-04-01 13:33:29]</li><li><a href="https://blogread.cn/it/article.php?id=3488" target="_blank">Firefox滚动残影</a> [2011-03-30 13:46:52]</li><li><a href="https://blogread.cn/it/article.php?id=3486" target="_blank">关于前端开发那些事（五）激励体制</a> [2011-03-29 00:17:10]</li><li><a href="https://blogread.cn/it/article.php?id=3485" target="_blank">关于前端开发那些事儿(四) 技术的本质何在?</a> [2011-03-29 00:16:51]</li><li><a href="https://blogread.cn/it/article.php?id=3454" target="_blank">改善网页设计的10个绝佳SEO建议</a> [2011-03-27 23:38:55]</li><li><a href="https://blogread.cn/it/article.php?id=3323" target="_blank">让人又爱又恨的标签们</a> [2011-02-23 22:18:59]</li><li><a href="https://blogread.cn/it/article.php?id=3312" target="_blank">Pinterest：充分挖掘视觉的潜力</a> [2011-02-22 23:23:16]</li><li><a href="https://blogread.cn/it/article.php?id=3289" target="_blank">建设一个网站的成本（之一）</a> [2011-02-16 22:24:34]</li><li><a href="https://blogread.cn/it/article.php?id=3282" target="_blank">Web开发人员速查卡</a> [2011-02-16 22:16:42]</li><li><a href="https://blogread.cn/it/article.php?id=3272" target="_blank">怎样限制用户</a> [2011-02-15 22:54:10]</li><li><a href="https://blogread.cn/it/article.php?id=3229" target="_blank">用户及用户特征</a> [2011-02-13 21:03:25]</li><li><a href="https://blogread.cn/it/article.php?id=3201" target="_blank">为自己打造良好的文章阅读体验</a> [2011-02-10 22:21:44]</li><li><a href="https://blogread.cn/it/article.php?id=3162" target="_blank">未知高度的图片垂直居中</a> [2011-02-06 23:45:08]</li><li><a href="https://blogread.cn/it/article.php?id=3147" target="_blank">RMB符号的几种显示方式</a> [2011-01-30 19:08:22]</li><li><a href="https://blogread.cn/it/article.php?id=3111" target="_blank">Nicholas C. Zakas谈怎样才能成为优秀的前端工程师</a> [2011-01-27 22:57:44]</li><li><a href="https://blogread.cn/it/article.php?id=3099" target="_blank">解决Chrome最小字体限制</a> [2011-01-26 21:16:54]</li><li><a href="https://blogread.cn/it/article.php?id=3098" target="_blank">网站开发人员应该知道的61件事</a> [2011-01-26 21:16:37]</li><li><a href="https://blogread.cn/it/article.php?id=3071" target="_blank">内联元素和块状元素，盒子模型</a> [2011-01-23 23:00:14]</li><li><a href="https://blogread.cn/it/article.php?id=3022" target="_blank">:before和::before的区别</a> [2011-01-17 22:57:55]</li><li><a href="https://blogread.cn/it/article.php?id=3006" target="_blank">设置&lt;input type=”file”&gt;样式</a> [2011-01-12 23:27:09]</li><li><a href="https://blogread.cn/it/article.php?id=2998" target="_blank">前端开发小工具集合</a> [2011-01-12 23:12:00]</li><li><a href="https://blogread.cn/it/article.php?id=2963" target="_blank">网易首页2011新版随想</a> [2011-01-05 22:11:18]</li><li><a href="https://blogread.cn/it/article.php?id=2959" target="_blank">标题栏新消息提示</a> [2011-01-05 03:32:11]</li><li><a href="https://blogread.cn/it/article.php?id=2942" target="_blank">新媒体艺术的分众性研究</a> [2010-12-29 21:49:23]</li><li><a href="https://blogread.cn/it/article.php?id=2940" target="_blank">关于前端开发那些事儿（三）技术之变现</a> [2010-12-29 21:46:25]</li><li><a href="https://blogread.cn/it/article.php?id=2926" target="_blank">让“提到”、“转发”和“评论”各司其职</a> [2010-12-28 20:56:16]</li><li><a href="https://blogread.cn/it/article.php?id=2903" target="_blank">门户、创新、创业之道</a> [2010-12-26 20:57:54]</li><li><a href="https://blogread.cn/it/article.php?id=2859" target="_blank">关于WEB登录注册系统的下午茶</a> [2010-12-14 22:05:06]</li><li><a href="https://blogread.cn/it/article.php?id=2798" target="_blank">Web标准路漫漫</a> [2010-12-05 22:54:46]</li><li><a href="https://blogread.cn/it/article.php?id=2781" target="_blank">社区获取新用户的一些尝试</a> [2010-12-01 22:46:50]</li><li><a href="https://blogread.cn/it/article.php?id=2761" target="_blank">让生活变简单的简单网站</a> [2010-11-29 22:45:37]</li><li><a href="https://blogread.cn/it/article.php?id=2748" target="_blank">模拟宽度自适应的输入框</a> [2010-11-24 23:10:19]</li><li><a href="https://blogread.cn/it/article.php?id=2734" target="_blank">如何开发Web应用程序</a> [2010-11-22 21:22:54]</li><li><a href="https://blogread.cn/it/article.php?id=2720" target="_blank">网页设计中的</a> [2010-11-17 19:04:01]</li><li><a href="https://blogread.cn/it/article.php?id=2690" target="_blank">弹窗广告开发</a> [2010-11-13 09:07:19]</li><li><a href="https://blogread.cn/it/article.php?id=2687" target="_blank">红孩子网站推广方案</a> [2010-11-13 08:54:33]</li><li><a href="https://blogread.cn/it/article.php?id=2675" target="_blank">网站UI实现的8种方式</a> [2010-11-10 18:58:23]</li><li><a href="https://blogread.cn/it/article.php?id=2657" target="_blank">前端开发是产品设计么</a> [2010-11-07 22:39:24]</li><li><a href="https://blogread.cn/it/article.php?id=2606" target="_blank">又到一年校招时： 校园用户使用的招聘类网站对比</a> [2010-10-30 07:58:35]</li><li><a href="https://blogread.cn/it/article.php?id=2602" target="_blank">互联网广告的发展史</a> [2010-10-28 22:20:35]</li><li><a href="https://blogread.cn/it/article.php?id=2563" target="_blank">互联网上的恶趣味以及价值观</a> [2010-10-25 09:04:06]</li><li><a href="https://blogread.cn/it/article.php?id=2549" target="_blank">如何在25步之内开发出一个网站</a> [2010-10-22 00:31:07]</li><li><a href="https://blogread.cn/it/article.php?id=2548" target="_blank">Seor想成功必须具备的十大素质</a> [2010-10-22 00:30:39]</li><li><a href="https://blogread.cn/it/article.php?id=2507" target="_blank">word wrap 解惑</a> [2010-10-14 09:03:48]</li><li><a href="https://blogread.cn/it/article.php?id=2448" target="_blank">网站css样式命名规范和应用原则</a> [2010-10-02 08:18:51]</li><li><a href="https://blogread.cn/it/article.php?id=2413" target="_blank">团购体验记 -- 上岛咖啡</a> [2010-09-26 09:08:53]</li><li><a href="https://blogread.cn/it/article.php?id=2411" target="_blank">关于网页问卷入口的小结</a> [2010-09-26 08:58:43]</li><li><a href="https://blogread.cn/it/article.php?id=2400" target="_blank">优雅地扩大链接响应区域</a> [2010-09-24 23:48:43]</li><li><a href="https://blogread.cn/it/article.php?id=2392" target="_blank">display属性及其对SEO的影响</a> [2010-09-14 08:57:32]</li><li><a href="https://blogread.cn/it/article.php?id=2378" target="_blank">浅谈后台页面按钮运用</a> [2010-09-12 23:37:41]</li><li><a href="https://blogread.cn/it/article.php?id=2376" target="_blank">弹出窗口的兼容方案</a> [2010-09-11 09:56:16]</li><li><a href="https://blogread.cn/it/article.php?id=2345" target="_blank">OverFlow -- 创建BFC,清除浮动</a> [2010-09-05 23:34:04]</li><li><a href="https://blogread.cn/it/article.php?id=2344" target="_blank">社交网络语法：关于“Checkin”</a> [2010-09-05 23:29:35]</li><li><a href="https://blogread.cn/it/article.php?id=2308" target="_blank">头像web版交互设计总结</a> [2010-08-23 22:04:19]</li><li><a href="https://blogread.cn/it/article.php?id=2306" target="_blank">IE6下position:absolute相邻元素margin-top失效的bug</a> [2010-08-23 22:02:15]</li><li><a href="https://blogread.cn/it/article.php?id=2266" target="_blank">样式的作用域──页面重构中的模块化设计（一）</a> [2010-08-17 23:15:39]</li><li><a href="https://blogread.cn/it/article.php?id=2258" target="_blank">白话Block Formatting Context</a> [2010-08-17 23:03:47]</li><li><a href="https://blogread.cn/it/article.php?id=2257" target="_blank">触发hasLayout引起的BUG</a> [2010-08-17 22:59:38]</li><li><a href="https://blogread.cn/it/article.php?id=2240" target="_blank">底部浮动条的一种兼容方案</a> [2010-08-15 22:46:43]</li><li><a href="https://blogread.cn/it/article.php?id=2239" target="_blank">让IE支持RGBa的背景色</a> [2010-08-15 22:45:11]</li><li><a href="https://blogread.cn/it/article.php?id=2232" target="_blank">消失的列表背景</a> [2010-08-15 09:40:29]</li><li><a href="https://blogread.cn/it/article.php?id=2228" target="_blank">IE6，IE7中负缩进的问题</a> [2010-08-13 09:51:42]</li><li><a href="https://blogread.cn/it/article.php?id=2227" target="_blank">IE6浮动引起的一些BUG</a> [2010-08-13 09:50:06]</li><li><a href="https://blogread.cn/it/article.php?id=2197" target="_blank">多栏自适应布局问题浅谈</a> [2010-08-11 10:00:52]</li><li><a href="https://blogread.cn/it/article.php?id=2184" target="_blank">前端优化总结</a> [2010-08-09 09:37:37]</li><li><a href="https://blogread.cn/it/article.php?id=2171" target="_blank">elem.style.left与elem.offsetLeft的区别</a> [2010-08-06 00:15:38]</li><li><a href="https://blogread.cn/it/article.php?id=2169" target="_blank">li水平居中css实现</a> [2010-08-06 00:13:00]</li><li><a href="https://blogread.cn/it/article.php?id=2167" target="_blank">图片旋转的小例子</a> [2010-08-05 10:00:54]</li><li><a href="https://blogread.cn/it/article.php?id=2166" target="_blank">用CSS禁用输入法</a> [2010-08-05 09:58:50]</li><li><a href="https://blogread.cn/it/article.php?id=2163" target="_blank">文本自动换行</a> [2010-08-04 23:36:12]</li><li><a href="https://blogread.cn/it/article.php?id=2161" target="_blank">li的多余空白</a> [2010-08-04 23:21:14]</li><li><a href="https://blogread.cn/it/article.php?id=2156" target="_blank">CSS Border使用小分享</a> [2010-08-04 22:55:45]</li><li><a href="https://blogread.cn/it/article.php?id=2153" target="_blank">获取元素在页面的绝对位置</a> [2010-08-04 00:06:48]</li><li><a href="https://blogread.cn/it/article.php?id=2125" target="_blank">别让妈妈生气――浅谈长者用户</a> [2010-08-02 02:28:46]</li><li><a href="https://blogread.cn/it/article.php?id=2115" target="_blank">【翻译】构建成功web应用的十项黄金法则</a> [2010-07-29 22:53:24]</li><li><a href="https://blogread.cn/it/article.php?id=2113" target="_blank">使&lt;pre&gt;的内容自动换行</a> [2010-07-29 20:46:05]</li><li><a href="https://blogread.cn/it/article.php?id=2112" target="_blank">各浏览器的默认CSS</a> [2010-07-29 20:45:13]</li><li><a href="https://blogread.cn/it/article.php?id=2107" target="_blank">终极攻略――未知高度元素垂直居中</a> [2010-07-27 23:33:38]</li><li><a href="https://blogread.cn/it/article.php?id=2106" target="_blank">多列等高方案</a> [2010-07-27 23:30:57]</li><li><a href="https://blogread.cn/it/article.php?id=2101" target="_blank">Microstrategy 8.1.2 Web Universal  开发问题整理</a> [2010-07-27 23:23:34]</li><li><a href="https://blogread.cn/it/article.php?id=2100" target="_blank">Google Docs Ctrl + C 技术浅析</a> [2010-07-27 23:22:51]</li><li><a href="https://blogread.cn/it/article.php?id=2083" target="_blank">display: inline-block在IE6、IE7下bug的解决方法</a> [2010-07-25 22:33:02]</li><li><a href="https://blogread.cn/it/article.php?id=2039" target="_blank">无缝背景的推荐</a> [2010-07-21 23:42:17]</li><li><a href="https://blogread.cn/it/article.php?id=2000" target="_blank">亚马逊用户体验改善</a> [2010-07-20 09:50:25]</li><li><a href="https://blogread.cn/it/article.php?id=1991" target="_blank">Google font api、web font与中文</a> [2010-07-19 22:47:35]</li><li><a href="https://blogread.cn/it/article.php?id=1990" target="_blank">移动网站开发――CSS</a> [2010-07-19 22:44:25]</li><li><a href="https://blogread.cn/it/article.php?id=1960" target="_blank">按钮制作一小例</a> [2010-07-18 23:28:23]</li><li><a href="https://blogread.cn/it/article.php?id=1952" target="_blank">前端开发,最好是多好？</a> [2010-07-16 00:08:21]</li><li><a href="https://blogread.cn/it/article.php?id=1933" target="_blank">互联网产品设计十年</a> [2010-07-14 22:27:47]</li><li><a href="https://blogread.cn/it/article.php?id=1932" target="_blank">media type与media query</a> [2010-07-14 09:57:23]</li><li><a href="https://blogread.cn/it/article.php?id=1926" target="_blank">50个活力和动感的网页设计－颜色的灵感</a> [2010-07-14 09:42:46]</li><li><a href="https://blogread.cn/it/article.php?id=1924" target="_blank">如何创建CSS的对象？获取合适的粒度！</a> [2010-07-14 03:27:07]</li><li><a href="https://blogread.cn/it/article.php?id=1923" target="_blank">HTML和CSS中的视觉语义</a> [2010-07-14 03:25:44]</li><li><a href="https://blogread.cn/it/article.php?id=1922" target="_blank">同是做网站，他们是怎么用词的？</a> [2010-07-14 00:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=1920" target="_blank">各公司对前端开发的职位描述</a> [2010-07-14 00:01:20]</li><li><a href="https://blogread.cn/it/article.php?id=1906" target="_blank">电子商务网站“用户评论”模块浅析</a> [2010-07-09 13:13:20]</li><li><a href="https://blogread.cn/it/article.php?id=1901" target="_blank">我们来做一个会呼吸的菜单吧!!</a> [2010-07-07 12:29:39]</li><li><a href="https://blogread.cn/it/article.php?id=1882" target="_blank">关于排行榜代码优化</a> [2010-07-02 09:31:20]</li><li><a href="https://blogread.cn/it/article.php?id=1875" target="_blank">CSS float 父层定义的颜色无法显示</a> [2010-06-28 23:56:56]</li><li><a href="https://blogread.cn/it/article.php?id=1868" target="_blank">“铁”饭碗</a> [2010-06-27 22:26:43]</li><li><a href="https://blogread.cn/it/article.php?id=1864" target="_blank">解决IE6从Nginx服务器下载图片不Cache的Bug</a> [2010-06-27 22:19:15]</li><li><a href="https://blogread.cn/it/article.php?id=1862" target="_blank">2010网页设计趋势</a> [2010-06-27 22:14:17]</li><li><a href="https://blogread.cn/it/article.php?id=1859" target="_blank">CSS 简易浮动清除方法讨论</a> [2010-06-27 22:08:01]</li><li><a href="https://blogread.cn/it/article.php?id=1858" target="_blank">CSS 水平居中之相对定位与负边距法</a> [2010-06-27 22:06:36]</li><li><a href="https://blogread.cn/it/article.php?id=1857" target="_blank">IE 6与W3C盒子模型</a> [2010-06-25 12:22:32]</li><li><a href="https://blogread.cn/it/article.php?id=1846" target="_blank">白话Block Formatting Contexts</a> [2010-06-24 09:42:50]</li><li><a href="https://blogread.cn/it/article.php?id=1832" target="_blank">汉字的几何中心</a> [2010-06-22 13:19:03]</li><li><a href="https://blogread.cn/it/article.php?id=1823" target="_blank">实现一个更精简的Tab</a> [2010-06-21 17:29:49]</li><li><a href="https://blogread.cn/it/article.php?id=1814" target="_blank">一个全角空格的问题</a> [2010-06-18 18:10:36]</li><li><a href="https://blogread.cn/it/article.php?id=1812" target="_blank">创业和投资人的眼光</a> [2010-06-18 18:07:53]</li><li><a href="https://blogread.cn/it/article.php?id=1798" target="_blank">网页元素的层叠关系</a> [2010-06-17 10:18:03]</li><li><a href="https://blogread.cn/it/article.php?id=1781" target="_blank">用CSS禁用输入法</a> [2010-06-12 17:54:09]</li><li><a href="https://blogread.cn/it/article.php?id=1771" target="_blank">W3C 验证的是是非非</a> [2010-06-12 09:58:14]</li><li><a href="https://blogread.cn/it/article.php?id=1769" target="_blank">创造一个可理解的世界</a> [2010-06-12 09:56:11]</li><li><a href="https://blogread.cn/it/article.php?id=1764" target="_blank">在服务端合并和压缩JavaScript和CSS文件</a> [2010-06-11 11:55:52]</li><li><a href="https://blogread.cn/it/article.php?id=1692" target="_blank">关于前端开发的那些事（一）</a> [2010-06-01 13:12:16]</li><li><a href="https://blogread.cn/it/article.php?id=1682" target="_blank">我的互联网信仰</a> [2010-06-01 13:01:12]</li><li><a href="https://blogread.cn/it/article.php?id=1672" target="_blank">狗血的中天置地</a> [2010-05-31 23:56:55]</li><li><a href="https://blogread.cn/it/article.php?id=1663" target="_blank">HTML在线编辑器的实现难点</a> [2010-05-28 18:39:13]</li><li><a href="https://blogread.cn/it/article.php?id=1662" target="_blank">记开发firefox extension</a> [2010-05-28 13:07:30]</li><li><a href="https://blogread.cn/it/article.php?id=1652" target="_blank">IE双倍浮动边界Bug</a> [2010-05-27 13:26:08]</li><li><a href="https://blogread.cn/it/article.php?id=1489" target="_blank">关于腾讯微博的一些思考……</a> [2010-04-30 15:47:32]</li><li><a href="https://blogread.cn/it/article.php?id=1466" target="_blank">CSS Sprites 是否有必要？</a> [2010-04-28 15:36:24]</li><li><a href="https://blogread.cn/it/article.php?id=1457" target="_blank">支持多浏览器的网站变灰方法</a> [2010-04-27 13:48:13]</li><li><a href="https://blogread.cn/it/article.php?id=1455" target="_blank">通过Nginx使全站页面变灰，哀悼玉树地震遇难者</a> [2010-04-27 13:45:34]</li><li><a href="https://blogread.cn/it/article.php?id=1444" target="_blank">十六进制HTML颜色</a> [2010-04-26 11:14:06]</li><li><a href="https://blogread.cn/it/article.php?id=1426" target="_blank">繁体中文的混合排版</a> [2010-04-22 11:07:00]</li><li><a href="https://blogread.cn/it/article.php?id=1399" target="_blank">界面程序开发的一些总结</a> [2010-04-16 09:20:18]</li><li><a href="https://blogread.cn/it/article.php?id=1396" target="_blank">IE7 form中input背景图片失效的解决</a> [2010-04-15 13:50:45]</li><li><a href="https://blogread.cn/it/article.php?id=1375" target="_blank">如何创建google浏览器插件</a> [2010-04-14 13:35:59]</li><li><a href="https://blogread.cn/it/article.php?id=1363" target="_blank">如何强制限制表格宽度</a> [2010-04-14 09:14:05]</li><li><a href="https://blogread.cn/it/article.php?id=1360" target="_blank">制作CSS气泡框</a> [2010-04-13 11:10:16]</li><li><a href="https://blogread.cn/it/article.php?id=1351" target="_blank">你真的了解HTML吗</a> [2010-04-12 23:48:33]</li><li><a href="https://blogread.cn/it/article.php?id=1336" target="_blank">iPad Orientation CSS</a> [2010-04-12 09:19:33]</li><li><a href="https://blogread.cn/it/article.php?id=1329" target="_blank">JavaScript组件打包模式</a> [2010-04-09 09:12:53]</li><li><a href="https://blogread.cn/it/article.php?id=1323" target="_blank">什么是网页标准？</a> [2010-04-08 23:52:05]</li><li><a href="https://blogread.cn/it/article.php?id=1318" target="_blank">用私有属性来拯救IE7缩放图片的失真</a> [2010-04-07 15:41:35]</li><li><a href="https://blogread.cn/it/article.php?id=1315" target="_blank">语义化的label？</a> [2010-04-07 09:11:44]</li><li><a href="https://blogread.cn/it/article.php?id=1308" target="_blank">CSS简写指南</a> [2010-04-01 13:32:43]</li><li><a href="https://blogread.cn/it/article.php?id=1302" target="_blank">CSS使用技巧大全</a> [2010-04-01 08:57:58]</li><li><a href="https://blogread.cn/it/article.php?id=1295" target="_blank">[译]渐进增强：纯CSS聊天泡泡</a> [2010-03-31 13:37:36]</li><li><a href="https://blogread.cn/it/article.php?id=1274" target="_blank">简单的全系列浏览器css hack</a> [2010-03-29 09:03:54]</li><li><a href="https://blogread.cn/it/article.php?id=1188" target="_blank">关于系统邮件的设计</a> [2010-03-11 09:17:54]</li><li><a href="https://blogread.cn/it/article.php?id=1171" target="_blank">display属性和display属性对SEO的影响</a> [2010-03-09 09:18:00]</li><li><a href="https://blogread.cn/it/article.php?id=1168" target="_blank">防止垃圾邮件小技巧两则</a> [2010-03-09 09:14:15]</li><li><a href="https://blogread.cn/it/article.php?id=1138" target="_blank">jQuery边框圆角插件：DivCorners</a> [2010-03-03 23:58:12]</li><li><a href="https://blogread.cn/it/article.php?id=1069" target="_blank">页面上元素对齐的问题</a> [2010-02-25 09:27:37]</li><li><a href="https://blogread.cn/it/article.php?id=1051" target="_blank">CSS设置字体大小</a> [2010-02-23 22:39:36]</li><li><a href="https://blogread.cn/it/article.php?id=1043" target="_blank">两侧背景自动延伸的CSS实现方法</a> [2010-02-23 22:12:24]</li><li><a href="https://blogread.cn/it/article.php?id=961" target="_blank">终于想到如何给《三枪》归类了</a> [2010-01-12 13:24:35]</li><li><a href="https://blogread.cn/it/article.php?id=958" target="_blank">用于打印的页面设计</a> [2010-01-11 12:19:37]</li><li><a href="https://blogread.cn/it/article.php?id=956" target="_blank">如何做好一份前端工程师的简历？</a> [2010-01-11 12:13:21]</li><li><a href="https://blogread.cn/it/article.php?id=951" target="_blank">用javascript悬停效果改善你的在线商店的12种方法</a> [2010-01-08 17:05:42]</li><li><a href="https://blogread.cn/it/article.php?id=948" target="_blank">手机网站开发必修课[2009总结版]</a> [2010-01-08 13:03:31]</li><li><a href="https://blogread.cn/it/article.php?id=904" target="_blank">能看到的都不是核心竞争力</a> [2010-01-04 12:51:07]</li><li><a href="https://blogread.cn/it/article.php?id=866" target="_blank">图片轮播控件 Carousel Controls</a> [2009-12-22 14:22:26]</li><li><a href="https://blogread.cn/it/article.php?id=844" target="_blank">2009年年终盘点</a> [2009-12-19 17:58:19]</li><li><a href="https://blogread.cn/it/article.php?id=840" target="_blank">你的网上商店需要用TAB栏吗？</a> [2009-12-18 15:42:34]</li><li><a href="https://blogread.cn/it/article.php?id=828" target="_blank">三谈 Web 默认字体</a> [2009-12-17 09:13:28]</li><li><a href="https://blogread.cn/it/article.php?id=827" target="_blank">再谈 Web 默认字体</a> [2009-12-17 09:12:55]</li><li><a href="https://blogread.cn/it/article.php?id=810" target="_blank">JS+CSS实现隔行换色</a> [2009-12-13 20:20:43]</li><li><a href="https://blogread.cn/it/article.php?id=789" target="_blank">国务院发布2010年放假安排</a> [2009-12-09 16:43:44]</li><li><a href="https://blogread.cn/it/article.php?id=770" target="_blank">视觉设计前瞻实用性研究（PNVD） 第二期</a> [2009-12-04 23:24:49]</li><li><a href="https://blogread.cn/it/article.php?id=767" target="_blank">Teleport垃圾代码tppabs的清理</a> [2009-12-04 13:35:08]</li><li><a href="https://blogread.cn/it/article.php?id=765" target="_blank">色板 -- 颜色收集</a> [2009-12-04 13:33:03]</li><li><a href="https://blogread.cn/it/article.php?id=754" target="_blank">IE6 bug: 消失的绝对定位元素</a> [2009-12-02 22:56:22]</li><li><a href="https://blogread.cn/it/article.php?id=698" target="_blank">定位相关的怪异问题</a> [2009-11-25 23:49:53]</li><li><a href="https://blogread.cn/it/article.php?id=697" target="_blank">borderl:none;与border:0;的区别</a> [2009-11-25 23:49:00]</li><li><a href="https://blogread.cn/it/article.php?id=687" target="_blank">默认Web字体样式</a> [2009-11-23 23:29:34]</li><li><a href="https://blogread.cn/it/article.php?id=678" target="_blank">定位相关的怪异问题</a> [2009-11-22 20:46:14]</li><li><a href="https://blogread.cn/it/article.php?id=677" target="_blank">border:none;与border:0;的区别</a> [2009-11-22 20:45:13]</li><li><a href="https://blogread.cn/it/article.php?id=664" target="_blank">改善IE6中a与a:hover的背景支持</a> [2009-11-20 21:00:27]</li><li><a href="https://blogread.cn/it/article.php?id=657" target="_blank">输入框的大小</a> [2009-11-19 22:32:37]</li><li><a href="https://blogread.cn/it/article.php?id=634" target="_blank">由黄钻等级图标处理引发的思考</a> [2009-11-18 23:07:14]</li><li><a href="https://blogread.cn/it/article.php?id=606" target="_blank">Reflow</a> [2009-11-16 23:24:16]</li><li><a href="https://blogread.cn/it/article.php?id=573" target="_blank">动态加载JavaScript的小实践</a> [2009-11-13 18:37:49]</li><li><a href="https://blogread.cn/it/article.php?id=572" target="_blank">IE中选择符的4095限制</a> [2009-11-13 18:36:56]</li><li><a href="https://blogread.cn/it/article.php?id=571" target="_blank">CSS实现HTML元素透明的那些事</a> [2009-11-13 18:36:18]</li><li><a href="https://blogread.cn/it/article.php?id=569" target="_blank">JavaScript获取准确的行高</a> [2009-11-13 18:31:08]</li><li><a href="https://blogread.cn/it/article.php?id=556" target="_blank">网站重构到底是什么，网站重构到底要多久</a> [2009-11-12 19:01:52]</li><li><a href="https://blogread.cn/it/article.php?id=545" target="_blank">jquery判断是否隐藏</a> [2009-11-11 13:57:39]</li><li><a href="https://blogread.cn/it/article.php?id=544" target="_blank">jquery表格色彩差异显示</a> [2009-11-11 13:56:42]</li><li><a href="https://blogread.cn/it/article.php?id=543" target="_blank">li并行显示</a> [2009-11-11 13:55:50]</li><li><a href="https://blogread.cn/it/article.php?id=542" target="_blank">margin-left负值定位，在ie6下面错位的解决办法</a> [2009-11-11 13:54:44]</li><li><a href="https://blogread.cn/it/article.php?id=490" target="_blank">浮动引起的文本重影</a> [2009-11-08 23:10:45]</li><li><a href="https://blogread.cn/it/article.php?id=489" target="_blank">浏览器对居中的背景图片的兼容性</a> [2009-11-08 23:07:57]</li><li><a href="https://blogread.cn/it/article.php?id=488" target="_blank">缩小窗口&lt;body&gt;背景被裁掉</a> [2009-11-08 23:07:38]</li><li><a href="https://blogread.cn/it/article.php?id=487" target="_blank">页面元素的背景及boder被裁掉</a> [2009-11-08 23:07:20]</li><li><a href="https://blogread.cn/it/article.php?id=486" target="_blank">缩少窗口&lt;img/&gt;被裁掉</a> [2009-11-08 23:05:00]</li><li><a href="https://blogread.cn/it/article.php?id=485" target="_blank">CSS Sprites图片切割术与图片优化</a> [2009-11-08 23:03:33]</li><li><a href="https://blogread.cn/it/article.php?id=482" target="_blank">IE5至IE7读取不了4095行以后的CSS</a> [2009-11-08 21:51:29]</li><li><a href="https://blogread.cn/it/article.php?id=481" target="_blank">渐变背景上的内容垂直居中</a> [2009-11-08 21:50:53]</li><li><a href="https://blogread.cn/it/article.php?id=480" target="_blank">CSS让你的IE浏览器崩溃</a> [2009-11-08 21:50:01]</li><li><a href="https://blogread.cn/it/article.php?id=479" target="_blank">一个标签应用三个背景图片</a> [2009-11-08 21:46:50]</li><li><a href="https://blogread.cn/it/article.php?id=478" target="_blank">CSS的渲染效率</a> [2009-11-08 17:08:48]</li><li><a href="https://blogread.cn/it/article.php?id=447" target="_blank">公用样式模板的设计制作</a> [2009-11-04 23:04:01]</li><li><a href="https://blogread.cn/it/article.php?id=383" target="_blank">CSS让你的IE浏览器崩溃(Crash your IE)</a> [2009-10-30 08:44:46]</li><li><a href="https://blogread.cn/it/article.php?id=359" target="_blank">边框有时会消失的解决办法</a> [2009-10-29 08:50:39]</li><li><a href="https://blogread.cn/it/article.php?id=282" target="_blank">模式化窗口</a> [2009-10-22 09:37:49]</li><li><a href="https://blogread.cn/it/article.php?id=191" target="_blank">母亲也是爱美的</a> [2009-10-16 12:16:11]</li><li><a href="https://blogread.cn/it/article.php?id=163" target="_blank">符合Web标准：W3C 验证中10个导致失败的常见问题</a> [2009-10-14 23:35:50]</li><li><a href="https://blogread.cn/it/article.php?id=158" target="_blank">定位元素间的Z值比较及z-index在不同浏览器下默认值的影响</a> [2009-10-14 13:36:27]</li><li><a href="https://blogread.cn/it/article.php?id=134" target="_blank">基础体验决定上层应用</a> [2009-10-13 23:02:29]</li><li><a href="https://blogread.cn/it/article.php?id=29" target="_blank">一篇关于新媒体和新媒体营销的小结</a> [2009-10-10 23:56:20]</li><li><a href="https://blogread.cn/it/article.php?id=27" target="_blank">网站导航栏的过去与现在</a> [2009-10-10 23:43:59]</li><li><a href="https://blogread.cn/it/article.php?id=18" target="_blank">20个有趣的网站</a> [2009-10-10 18:14:11]</li></ol></p>]]></description>
		<content><![CDATA[text-align:match-parent 是一个用于精确继承父元素对齐方式的 CSS 属性值，它解决了在 CSS 逻辑属性（如 text-align:end）场景下无法直接通过 getComputedStyle 获取具体方向（left 或 right）的问题。当父元素设置 text-align:end 时，子元素默认计算值仍为 end，而使用 match-parent 后，浏览器会根据当前书写方向（direction）返回确切的 left 或 right，从而提供明确的对齐信息。然而，该特性实际应用极少，因为它依赖于 direction 属性的使用，且需要获取 textAlign 计算值的需求本身较为小众，因此在常规开发中几乎没有必要使用。尽管如此，其兼容性却异常广泛，所有主流浏览器均支持（Chrome 需加 -webkit- 前缀），作者戏称其可用于替代 text-align:inherit 以增加代码的“专业感”。总体而言，这是一个技术意义明确但实用场景狭窄的 CSS 特性，了解其存在和作用即可。]]></content>
	</item>
	<item>
		<title>WARNING: detected duplicate paths to the same disk导致crs无法正常启动故障解决</title>
		<link>https://blogread.cn/it/article.php?id=8588</link>
		<author>惜分飞</author>
		<pubDate>2026-06-03 09:03:24</pubDate>
		<category domain="https://blogread.cn/it/category.php?id=18">DevOps</category>
		<guid>https://blogread.cn/it/article.php?id=8588</guid>
		<comments>https://blogread.cn/it/article.php?id=8588#comment</comments>
		<description><![CDATA[<p><strong>标签：</strong>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=CRS" target="_blank">CRS</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=%E6%95%85%E9%9A%9C%E6%8E%92%E9%99%A4" target="_blank">故障排除</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=%E7%A3%81%E7%9B%98%E7%AE%A1%E7%90%86" target="_blank">磁盘管理</a></p><div>
<p>联系：<a href="https://www.xifenfei.com/about_xifenfei" target="_blank">手机/微信(+86 17813235971)   QQ(107644445)</a><a target="_blank" href="http://wpa.qq.com/msgrd?v=3&amp;uin=107644445&amp;site=qq&amp;menu=yes"><img src="https://www.xifenfei.com/wp-content/themes/img/site_qq.jpg" alt="QQ咨询惜分飞" title="QQ咨询惜分飞"></a></p>
<p>标题：<a href="https://www.xifenfei.com/2026/05/warning-detected-duplicate-paths-to-the-same-disk.html" target="_blank">WARNING: detected duplicate paths to the same disk导致crs无法正常启动故障解决</a></p>
<p>作者：<a href="https://www.xifenfei.com/" target="_blank">惜分飞</a>©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]</p>
</div>
<p>最近一周之内,两个客户由于错误修改asm_diskstring=’/dev/dm*’,’/dev/mapper/*’,导致后续集群无法启动成功,查看asm的alert日志发现类似错误(为了说明类似问题，实际中情况比现在复杂)</p>
<pre class="blogread-code language-bash" data-lang="bash"><code class="language-bash">WARNING: detected duplicate paths to the same disk:
  '/dev/mapper/mpathi' and
  '/dev/dm-3'
ERROR: diskgroup CRS was not mounted
ORA-15032: not all alterations performed
ORA-15017: diskgroup "CRS" cannot be mounted
ORA-15040: diskgroup is incomplete</code></pre>
<p>由于asm的vote磁盘组无法mount,从而使得crs无法正常启动,进而导致集群无法正常启动和工作.而在系统中mpathi和dm-3是同一块磁盘</p>
<pre class="blogread-code language-bash" data-lang="bash"><code class="language-bash">[root@rac1 mapper]# ls -ltr mpathi
lrwxrwxrwx 1 root root       7 May 24 13:09 mpathi -&gt; ../dm-3</code></pre>
<p>GPnP profile中关于asm_diskstring配置</p>
<pre class="blogread-code language-bash" data-lang="bash"><code class="language-bash">[grid@rac1 trace]$  gpnptool get -o-
……
&lt;orcl:ASM-Profile id="asm" DiscoveryString="/dev/dm*,/dev/mapper/mpath*" 
SPFile="+DATA/cimp-cluster/asmparameterfile/registry.253.889969697"/&gt;
……</code></pre>
<p>对于这样的情况,需要把profile中值修改了才行,通过重建asm spfile来实现</p>
<pre class="blogread-code language-bash" data-lang="bash"><code class="language-bash">---pfile
large_pool_size= 12M
instance_type= 'asm'
remote_login_passwordfile= 'EXCLUSIVE'
asm_diskstring= '/dev/mapper/*'
asm_power_limit= 1
diagnostic_dest= '/opt/app/grid'</code></pre>
<p>创建spfile(create spfile=’+CRS’ from pfile=’/tmp/pfile’)</p>
<pre class="blogread-code language-bash" data-lang="bash"><code class="language-bash">NOTE: Attempting voting file refresh on diskgroup CRS
NOTE: Refresh completed on diskgroup CRS. No voting file found.
NOTE: Voting file relocation is required in diskgroup CRS
NOTE: Attempting voting file relocation on diskgroup CRS
NOTE: voting file deletion on grp 1 disk CRS_0000
NOTE: voting file deletion on grp 1 disk CRS_0001
NOTE: voting file deletion on grp 1 disk CRS_0002
NOTE: No voting file found on diskgroup CRS
Sun May 24 13:23:25 2026
NOTE: updated gpnp profile ASM SPFILE to 
NOTE: updated gpnp profile ASM diskstring: /dev/mapper/*
NOTE: updated gpnp profile ASM diskstring: /dev/mapper/*
NOTE: updated gpnp profile ASM SPFILE to +CRS/cluster/asmparameterfile/registry.253.1234099407</code></pre>
<p>主要注意在create spfile的过程中voting file的信息被删除,使用kfed进行验证</p>
<pre class="blogread-code language-bash" data-lang="bash"><code class="language-bash">[root@rac1 dbs]# kfed read /dev/asm_mpathi|grep vf
kfdhdb.vfstart:                       0 ; 0x0ec: 0x00000000
kfdhdb.vfend:                         0 ; 0x0f0: 0x00000000
[root@rac1 dbs]# kfed read /dev/asm_mpatha|grep vf
kfdhdb.vfstart:                       0 ; 0x0ec: 0x00000000
kfdhdb.vfend:                         0 ; 0x0f0: 0x00000000
[root@rac1 dbs]# kfed read /dev/asm_mpathd|grep vf
kfdhdb.vfstart:                       0 ; 0x0ec: 0x00000000
kfdhdb.vfend:                         0 ; 0x0f0: 0x00000000</code></pre>
<p>需要执行replace votedisk</p>
<pre class="blogread-code language-bash" data-lang="bash"><code class="language-bash">[root@rac1 dbs]# crsctl replace votedisk +CRS
Successful addition of voting disk 99df870869c64f78bf944b40bfff8644.
Successful addition of voting disk e6db086a74d64f49bf0aff02944bcac5.
Successful addition of voting disk e88a412fe04b4fe6bf1ca067bca779b8.
Successful deletion of voting disk 615579e778684f54bf31c0ce83709f37.
Successful deletion of voting disk 9e48b89f95084fefbfb7648897508684.
Successful deletion of voting disk 274b913b3b874f7cbfb6b025028b4eaa.
Successfully replaced voting disk group with +CRS.
CRS-4266: Voting file(s) successfully replaced</code></pre>
<p>这样操作完成之后,再次查看GPnP profile中关于asm_diskstring配置</p>
<pre class="blogread-code language-bash" data-lang="bash"><code class="language-bash">[grid@rac1 trace]$  gpnptool get -o-
……
&lt;orcl:ASM-Profile id="asm" DiscoveryString="/dev/asm_*" 
SPFile="+DATA/cimp-cluster/asmparameterfile/registry.253.1234099407"/&gt;
……</code></pre>
<p>然后再次重启集群,一切恢复正常,解决了asm_diskstring=’/dev/dm*’,’/dev/mapper/*’误操作引起的WARNING: detected duplicate paths to the same disk:故障</p>
<div><ul><li><a href="https://www.xifenfei.com/2012/12/how-to-dump-the-contents-of-an-spfile-on-asm-when-asmgrid-is-down.html" rel="bookmark" class="crp_title">How to Get the Contents of an Spfile on ASM when ASM/GRID is down</a></li><li><a href="https://www.xifenfei.com/2022/02/_dropped_0000_ocr-recovery.html" rel="bookmark" class="crp_title">ocr磁盘组掉盘故障处理</a></li><li><a href="https://www.xifenfei.com/2012/04/ocrvote-disk-maintenance-operations-addremovereplacemove.html" rel="bookmark" class="crp_title">OCR/Vote disk 维护操作</a></li><li><a href="https://www.xifenfei.com/2013/11/oracle-12c-rac%E4%BF%AE%E6%94%B9ocrvotediskasm-spfile%E6%89%80%E5%9C%A8%E7%A3%81%E7%9B%98%E7%BB%84%E5%90%8D%E7%A7%B0.html" rel="bookmark" class="crp_title">ORACLE 12C RAC修改ocr/votedisk/asm spfile所在磁盘组名称</a></li><li><a href="https://www.xifenfei.com/2019/06/warning-read-failed-asm-dismount.html" rel="bookmark" class="crp_title">WARNING: Read Failed.导致asm磁盘组异常</a></li><li><a href="https://www.xifenfei.com/2012/04/asm-header-%E5%A4%87%E4%BB%BD%E4%B8%8E%E6%81%A2%E5%A4%8D.html" rel="bookmark" class="crp_title">ASM DISK HEADER 备份与恢复</a></li><li><a href="https://www.xifenfei.com/2020/12/_dropped_0001_data-recovery.html" rel="bookmark" class="crp_title">asm磁盘类似_DROPPED_0001_DATA名称故障处理</a></li><li><a href="https://www.xifenfei.com/2014/01/multipath%E5%AE%9E%E7%8E%B0%E8%AE%BE%E5%A4%87%E7%94%A8%E6%88%B7%E7%BB%84%E8%AE%BE%E7%BD%AE.html" rel="bookmark" class="crp_title">multipath实现设备用户组设置</a></li><li><a href="https://www.xifenfei.com/2013/11/oracle-12-1-rac%E7%9A%84ocr%E7%A3%81%E7%9B%98%E7%BB%84%E5%BC%82%E5%B8%B8%E6%81%A2%E5%A4%8D.html" rel="bookmark" class="crp_title">oracle 12.1 RAC的ocr磁盘组异常恢复</a></li><li><a href="https://www.xifenfei.com/2014/01/%E5%9B%A0sga_target%E8%AE%BE%E7%BD%AE%E4%B8%8D%E5%BD%93%E5%AF%BC%E8%87%B411gr2-rac%E6%97%A0%E6%B3%95%E6%AD%A3%E5%B8%B8%E5%90%AF%E5%8A%A8.html" rel="bookmark" class="crp_title">因asm sga_target设置不当导致11gr2 rac无法正常启动</a></li><li><a href="https://www.xifenfei.com/2021/06/ora-15335-ora-15130-ora-15066-ora-15196.html" rel="bookmark" class="crp_title">ORA-15335: ASM metadata corruption detected in disk group ‘DATA’</a></li><li><a href="https://www.xifenfei.com/2019/11/ora-15196.html" rel="bookmark" class="crp_title">ORA-15196: invalid ASM block header [kfc.c:26368] [endian_kfbh]故障处理</a></li></ul></div>
				<p><strong>您可能还对下面的文章感兴趣：</strong></p>
				<p><ol><li><a href="https://blogread.cn/it/article.php?id=6565" target="_blank">找回linux丢失的磁盘空间</a> [2013-07-30 13:50:50]</li><li><a href="https://blogread.cn/it/article.php?id=5475" target="_blank">为什么Linux不需要磁盘碎片整理</a> [2012-06-14 13:53:14]</li><li><a href="https://blogread.cn/it/article.php?id=4834" target="_blank">ubuntu linux 下硬盘坏道的检测与修复</a> [2012-01-27 17:45:13]</li><li><a href="https://blogread.cn/it/article.php?id=2320" target="_blank">linux磁盘管理学习笔记（中）：df命令、du命令</a> [2010-08-26 09:33:30]</li><li><a href="https://blogread.cn/it/article.php?id=2319" target="_blank">linux磁盘管理学习笔记（上）</a> [2010-08-26 09:32:08]</li><li><a href="https://blogread.cn/it/article.php?id=2096" target="_blank">Linux下硬盘格式化的相关命令Partprobe</a> [2010-07-27 23:15:32]</li></ol></p>]]></description>
		<content><![CDATA[该文章是一篇Oracle RAC集群故障排查案例，详细分析了因错误配置ASM磁盘发现字符串导致的集群无法启动问题。故障根源是管理员将asm_diskstring参数设置为包含系统设备映射符号链接的路径（如/dev/dm*和/dev/mapper/*），导致ASM在发现磁盘时检测到同一物理磁盘的重复路径（如/dev/mapper/mpathi与/dev/dm-3），进而无法挂载投票磁盘组（CRS），致使集群资源管理器（CRS）启动失败。

解决该故障的核心步骤包括：首先，通过创建一个仅包含正确磁盘路径（如/dev/mapper/*）的临时pfile，然后基于此pfile重新创建ASM SPFILE，以自动更新GPnP配置文件中的DiscoveryString和SPFile路径。此操作会清除原有的投票磁盘信息，因此修复后需使用kfed工具验证磁盘头信息，并通过crsctl replace votedisk命令重新配置投票磁盘。最终，集群得以正常启动。文章强调了正确配置asm_diskstring的重要性，并提供了通过重建SPFILE来修正配置错误的完整技术方案。]]></content>
	</item>
	<item>
		<title>从 Sublime Text 到 Zed</title>
		<link>https://blogread.cn/it/article.php?id=8587</link>
		<author>唐巧</author>
		<pubDate>2026-06-03 09:03:24</pubDate>
		<category domain="https://blogread.cn/it/category.php?id=4">AI</category>
		<guid>https://blogread.cn/it/article.php?id=8587</guid>
		<comments>https://blogread.cn/it/article.php?id=8587#comment</comments>
		<description><![CDATA[<p><strong>标签：</strong>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=Claude" target="_blank">Claude</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=GPT" target="_blank">GPT</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=Rust" target="_blank">Rust</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=Zed" target="_blank">Zed</a></p><h2><a href="https://blog.devtang.com/2026/05/16/open-in-zed-from-finder/#%E4%BB%8E-Sublime-Text-%E5%88%B0-Zed" class="headerlink" title="从 Sublime Text 到 Zed"></a>从 Sublime Text 到 Zed</h2><p>我用 Sublime Text 很多年了。它曾经是那个年代最好的编辑器：启动极快、界面干净、插件生态丰富。但这两年随着 AI 辅助编码成为日常，Sublime Text 的 AI 集成体验始终差一口气，我开始认真考虑迁移。</p><p><a href="https://zed.dev/">Zed</a> 是一款由 Atom 和 Tree-sitter 的原班人马打造的编辑器，用 Rust 编写，主打两件事：<strong>极致的性能</strong>和<strong>原生的 AI 协作</strong>。它的启动速度和文件响应比 VS Code 快得多，同时内置了对 Claude、GPT 等模型的支持，不需要额外装插件。界面风格上它和 Sublime Text 一脉相承——极简、无干扰——这让我迁移的心理成本低了不少。</p><img src="https://blog.devtang.com/images/zed.jpg"><p>用了一段时间之后，感觉不错，分享给大家。</p><h2><a href="https://blog.devtang.com/2026/05/16/open-in-zed-from-finder/#%E5%AE%89%E8%A3%85-Zed-CLI" class="headerlink" title="安装 Zed CLI"></a>安装 Zed CLI</h2><p>打开 Zed，按下 <code>cmd+shift+p</code>，输入 <code>Install</code>，选择安装 cli。这一步会把 <code>zed</code> 命令行工具安装到 <code>~/.local/bin/zed</code>，后面脚本依赖它来打开编辑器。</p><img src="https://blog.devtang.com/images/zed-1.jpg"><p>安装完成后在终端验证一下：</p><figure class="highlight bash"><pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">zed --version</code></pre></figure><p>装好 CLI 之后，日常在终端里就能直接调起 Zed，几个最常用的姿势：</p><figure class="highlight bash"><pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext"># 用当前目录作为工作区打开
zed .

# 打开单个文件
zed README.md

# 打开多个文件，会在同一窗口里以多标签呈现
zed src/main.rs src/lib.rs

# 新开一个独立窗口，不复用当前窗口
zed -n .

# 等待文件关闭后再返回（常用于 git commit、crontab -e 等场景）
zed -w COMMIT_EDITMSG

# 对比两个文件的差异
zed --diff a.txt b.txt</code></pre></figure><h2><a href="https://blog.devtang.com/2026/05/16/open-in-zed-from-finder/#%E5%9C%A8-Finder-%E7%9A%84%E5%8F%B3%E9%94%AE%E8%8F%9C%E5%8D%95%E4%B8%AD%E9%9B%86%E6%88%90-Zed" class="headerlink" title="在 Finder 的右键菜单中集成 Zed"></a>在 Finder 的右键菜单中集成 Zed</h2><p>macOS 内置了一套叫**快速操作（Quick Actions）**的机制，配合 Automator 可以把任意脚本挂到 Finder 的右键菜单里，可以做到把 Zed 集成到菜单里。</p><h3><a href="https://blog.devtang.com/2026/05/16/open-in-zed-from-finder/#%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86" class="headerlink" title="实现原理"></a>实现原理</h3><p>macOS 的服务（Services）机制允许我们把一个 <code>.workflow</code> 文件注册为系统服务。当用户在 Finder 里右键某个文件夹时，系统会把选中的路径传入这个 workflow，由里面的 Shell 脚本来处理。</p><p>我们只需要让脚本调用 <code>zed</code> 命令打开对应路径即可。</p><h3><a href="https://blog.devtang.com/2026/05/16/open-in-zed-from-finder/#%E5%AE%89%E8%A3%85%E6%AD%A5%E9%AA%A4" class="headerlink" title="安装步骤"></a>安装步骤</h3><h4><a href="https://blog.devtang.com/2026/05/16/open-in-zed-from-finder/#%E7%AC%AC%E4%B8%80%E6%AD%A5%EF%BC%9A%E5%88%9B%E5%BB%BA-Automator-Workflow" class="headerlink" title="第一步：创建 Automator Workflow"></a>第一步：创建 Automator Workflow</h4><p>用下面这个一键生成脚本，在终端执行后会直接在当前目录产出 <code>OpenInZed.workflow</code>：</p><figure class="highlight bash"><pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">#!/bin/bash
# 一键生成 OpenInZed.workflow

set -e
DEST="$HOME/Desktop/OpenInZed.workflow/Contents"
mkdir -p "$DEST"

cat &gt; "$DEST/Info.plist" &lt;&lt; 'PLIST'
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;dict&gt;
  &lt;key&gt;NSServices&lt;/key&gt;
  &lt;array&gt;
    &lt;dict&gt;
      &lt;key&gt;NSMenuItem&lt;/key&gt;
      &lt;dict&gt;
        &lt;key&gt;default&lt;/key&gt;
        &lt;string&gt;在 Zed 中打开&lt;/string&gt;
      &lt;/dict&gt;
      &lt;key&gt;NSMessage&lt;/key&gt;
      &lt;string&gt;runWorkflowAsService&lt;/string&gt;
      &lt;key&gt;NSRequiredContext&lt;/key&gt;
      &lt;dict&gt;
        &lt;key&gt;NSApplicationIdentifier&lt;/key&gt;
        &lt;string&gt;com.apple.finder&lt;/string&gt;
      &lt;/dict&gt;
      &lt;key&gt;NSSendFileTypes&lt;/key&gt;
      &lt;array&gt;
        &lt;string&gt;public.folder&lt;/string&gt;
      &lt;/array&gt;
    &lt;/dict&gt;
  &lt;/array&gt;
&lt;/dict&gt;
&lt;/plist&gt;
PLIST

python3 - &lt;&lt; 'PYEOF'
content = open('/dev/stdin').read() if False else r"""&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;dict&gt;
  &lt;key&gt;AMApplicationBuild&lt;/key&gt;&lt;string&gt;521.1&lt;/string&gt;
  &lt;key&gt;AMApplicationVersion&lt;/key&gt;&lt;string&gt;2.10&lt;/string&gt;
  &lt;key&gt;AMDocumentVersion&lt;/key&gt;&lt;string&gt;2&lt;/string&gt;
  &lt;key&gt;actions&lt;/key&gt;
  &lt;array&gt;
    &lt;dict&gt;
      &lt;key&gt;action&lt;/key&gt;
      &lt;dict&gt;
        &lt;key&gt;ActionBundlePath&lt;/key&gt;
        &lt;string&gt;/System/Library/Automator/Run Shell Script.action&lt;/string&gt;
        &lt;key&gt;ActionName&lt;/key&gt;&lt;string&gt;Run Shell Script&lt;/string&gt;
        &lt;key&gt;ActionParameters&lt;/key&gt;
        &lt;dict&gt;
          &lt;key&gt;COMMAND_STRING&lt;/key&gt;
          &lt;string&gt;for f in "$@"
do
  if [ -d "$f" ]; then TARGET="$f"; else TARGET=$(dirname "$f"); fi
  if command -v zed &amp;amp;&gt;/dev/null; then
    zed -n "$TARGET"
  elif [ -x "$HOME/.local/bin/zed" ]; then
    "$HOME/.local/bin/zed" -n "$TARGET"
  else
    open -na "Zed" --args "$TARGET"
  fi
done&lt;/string&gt;
          &lt;key&gt;CheckedForUserDefaultShell&lt;/key&gt;&lt;true/&gt;
          &lt;key&gt;inputMethod&lt;/key&gt;&lt;integer&gt;1&lt;/integer&gt;
          &lt;key&gt;shell&lt;/key&gt;&lt;string&gt;/bin/bash&lt;/string&gt;
          &lt;key&gt;source&lt;/key&gt;&lt;string&gt;&lt;/string&gt;
        &lt;/dict&gt;
        &lt;key&gt;BundleIdentifier&lt;/key&gt;
        &lt;string&gt;com.apple.automator.runShellScript&lt;/string&gt;
        &lt;key&gt;CFBundleVersion&lt;/key&gt;&lt;string&gt;2.0.3&lt;/string&gt;
        &lt;key&gt;CanShowSelectedItemsWhenRun&lt;/key&gt;&lt;false/&gt;
        &lt;key&gt;CanShowWhenRun&lt;/key&gt;&lt;true/&gt;
        &lt;key&gt;isViewVisible&lt;/key&gt;&lt;true/&gt;
      &lt;/dict&gt;
      &lt;key&gt;isViewVisible&lt;/key&gt;&lt;true/&gt;
    &lt;/dict&gt;
  &lt;/array&gt;
  &lt;key&gt;connectors&lt;/key&gt;&lt;dict/&gt;
  &lt;key&gt;workflowMetaData&lt;/key&gt;
  &lt;dict&gt;
    &lt;key&gt;serviceInputTypeIdentifier&lt;/key&gt;
    &lt;string&gt;com.apple.Automator.fileSystemObject.folder&lt;/string&gt;
    &lt;key&gt;serviceOutputTypeIdentifier&lt;/key&gt;
    &lt;string&gt;com.apple.Automator.nothing&lt;/string&gt;
    &lt;key&gt;serviceProcessesInput&lt;/key&gt;&lt;integer&gt;0&lt;/integer&gt;
    &lt;key&gt;workflowTypeIdentifier&lt;/key&gt;
    &lt;string&gt;com.apple.Automator.servicesMenu&lt;/string&gt;
  &lt;/dict&gt;
&lt;/dict&gt;
&lt;/plist&gt;"""
import os
dest = os.path.expanduser("~/Desktop/OpenInZed.workflow/Contents/document.wflow")
with open(dest, "w") as f:
    f.write(content)
print("document.wflow written")
PYEOF

echo "✅ OpenInZed.workflow 已生成到桌面，双击即可安装"</code></pre></figure><h4><a href="https://blog.devtang.com/2026/05/16/open-in-zed-from-finder/#%E7%AC%AC%E4%BA%8C%E6%AD%A5%EF%BC%9A%E5%AE%89%E8%A3%85-Workflow" class="headerlink" title="第二步：安装 Workflow"></a>第二步：安装 Workflow</h4><p>把生成好的 <code>OpenInZed.workflow</code> 双击打开，系统弹出确认框后点击**「安装」**即可。</p><h4><a href="https://blog.devtang.com/2026/05/16/open-in-zed-from-finder/#%E7%AC%AC%E4%B8%89%E6%AD%A5%EF%BC%9A%E5%88%B7%E6%96%B0%E6%9C%8D%E5%8A%A1%E7%BC%93%E5%AD%98" class="headerlink" title="第三步：刷新服务缓存"></a>第三步：刷新服务缓存</h4><p>安装后在终端执行一次：</p><figure class="highlight bash"><pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">/System/Library/CoreServices/pbs -flush</code></pre></figure><p>这会强制 macOS 重新扫描已安装的服务，避免右键菜单没有立刻出现新选项。</p><h4><a href="https://blog.devtang.com/2026/05/16/open-in-zed-from-finder/#%E7%AC%AC%E5%9B%9B%E6%AD%A5%EF%BC%9A%E5%9C%A8%E7%B3%BB%E7%BB%9F%E8%AE%BE%E7%BD%AE%E4%B8%AD%E7%A1%AE%E8%AE%A4%E5%90%AF%E7%94%A8" class="headerlink" title="第四步：在系统设置中确认启用"></a>第四步：在系统设置中确认启用</h4><p>打开 <strong>系统设置 → 键盘 → 键盘快捷键 → 服务 → 文件和文件夹</strong>，找到「在 Zed 中打开」并勾选。</p><img src="https://blog.devtang.com/images/zed-2.jpg"><h3><a href="https://blog.devtang.com/2026/05/16/open-in-zed-from-finder/#%E4%BD%BF%E7%94%A8%E6%95%88%E6%9E%9C" class="headerlink" title="使用效果"></a>使用效果</h3><p>配置完成后，在 Finder 中右键任意文件夹，选择 <strong>快速操作 → 在 Zed 中打开</strong>，Zed 会直接以该目录为工作区启动。</p><p>如果右键的是普通文件而非文件夹，脚本会自动取其父目录打开，不会报错。</p><h3><a href="https://blog.devtang.com/2026/05/16/open-in-zed-from-finder/#%E5%87%A0%E7%82%B9%E8%AF%B4%E6%98%8E" class="headerlink" title="几点说明"></a>几点说明</h3><p><strong>为什么不用 Finder 扩展（FinderSync）？</strong> FinderSync 需要开发一个完整的 Xcode 项目并签名，成本远高于 Automator workflow，对于这个简单需求来说完全没必要。</p><p><strong>为什么脚本里要三重兜底？</strong> Zed 的 CLI 路径在不同安装方式下不一样。通过 <code>Zed → Install CLI</code> 安装的会在 <code>~/.local/bin/zed</code>，手动加到 PATH 的会被 <code>command -v zed</code> 找到，而 <code>open -a "Zed"</code> 则是最后的保险，只要 Zed.app 在 <code>/Applications</code> 里就一定能用。</p><p><strong>为什么脚本里都加了 <code>-n</code>？</strong> Zed CLI 的默认行为是把新打开的目录加到当前已聚焦窗口的侧边栏，而不是新开一个窗口。从 Finder 触发时这种”复用”会让人误以为上一个工作区被覆盖、甚至”实例被隐藏”了。加上 <code>-n</code>（<code>--new</code>）就能强制开一个独立窗口，原工作区保持原样。</p><p><strong>如何卸载？</strong> 删除 <code>~/Library/Services/OpenInZed.workflow</code> 这个文件夹即可，不会留下任何残余。</p>
				<p><strong>您可能还对下面的文章感兴趣：</strong></p>
				<p><ol><li><a href="https://blogread.cn/it/article.php?id=6560" target="_blank">面向“接口”编程和面向“实现”编程</a> [2013-07-30 13:39:02]</li></ol></p>]]></description>
		<content><![CDATA[作者长期使用 Sublime Text，因其快速启动和丰富插件生态而满意，但随着 AI 辅助编码成为常态，Sublime Text 的 AI 集成体验不足，促使其迁移到 Zed。Zed 由 Atom 和 Tree-sitter 原团队开发，采用 Rust 编写，以极致性能和原生 AI 协作为核心优势，启动速度与文件响应优于 VS Code，并内置 Claude、GPT 等模型支持，无需额外插件。其极简界面与 Sublime Text 相似，降低了迁移成本。

安装 Zed CLI 是首要步骤：在 Zed 中通过命令面板执行安装，将 CLI 工具置于 ~/.local/bin/zed，之后可在终端使用如 `zed .` 打开目录或 `zed --diff` 比较文件等命令。为提升效率，作者进一步将 Zed 集成到 macOS Finder 右键菜单，利用 Automator 快速操作机制：首先通过一键脚本生成 OpenInZed.workflow 文件，其中包含 Shell 脚本调用 Zed 打开选中路径；双击安装 workflow 并刷新服务缓存（执行 `/System/Library/CoreServices/pbs -flush`），最后在系统设置中启用该服务。配置后，右键文件夹或文件即可选择“在 Zed 中打开”，脚本自动处理路径。

技术细节上，脚本采用三重兜底逻辑以兼容不同安装方式（如 CLI 路径检测、PATH 变量、应用程序直接调用），并添加 `-n`]]></content>
	</item>
	<item>
		<title>了解 Claude Code 的提示词工程</title>
		<link>https://blogread.cn/it/article.php?id=8586</link>
		<author>唐巧</author>
		<pubDate>2026-06-03 09:03:24</pubDate>
		<category domain="https://blogread.cn/it/category.php?id=4">AI</category>
		<guid>https://blogread.cn/it/article.php?id=8586</guid>
		<comments>https://blogread.cn/it/article.php?id=8586#comment</comments>
		<description><![CDATA[<p><strong>标签：</strong>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=ccglass" target="_blank">ccglass</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=Claude%20Code" target="_blank">Claude Code</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=Opus%204.7" target="_blank">Opus 4.7</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=%E6%8F%90%E7%A4%BA%E8%AF%8D%E5%B7%A5%E7%A8%8B" target="_blank">提示词工程</a></p><p>虽然同样是调用 Opus 4.7 模型，但是不同的编程工具展现的表现确不一样。就拿 Claude Code, Cursor, OpenCode，Windsurf 这几个产品来说，显然 Claude Code 在程序员中的口碑更好。</p><p>那 Claude Code 与其它编程工具的差异性在哪儿呢？其中有一个重要的环节就是：提示词工程(prompt engine)。</p><p>正好我今天看到了 <a href="https://github.com/jianshuo/ccglass">ccglass</a> 这个开源项目，它可以把 Claude Code 的提示词通过网络请求截取出来，于是我试了一下，给大家分享一下我看到的有趣的地方。</p><p>整个提示词分为：系统层、消息层、工具层。这三层的提示词是拼接在一起发给服务器的。</p><h2><a href="https://blog.devtang.com/2026/05/22/inspect-claude-code-through-ccglass/#%E7%B3%BB%E7%BB%9F%E5%B1%82" class="headerlink" title="系统层"></a>系统层</h2><p>我们先看系统层，这一层规定了 Claude Code 的人设，工作原则和方法，以及记忆。</p><h3><a href="https://blog.devtang.com/2026/05/22/inspect-claude-code-through-ccglass/#%E8%91%97%E5%90%8D%E7%9A%84-cch-header" class="headerlink" title="著名的 cch header"></a>著名的 cch header</h3><p>在提示词的最顶部，你能看到这样一行：</p><figure class="highlight plaintext"><pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">x-anthropic-billing-header: cc_version=2.1.148.90a; cc_entrypoint=cli; cch=06d7a;</code></pre></figure><p>这行最后的 cch 参数，就是造成 claude code 配置别的大语言模型缓存失效的元凶。因为模型调用的缓存是基于“前缀”的，如果你的提示词前面都没变，只是在最后加了一句新的对话。那么前面的缓存都会命中。但是 claude code 在今年 2 月的升级中加入了这个参数，在每轮对话中 cch 参数都会变，如果别的模型不特殊处理这个参数，就会造成所有缓存失效。</p><h3><a href="https://blog.devtang.com/2026/05/22/inspect-claude-code-through-ccglass/#%E4%BA%BA%E8%AE%BE" class="headerlink" title="人设"></a>人设</h3><p>告诉它是官方的，并且主要是做软件工程相关的任务。</p><p>提示词如下：</p><figure class="highlight plaintext"><pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">You are Claude Code, Anthropic's official CLI for Claude.

You are an interactive agent that helps users with software engineering tasks.</code></pre></figure><h3><a href="https://blog.devtang.com/2026/05/22/inspect-claude-code-through-ccglass/#%E7%A6%81%E6%AD%A2%E5%B9%B2%E5%9D%8F%E4%BA%8B" class="headerlink" title="禁止干坏事"></a>禁止干坏事</h3><p>提示词中明确禁止了做破坏性（比如 DoS 攻击）的事情，一些高风险的事情，也会要求用户澄清用处。</p><p>提示词如下：</p><figure class="highlight plaintext"><pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">Refuse requests for destructive techniques, DoS attacks, mass targeting, supply chain compromise, or detection evasion for malicious purposes. Dual-use security tools (C2 frameworks, credential testing, exploit development) require clear authorization context: pentesting engagements, CTF competitions, security research, or defensive use cases.</code></pre></figure><h3><a href="https://blog.devtang.com/2026/05/22/inspect-claude-code-through-ccglass/#%E8%AE%B0%E5%BF%86" class="headerlink" title="记忆"></a>记忆</h3><p>提示词中为每个目录都创建了记忆，让 Agent 需要的时候把记忆保存下来。</p><p>像我的这个实验项目，记忆文件就在 <code>/Users/tangqiao/.claude/projects/-Users-tangqiao-ccglass/memory/</code>。</p><p>提示词如下：</p><figure class="highlight plaintext"><pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">You have a persistent, file-based memory system at `/Users/tangqiao/.claude/projects/-Users-tangqiao-ccglass/memory/`. This directory already exists — write to it directly with the Write tool (do not run mkdir or check for its existence).

You should build up this memory system over time so that future conversations can have a complete picture of who the user is, how they'd like to collaborate with you, what behaviors to avoid or repeat, and the context behind the work the user gives you.

If the user explicitly asks you to remember something, save it immediately as whichever type fits best. If they ask you to forget something, find and remove the relevant entry.</code></pre></figure><p>关于记忆，提示词中还规定了什么时候保存，怎么保存。</p><p>提示词如下：</p><figure class="highlight plaintext"><pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">## How to save memories

Saving a memory is a two-step process:

**Step 1** — write the memory to its own file (e.g., `user_role.md`, `feedback_testing.md`) using this frontmatter format:

此处省略

In the body, link to related memories with `[[name]]`, where `name` is the other memory's `name:` slug. Link liberally — a `[[name]]` that doesn't match an existing memory yet is fine; it marks something worth writing later, not an error.

**Step 2** — add a pointer to that file in `MEMORY.md`. `MEMORY.md` is an index, not a memory — each entry should be one line, under ~150 characters: `- [Title](file.md) — one-line hook`. It has no frontmatter. Never write memory content directly into `MEMORY.md`.</code></pre></figure><h3><a href="https://blog.devtang.com/2026/05/22/inspect-claude-code-through-ccglass/#%E5%8F%AA%E6%9C%89-200-%E8%A1%8C%E7%9A%84%E8%AE%B0%E5%BF%86%E9%99%90%E9%A2%9D" class="headerlink" title="只有 200 行的记忆限额"></a>只有 200 行的记忆限额</h3><p>提示词如下：</p><figure class="highlight plaintext"><pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">`MEMORY.md` is always loaded into your conversation context — lines after 200 will be truncated, so keep the index concise</code></pre></figure><h2><a href="https://blog.devtang.com/2026/05/22/inspect-claude-code-through-ccglass/#%E6%B6%88%E6%81%AF%E5%B1%82" class="headerlink" title="消息层"></a>消息层</h2><p>这一层定义了它能使用的各种工具。</p><h3><a href="https://blog.devtang.com/2026/05/22/inspect-claude-code-through-ccglass/#skill" class="headerlink" title="skill"></a>skill</h3><p>所有的 skill 在这一层被提示词引入，你能看到这样的提示词开头：</p><figure class="highlight plaintext"><pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">The following skills are available for use with the Skill tool:</code></pre></figure><p>我因为之前装过 hyperframes，所以我看到了大量 hyperframes 的 skill。</p><p>我这才知道 hyperframes 这个框架一共有 16 个 skill，每次我用 claude code，这些 skill 都被注入到了提示词。</p><p>hyperframes 引入了一共有多少提示词呢？给大家看一下：</p><figure class="highlight plaintext"><pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">- hyperframes: Create video compositions, animations, title cards, overlays, captions, voiceovers, audio-reactive visuals, and scene transitions in HyperFrames HTML. Use when asked to build any HTML-based video content, add captions or subtitles synced to audio, generate text-to-speech narration, create audio-reactive animation (beat sync, glow, pulse driven by music), add animated text highlighting (marker sweeps, hand-drawn circles, burst lines, scribble, sketchout), or add transitions between scenes (crossfades, wipes, reveals, shader transitions). Covers composition authoring, timing, media, and the full video production workflow. For CLI commands (init, lint, preview, render, transcribe, tts) see the hyperframes-cli skill.
- website-to-hyperframes: Capture a website and create a HyperFrames video from it. Use when: (1) a user provides a URL and wants a video, (2) someone says "capture this site", "turn this into a video", "make a promo from my site", (3) the user wants a social ad, product tour, or any video based on an existing website, (4) the user shares a link and asks for any kind of video content. Even if the user just pastes a URL — this is the skill to use.
- remotion-to-hyperframes: Translate an existing Remotion (React-based) video composition into a HyperFrames HTML composition. Use ONLY when the user explicitly asks to port, convert, migrate, translate, or rewrite a Remotion composition as HyperFrames — for example "port my Remotion project to HyperFrames", "convert this Remotion code to HyperFrames", "migrate from Remotion", "translate this Remotion comp", or "rewrite this as HyperFrames HTML". Do NOT use when (a) the user is authoring a NEW HyperFrames composition, even if they have or are A/B-testing a similar Remotion video; (b) the user mentions Remotion in passing without asking for migration; (c) the user shares Remotion code as reference material rather than asking for a translation; (d) the user asks for "the same video as my Remotion one" without explicitly asking to migrate the source — treat that as a fresh HyperFrames build. When in doubt, default to authoring a native HyperFrames composition with the `hyperframes` skill instead. Skill detects unsupported patterns (useState, useEffect with side effects, async calculateMetadata, third-party React component libraries, `@remotion/lambda` features) and recommends the runtime interop escape hatch instead of attempting a lossy translation.
- hyperframes-cli: HyperFrames CLI tool — hyperframes init, lint, inspect, preview, render, transcribe, tts, doctor, browser, info, upgrade, compositions, docs, benchmark. Use when scaffolding a project, linting, validating, inspecting visual layout in compositions, previewing in the studio, rendering to video, transcribing audio, generating TTS, or troubleshooting the HyperFrames environment.
- waapi: Web Animations API adapter patterns for HyperFrames. Use when authoring element.animate() motion, Animation currentTime seeking, document.getAnimations(), KeyframeEffect timing, fill modes, or native browser animations that must render deterministically in HyperFrames.
- animejs: Anime.js adapter patterns for HyperFrames. Use when writing Anime.js animations or timelines inside HyperFrames compositions, registering animations on window.__hfAnime, making Anime.js seek-driven and deterministic, or translating Anime.js examples into render-safe HyperFrames HTML.
- hyperframes-registry: Install and wire registry blocks and components into HyperFrames compositions. Use when running hyperframes add, installing a block or component, wiring an installed item into index.html, or working with hyperframes.json. Covers the add command, install locations, block sub-composition wiring, component snippet merging, and registry discovery.
- three: Three.js and WebGL adapter patterns for HyperFrames. Use when creating deterministic Three.js scenes, WebGL canvas layers, AnimationMixer timelines, camera motion, shader-driven visuals, or canvas renders that respond to HyperFrames hf-seek events.
- tailwind: Tailwind CSS v4.2 browser-runtime patterns for HyperFrames compositions. Use when scaffolding or editing projects created with `hyperframes init --tailwind`, writing Tailwind utility classes in composition HTML, adding CSS-first Tailwind v4 theme tokens, debugging v3 vs v4 syntax, or deciding when to compile Tailwind to CSS instead of using the browser runtime.
- hyperframes-media: Asset preprocessing for HyperFrames compositions — text-to-speech narration (Kokoro), audio/video transcription (Whisper), and background removal for transparent overlays (u2net). Use when generating voiceover from text, transcribing speech for captions, removing the background from a video or image to use as a transparent overlay, choosing a TTS voice or whisper model, or chaining these (TTS → transcribe → captions). Each command downloads its own model on first run.
- lottie: Lottie and dotLottie adapter patterns for HyperFrames. Use when embedding lottie-web JSON animations, .lottie files, @lottiefiles/dotlottie-web players, registering instances on window.__hfLottie, or making After Effects exports deterministic in HyperFrames.
- gsap: GSAP animation reference for HyperFrames. Covers gsap.to(), from(), fromTo(), easing, stagger, defaults, timelines (gsap.timeline(), position parameter, labels, nesting, playback), and performance (transforms, will-change, quickTo). Use when writing GSAP animations in HyperFrames compositions.
- css-animations: CSS animation adapter patterns for HyperFrames. Use when authoring CSS keyframes, animation-delay based timing, animation-fill-mode, animation-play-state, or CSS-only motion that HyperFrames must seek deterministically during preview and rendering.</code></pre></figure><p>怎么说呢？反正我立马把它卸载了。我给 claude code 的提示词如下：</p><figure class="highlight plaintext"><pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">我曾经用 npx skills add heygen-com/hyperframes 命令增加了 hyperframes skill, 现在我希望你帮我把这个 skill 删除掉。</code></pre></figure><h3><a href="https://blog.devtang.com/2026/05/22/inspect-claude-code-through-ccglass/#%E7%94%A8%E6%88%B7%E4%BA%BA%E8%AE%BE%E5%92%8C%E6%97%B6%E9%97%B4" class="headerlink" title="用户人设和时间"></a>用户人设和时间</h3><p>其实 claude code 知道你的信息，相关提示词如下：</p><figure class="highlight plaintext"><pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">&lt;system-reminder&gt;
As you answer the user's questions, you can use the following context:
# userEmail
The user's email address is xxx@xxx.com .
# currentDate
Today's date is 2026/05/22.

IMPORTANT: this context may or may not be relevant to your tasks. You should not respond to this context unless it is highly relevant to your task.
&lt;/system-reminder&gt;</code></pre></figure><h3><a href="https://blog.devtang.com/2026/05/22/inspect-claude-code-through-ccglass/#%E7%94%A8%E6%88%B7%E7%9A%84%E9%97%AE%E9%A2%98" class="headerlink" title="用户的问题"></a>用户的问题</h3><p>用户输入的问题被放在了这里。</p><p>注意，每轮对话，它会把之前所有的对话都带上，直到上下文超限，才会进行压缩。</p><p>有意思的是，你能看到它不但带上了我的输入，还带上了工具执行的结果。所以对话的上下文增长的速度也非常快。</p><p>就比如我让它删除 hyperframes 的输入，它因为调用了 10 来次工具，使得我已经无法在这儿把所有的上下文贴给大家了。</p><h2><a href="https://blog.devtang.com/2026/05/22/inspect-claude-code-through-ccglass/#%E5%B7%A5%E5%85%B7%E5%B1%82" class="headerlink" title="工具层"></a>工具层</h2><p>有意思的是，工具层虽然也是可以缓存的部分，但是 claude code 把它放在了消息层后面。我猜这也是一个对抗其它模型缓存的办法，其它模型需要主动地把工具层部分的提示词也单独计算，否则它一定会因为夹在中间的用户输入而失效（心机重的 Anthropic 啊！）。</p><h3><a href="https://blog.devtang.com/2026/05/22/inspect-claude-code-through-ccglass/#%E9%BC%93%E5%8A%B1%E4%BD%BF%E7%94%A8%E5%AD%90-Agent" class="headerlink" title="鼓励使用子 Agent"></a>鼓励使用子 Agent</h3><figure class="highlight plaintext"><pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">Launch a new agent to handle complex, multi-step tasks. Each agent type has specific capabilities and tools available to it.</code></pre></figure><h3><a href="https://blog.devtang.com/2026/05/22/inspect-claude-code-through-ccglass/#%E5%A6%82%E4%BD%95%E6%8F%90%E9%97%AE" class="headerlink" title="如何提问"></a>如何提问</h3><p>教大模型如何向用户提问，Claude code 有时候会弹出单选/复选框，就是这个提示词在起作用。</p><figure class="highlight plaintext"><pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">Use this tool when you need to ask the user questions during execution. This allows you to:
1. Gather user preferences or requirements
2. Clarify ambiguous instructions
3. Get decisions on implementation choices as you work
4. Offer choices to the user about what direction to take.

Usage notes:
- Users will always be able to select "Other" to provide custom text input
- Use multiSelect: true to allow multiple answers to be selected for a question
- If you recommend a specific option, make that the first option in the list and add "(Recommended)" at the end of the label</code></pre></figure><h3><a href="https://blog.devtang.com/2026/05/22/inspect-claude-code-through-ccglass/#bash" class="headerlink" title="bash"></a>bash</h3><p>所有的 bash 命令，也会在这一层被介绍给 Claude code 具体的使用方法。</p><p>比如 Read 命令的提示词如下：</p><figure class="highlight plaintext"><pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">Reads a file from the local filesystem. You can access any file directly by using this tool.
Assume this tool is able to read all files on the machine. If the User provides a path to a file assume that path is valid. It is okay to read a file that does not exist; an error will be returned.

Usage:
- The file_path parameter must be an absolute path, not a relative path
- By default, it reads up to 2000 lines starting from the beginning of the file
- When you already know which part of the file you need, only read that part. This can be important for larger files.
- Results are returned using cat -n format, with line numbers starting at 1
- This tool allows Claude Code to read images (eg PNG, JPG, etc). When reading an image file the contents are presented visually as Claude Code is a multimodal LLM.
- This tool can read PDF files (.pdf). For large PDFs (more than 10 pages), you MUST provide the pages parameter to read specific page ranges (e.g., pages: "1-5"). Reading a large PDF without the pages parameter will fail. Maximum 20 pages per request.
- This tool can read Jupyter notebooks (.ipynb files) and returns all cells with their outputs, combining code, text, and visualizations.
- This tool can only read files, not directories. To list files in a directory, use the registered shell tool.
- You will regularly be asked to read screenshots. If the user provides a path to a screenshot, ALWAYS use this tool to view the file at the path. This tool will work with all temporary file paths.
- If you read a file that exists but has empty contents you will receive a system reminder warning in place of file contents.
- Do NOT re-read a file you just edited to verify — Edit/Write would have errored if the change failed, and the harness tracks file state for you.

— schema —
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "file_path": {
      "description": "The absolute path to the file to read",
      "type": "string"
    },
    "offset": {
      "description": "The line number to start reading from. Only provide if the file is too large to read at once",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "limit": {
      "description": "The number of lines to read. Only provide if the file is too large to read at once.",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    },
    "pages": {
      "description": "Page range for PDF files (e.g., \"1-5\", \"3\", \"10-20\"). Only applicable to PDF files. Maximum 20 pages per request.",
      "type": "string"
    }
  },
  "required": [
    "file_path"
  ],
  "additionalProperties": false
}</code></pre></figure><h3><a href="https://blog.devtang.com/2026/05/22/inspect-claude-code-through-ccglass/#MCP" class="headerlink" title="MCP"></a>MCP</h3><p>所有的 MCP 在这一层被一一介绍。</p><p>比如这个 mcp__claude-in-chrome__tabs_create_mcp：</p><figure class="highlight plaintext"><pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">Creates a new empty tab in the MCP tab group. CRITICAL: You must get the context using tabs_context_mcp at least once before using other browser automation tools so you know what tabs exist.

— schema —
{
  "type": "object",
  "properties": {},
  "required": []
}</code></pre></figure><h3><a href="https://blog.devtang.com/2026/05/22/inspect-claude-code-through-ccglass/#%E8%B0%83%E7%94%A8-skill" class="headerlink" title="调用 skill"></a>调用 skill</h3><p>虽然 skill 是在消息层注入的，但是工具层教大模型什么时候调用 skill。</p><figure class="highlight plaintext"><pre class="blogread-code language-plaintext" data-lang="plaintext"><code class="language-plaintext">When users reference a "slash command" or "/&lt;something&gt;", they are referring to a skill. Use this tool to invoke it.

How to invoke:
- Set `skill` to the exact name of an available skill (no leading slash). For plugin-namespaced skills use the fully qualified `plugin:skill` form.
- Set `args` to pass optional arguments.</code></pre></figure><h2><a href="https://blog.devtang.com/2026/05/22/inspect-claude-code-through-ccglass/#%E7%BB%93%E6%9D%9F%E8%AF%AD" class="headerlink" title="结束语"></a>结束语</h2><p>最后给大家讲个题外话，ccglass 这个开源项目是百姓网CEO王建硕的作品，感谢王建硕先生！</p>
				<p><strong>您可能还对下面的文章感兴趣：</strong></p>
				<p><ol><li><a href="https://blogread.cn/it/article.php?id=8582" target="_blank">手搓一个 Agent 驱动的项目 Wiki 生成方案</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8517" target="_blank">Claude Code 从 AWS Bedrock 切换到 Team 订阅指南</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8497" target="_blank">SmartPerfetto 架构文章 Q&amp;amp;A：8 个深度技术问答</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8494" target="_blank">别再傻等了，给 Claude Code 装个通知铃铛</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8493" target="_blank">全程用 Claude Code 搓了一个 macOS 原生应用：SkillDeck</a> [2026-06-03 09:03:24]</li></ol></p>]]></description>
		<content><![CDATA[Claude Code 之所以在众多同模型的编程工具中脱颖而出，其关键差异之一在于其内部复杂且经过精心设计的提示词工程。通过截取分析其实际发送的提示词，可以清晰地看到其三层结构：系统层、消息层和工具层。

系统层为Claude Code设定了“Anthropic官方CLI软件工程师”的核心人设，并包含严格的行为准则，例如拒绝破坏性任务。此外，该层为每个项目目录都配置了基于文件的记忆系统，以保存上下文信息。一个值得注意的细节是，Claude Code会在请求头中加入一个动态变化的参数，这使得其他工具若不特殊处理会导致缓存失效。

消息层不仅包含用户的历史对话，还会注入用户安装的所有工具的详细说明。例如，安装hyperframes框架会带来大量特定技能的提示词，显著增加上下文长度。同时，系统会将用户的邮箱、当前日期等信息作为上下文提供给模型。

工具层则定义了模型可调用的具体工具及其使用方法，如鼓励使用子Agent处理复杂任务，以及如何通过提问工具向用户获取澄清信息。该层被巧妙地置于消息层之后，这可能是为了对抗其他模型的缓存机制。整个提示词架构展现了Claude Code如何通过精细的工程设计来引导模型行为、管理上下文并提升任务完成质量。]]></content>
	</item>
	<item>
		<title>「置顶」我做了什么</title>
		<link>https://blogread.cn/it/article.php?id=8585</link>
		<author>Gracker</author>
		<pubDate>2026-06-03 09:03:24</pubDate>
		<category domain="https://blogread.cn/it/category.php?id=24">移动开发</category>
		<guid>https://blogread.cn/it/article.php?id=8585</guid>
		<comments>https://blogread.cn/it/article.php?id=8585#comment</comments>
		<description><![CDATA[<p><strong>标签：</strong>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=AI" target="_blank">AI</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=Android" target="_blank">Android</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=SmartPerfetto" target="_blank">SmartPerfetto</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=TraceFix" target="_blank">TraceFix</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90" target="_blank">性能分析</a></p><p>这篇置顶页只做一件事：把我长期维护、正在推进、已经公开和暂未公开的项目集中到一个地方。范围包括 Android 性能分析、Perfetto 工具、AI 自动化、iOS App、Android Demo、测试套件、博客系列、社群和各个平台账号。</p><p>第一次来到这个博客，可以按需求直接跳转：学 Android 性能分析，看 Perfetto / Systrace 系列；找工具项目，看 SmartPerfetto、TraceFix、Android App Memory Analysis；了解 AI 如何参与知识管理和日常工作，看 OpenClaw 与 AI Field Notes；联系我或查看其它平台账号，看文末。</p><p>项目按四条线划：性能分析方向有 SmartPerfetto、Android App Memory Analysis、TraceFix、Perfetto Auto-Pin 这类工具，以及 High Performance Friends Circle 社群；AI 与自动化方向有 OpenClaw、AI Field Notes、Gracker Skills、Open Design；正在做的 App 包括 100Years、iBattery、Juju 三款 iOS 项目；内容项目则是博客、Android Weekly、知识星球三处主阵地。下面每个项目都会注明状态：日常维护、近期重点、还是已经暂停。</p><h2><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#%E4%B8%BB%E7%BA%BF%E6%96%B9%E5%90%91" class="headerlink" title="主线方向"></a>主线方向</h2><ul><li>Android 系统性能与稳定性：日常工作和长期写作都围绕 Android Framework、APM、Perfetto、Systrace、启动、卡顿、ANR、内存和功耗展开。</li><li>Perfetto 和 Trace 分析工具：把手工看 Trace 的经验做成工具、脚本、Skill 和可复用的分析流程。</li><li>AI Agent 与个人自动化：用 OpenClaw、Claude Code、Codex、Obsidian、Telegram 和定时任务管理资料、日报、知识库、写作和工程协作。</li><li>个人 App：做 iOS / Android 端的小产品，把真实需求做成完整 App。</li><li>技术写作与资料整理：维护 Android Performance 博客、Android Weekly、AI Field Notes 和若干公开 Skill。</li></ul><h2><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#%E5%85%AC%E5%BC%80%E9%A1%B9%E7%9B%AE" class="headerlink" title="公开项目"></a>公开项目</h2><h3><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#SmartPerfetto" class="headerlink" title="SmartPerfetto"></a>SmartPerfetto</h3><p><a href="https://github.com/Gracker/SmartPerfetto">SmartPerfetto</a> 是我现在投入最多的开源项目。它在 Perfetto 之上增加 AI Assistant：用户加载 trace 后，可以用自然语言提问，后端通过 <code>trace_processor_shell</code>、SQL、YAML Skill 和场景策略组织证据，再给出分析结论。</p><p>目前包含这些部分：</p><ul><li>Perfetto UI fork：<a href="https://github.com/Gracker/perfetto">Gracker/perfetto</a>，用于承载 AI Assistant 插件。</li><li>TypeScript 后端：负责 Agent 运行、MCP 工具调用、Skill 执行、报告生成和流式输出。</li><li>YAML Skill 与场景策略：把滑动、启动、ANR、Binder、CPU、内存、渲染管线等分析经验写成可执行单元。</li><li>相关长文：<a href="https://www.androidperformance.com/2026/04/29/SmartPerfetto-Open-Source-Perfetto-AI-Assistant/">SmartPerfetto 开源介绍</a>、<a href="https://www.androidperformance.com/2026/04/10/SmartPerfetto-Architecture-Deep-Dive/">架构深度解析</a>、<a href="https://www.androidperformance.com/2026/04/10/SmartPerfetto-Architecture-Deep-Dive-QA/">架构 Q&amp;A</a>。</li></ul><h3><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#Android-App-Memory-Analysis" class="headerlink" title="Android App Memory Analysis"></a>Android App Memory Analysis</h3><p><a href="https://github.com/Gracker/Android-App-Memory-Analysis">Android-App-Memory-Analysis</a> 是一个 Android App 内存分析工具集，目标是把 <code>dumpsys meminfo</code>、<code>dumpsys gfxinfo</code>、HPROF、smaps 等数据放在同一次分析里看。</p><p>适合这些场景：</p><ul><li>一键从连接设备上抓取目标 App 的内存相关数据。</li><li>关联 Java heap、Native memory、图形内存和进程视角数据。</li><li>输出可读报告，减少手工切换命令和文件的成本。</li><li>跟进 Android 16 / API 36、16 KB page size、edge-to-edge 等新版本兼容检查。</li></ul><h3><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#TraceFix" class="headerlink" title="TraceFix"></a>TraceFix</h3><p><a href="https://github.com/Gracker/TraceFix">TraceFix</a> 是一个 Android 字节码插桩插件，用来在编译期给方法自动插入 <code>android.os.Trace.beginSection/endSection</code>。</p><p>TraceFix 解决手工加 Trace 点太慢、容易漏点的问题。它在构建阶段自动给方法加 trace section，然后在 Perfetto 里查看调用耗时。当前已发布 Maven Central artifact：<code>io.github.gracker:TraceFix:0.1.0</code>。</p><h3><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#Perfetto-Auto-Pin" class="headerlink" title="Perfetto Auto-Pin"></a>Perfetto Auto-Pin</h3><p><a href="https://github.com/Gracker/Perfetto-AutoPin-For-Chrome">Perfetto-AutoPin-For-Chrome</a> 是一个 Chrome 插件，用来在 Perfetto UI 里自动 pin 常用轨道。</p><p>它内置 Frame Analysis、Startup Analysis、Input Response、Memory Analysis、Binder Calls、SurfaceFlinger、SystemUI、CPU 等场景预设，也支持自定义轨道集合。目标是减少打开 trace 后重复展开和 pin 轨道的动作。</p><h3><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#High-Performance-Friends-Circle" class="headerlink" title="High Performance Friends Circle"></a>High Performance Friends Circle</h3><p><a href="https://github.com/Gracker/Friends-Circle-Demo-Apks-For-Power-and-Performance-Test">Friends-Circle-Demo-Apks-For-Power-and-Performance-Test</a> 是一个基于朋友圈 UI 的 Android 性能和功耗测试平台。</p><p>这个仓库按性能负载测试套件设计：</p><ul><li>覆盖启动、滑动、页面切换等常见场景。</li><li>包含多种 UI 技术栈和多种负载强度。</li><li>用来观察主线程、RenderThread、SurfaceFlinger、CPU、功耗和帧表现。</li><li>配套 Flutter 版本：<a href="https://github.com/Gracker/Friends-Circle-Demo-Flutter-Apks-For-Power-and-Performance-Test">Friends-Circle-Demo-Flutter-Apks-For-Power-and-Performance-Test</a>。</li></ul><h3><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#Systrace-x2F-Perfetto-%E8%BE%85%E5%8A%A9%E5%B7%A5%E5%85%B7%E4%B8%8E%E5%8E%86%E5%8F%B2-Demo" class="headerlink" title="Systrace / Perfetto 辅助工具与历史 Demo"></a>Systrace / Perfetto 辅助工具与历史 Demo</h3><p>这里放长期工具和历史文章配套 Demo：</p><ul><li><a href="https://github.com/Gracker/SystraceForBlog">SystraceForBlog</a>：博客文章使用过的 Systrace 附件和案例材料。</li><li><a href="https://github.com/Gracker/SystraceAnalysis">SystraceAnalysis</a>：早期用于分析 systrace / ftrace 的工具。</li><li><a href="https://github.com/Gracker/android_cpu_usage_calculation">android_cpu_usage_calculation</a>：Android CPU 使用率计算相关脚本。</li><li><a href="https://github.com/Gracker/FPSDump">FPSDump</a>：FPS 数据采集相关 Demo。</li><li><a href="https://github.com/Gracker/GameBench">GameBench</a>：Android 游戏性能测试工具，包含 server 和 client。</li><li><a href="https://github.com/Gracker/Android-FPS-Calculation">Android-FPS-Calculation</a>：Android FPS 计算 Demo。</li><li><a href="https://github.com/Gracker/Android_HardwareLayer_Example">Android_HardwareLayer_Example</a>：硬件层动画性能测试示例。</li><li><a href="https://github.com/Gracker/DelayLoadSample">DelayLoadSample</a>：Android DelayLoad 示例项目。</li><li><a href="https://github.com/Gracker/ListHeaderAnimationPerformance">ListHeaderAnimationPerformance</a>：列表 Header 动画性能测试。</li><li><a href="https://github.com/Gracker/AndroidLunchModeTest">AndroidLunchModeTest</a>：Android launch mode 测试 Demo。</li><li><a href="https://github.com/Gracker/AndroidUML">AndroidUML</a>：基于 PlantUML 整理的 Android UML 资料。</li></ul><h3><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#Android-App-x2F-Java-%E5%8E%86%E5%8F%B2%E9%A1%B9%E7%9B%AE" class="headerlink" title="Android App / Java 历史项目"></a>Android App / Java 历史项目</h3><p>这里主要是学习项目、文章配套工程和早期工具：</p><ul><li><a href="https://github.com/Gracker/Cats">Cats</a>：Kotlin 练习和个人 App Demo。</li><li><a href="https://github.com/Gracker/Girls">Girls</a>：Gank 客户端练手项目。</li><li><a href="https://github.com/Gracker/Flutter-Gank">Flutter-Gank</a>：Flutter 练手项目。</li><li><a href="https://github.com/Gracker/FriendsCircle_Flutter_Demo">FriendsCircle_Flutter_Demo</a>：朋友圈 Flutter Demo。</li><li><a href="https://github.com/Gracker/SlideDelete-ListView">SlideDelete-ListView</a>：支持侧滑删除的 ListView 示例。</li><li><a href="https://github.com/Gracker/Android-NumberLimitEditText">Android-NumberLimitEditText</a>：输入长度限制 EditText。</li><li><a href="https://github.com/Gracker/SystemMonitor">SystemMonitor</a>：Android 系统监控示例。</li><li><a href="https://github.com/Gracker/JavaReflect">JavaReflect</a>：Java 反射测试。</li><li><a href="https://github.com/Gracker/AndroidInterview-PrintAllViews">AndroidInterview-PrintAllViews</a>：View 树打印相关 Demo。</li><li><a href="https://github.com/Gracker/MemoryAnalysisTools">MemoryAnalysisTools</a>：早期内存分析工具。</li><li><a href="https://github.com/Gracker/Fragment-NetEase">Fragment-NetEase</a>：早期 Fragment 基础框架，已归档。</li></ul><h3><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#%E8%B5%84%E6%96%99%E5%BA%93%E3%80%81%E7%AB%99%E7%82%B9%E5%92%8C%E7%BF%BB%E8%AF%91" class="headerlink" title="资料库、站点和翻译"></a>资料库、站点和翻译</h3><p>工具和 Demo 之外，我还维护过一些资料整理、站点和翻译项目：</p><ul><li><a href="https://github.com/Gracker/awesome-android-ai-dev-sources">awesome-android-ai-dev-sources</a>：个人订阅和收集的技术人、博客和开发资料入口。</li><li><a href="https://github.com/Gracker/Gracker.github.io">Gracker.github.io</a>：Android Performance 博客部署仓库。</li><li><a href="https://github.com/Gracker/hexo-theme-reading">hexo-theme-reading</a>：早期 Hexo 博客主题。</li><li><a href="https://github.com/Gracker/claude-code-from-source-zh-cn">claude-code-from-source-zh-cn</a>：Claude Code from Source 简体中文翻译版。</li></ul><p>完整公开仓库以 <a href="https://github.com/Gracker">GitHub 主页</a>为准。这篇文章只放和长期方向、博客内容、工具项目、App 项目关系更近的链接。</p><h3><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#SmartProtobuf" class="headerlink" title="SmartProtobuf"></a>SmartProtobuf</h3><p>SmartProtobuf 是 Protobuf / Trace 数据结构方向的工具项目。公开信息整理完成后，这里会补仓库地址、使用方式和文章链接；在此之前，先不放不稳定地址。</p><h2><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#AI-%E4%B8%8E%E8%87%AA%E5%8A%A8%E5%8C%96%E9%A1%B9%E7%9B%AE" class="headerlink" title="AI 与自动化项目"></a>AI 与自动化项目</h2><h3><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#OpenClaw" class="headerlink" title="OpenClaw"></a>OpenClaw</h3><p>OpenClaw 是我最近长期使用的本地 AI 自动化系统。这套系统接入 Telegram、Obsidian、定时任务、本地模型、云端模型和工程工具，用来做信息流整理、知识库维护、日报复盘、GitHub 监控、论文精读、内容素材归档和工程协作。</p><p>相关实践文章：</p><ul><li><a href="https://www.androidperformance.com/2026/03/08/OpenClaw-Local-Practice/">我把 OpenClaw 跑在本地三周后，发现它根本不是聊天机器人</a></li><li><a href="https://www.androidperformance.com/2026/03/10/OpenClaw-FAQ/">OpenClaw 常见问题解答：Token 消耗、能干什么、本地模型、隐私安全、使用体验</a></li></ul><h3><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#AI-Field-Notes" class="headerlink" title="AI Field Notes"></a>AI Field Notes</h3><p><a href="https://github.com/Gracker/awesome-ai-field-notes">awesome-ai-field-notes</a> 是一个由 OpenClaw 每日自动维护的 AI 领域资料库，在线站点是 <a href="https://godofgpt.com/">godofgpt.com</a>。</p><p>这个站点持续采集、去重、分类、评分、翻译和生成页面，内容覆盖模型、Agent、AI 编程、基础设施、行业观察和学习资源。对我来说，这是 AI 信息流的长期资料库，也是 OpenClaw 自动化能力的一个公开样本。</p><h3><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#Gracker-Skills" class="headerlink" title="Gracker Skills"></a>Gracker Skills</h3><p>我把自己常用的一些写作、调研和画图流程整理成了公开 Skill：</p><ul><li><a href="https://github.com/Gracker/gracker-writing">gracker-writing</a>：技术文章写作 Skill，适用于技术深度文章、工具实战复盘、FAQ、方法论和公众号长文。</li><li><a href="https://github.com/Gracker/gracker-deep-research-skill">gracker-deep-research-skill</a>：三阶段深度调研 Skill，本地资料扫描、探索落盘、离线写作分开处理。</li><li><a href="https://github.com/Gracker/gracker-diagrams-skill">gracker-diagrams-skill</a>：技术图、架构图、信息图生成 Skill。</li></ul><h3><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#Open-Design" class="headerlink" title="Open Design"></a>Open Design</h3><p><a href="https://github.com/Gracker/open-design">open-design</a> 是我 fork 并参与维护的开源设计工具方向项目。这个项目把本地 coding agent、设计系统、Skill、导出和预览放在同一套工作流里，让网页、移动端原型、幻灯片、图片和视频生成更接近真实设计生产过程。</p><h2><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#%E6%AD%A3%E5%9C%A8%E5%81%9A%E7%9A%84-App" class="headerlink" title="正在做的 App"></a>正在做的 App</h2><h3><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#100Years" class="headerlink" title="100Years"></a>100Years</h3><p>100Years 是一个 iOS 长寿预测与健康分析 App。它结合 HealthKit、生活方式、体检报告、运动、睡眠、营养、心理状态和 AI 分析，估算活到 100 岁的概率、预期寿命和健康寿命。</p><p>100Years 目前还在产品打磨阶段，源码仓库暂不公开。项目按完整 App 标准推进：数据导入、医学指标、AI 解读、HealthKit 同步、SwiftUI 设计系统、本地化和发布前检查都会持续做。</p><h3><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#iBattery" class="headerlink" title="iBattery"></a>iBattery</h3><p>iBattery 是一个给骑行用户做的设备电量监控 App。iOS 版本用于监控蓝牙运动设备，比如功率计、心率带、电子变速、踏频器、骑行台和码表。</p><p>核心功能包括：</p><ul><li>自动发现和分类附近的蓝牙运动设备。</li><li>实时读取电量并做低电量提醒。</li><li>支持 iOS Widget，把常用设备电量放到桌面。</li><li>支持多语言、本地缓存、通知和主题设置。</li></ul><p>iOS 仓库当前暂不公开；Android 版本也在本地进行中，目标是把 iOS 体验迁移到 Android。</p><h3><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#Juju" class="headerlink" title="Juju"></a>Juju</h3><p>Juju 是一个给家人使用的 Android 成长记录 App，用来记录孩子年龄、里程碑、照片和桌面小组件。它偏私人使用场景，当前不作为公开开源项目推广。</p><h2><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#%E5%86%85%E5%AE%B9%E9%A1%B9%E7%9B%AE" class="headerlink" title="内容项目"></a>内容项目</h2><h3><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#Android-Performance-%E5%8D%9A%E5%AE%A2" class="headerlink" title="Android Performance 博客"></a>Android Performance 博客</h3><p>这个博客是我维护时间最长的公开内容站点：<a href="https://www.androidperformance.com/">androidperformance.com</a>。</p><p>主要内容包括：</p><ul><li><a href="https://androidperformance.com/2019/12/01/BlogMap/">博客文章目录</a>：所有主要文章的总索引。</li><li>Perfetto 系列：从 Perfetto 工具、抓取、UI、SQL、Trace Processor、Binder、CPU、Vsync、RenderThread 到后续自动化分析。</li><li>Systrace 系列：Android 运行机制、线程状态、Vsync、Input、SurfaceFlinger、Binder、Triple Buffer、SystemServer 等。</li><li>流畅性与响应速度：启动、滑动、掉帧、低内存、CPU、Runnable / Running / Sleep 状态。</li><li>ANR、内存、Framework、App 开发、读书笔记、好物推荐和知乎问答。</li></ul><h3><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#Android-Weekly" class="headerlink" title="Android Weekly"></a>Android Weekly</h3><p>Android Weekly 是我维护的免费技术周刊，覆盖 Android、Linux、iOS、Flutter、性能优化和工程工具。</p><p>周刊入口：</p><ul><li><a href="https://juejin.cn/column/7456829086335107091">掘金专栏 - Android Weekly</a></li><li><a href="https://www.zhihu.com/column/c_1278963991947780096">知乎专栏 - Android Weekly</a></li></ul><h3><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#%E7%9F%A5%E8%AF%86%E6%98%9F%E7%90%83%EF%BC%9AThe-Performance" class="headerlink" title="知识星球：The Performance"></a>知识星球：The Performance</h3><p><a href="https://www.androidperformance.com/2022/03/13/the-performance/">The Performance</a> 是我维护的 Android 性能优化知识星球，主要分享性能分析基础、工具使用、案例分析、问题答疑和一线性能优化经验。</p><p>适合关注这些方向的同学：</p><ul><li>Android 卡顿、启动、ANR、内存、功耗分析。</li><li>Perfetto / Systrace / Trace Processor 使用。</li><li>Framework、APM、系统优化和厂商侧性能问题。</li><li>真实案例复盘和性能分析思路。</li></ul><h2><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#%E5%B9%B3%E5%8F%B0%E5%85%A5%E5%8F%A3" class="headerlink" title="平台入口"></a>平台入口</h2><ul><li>个人博客：<a href="https://www.androidperformance.com/">Android Performance</a></li><li>GitHub：<a href="https://github.com/Gracker">Gracker</a></li><li>知乎：<a href="https://www.zhihu.com/people/gracker">Gracker</a></li><li>知乎专栏：<a href="https://www.zhihu.com/column/gracker">Android Performance</a></li><li>掘金：<a href="https://juejin.cn/user/1816846860560749">Gracker</a></li><li>掘金专栏：<a href="https://juejin.cn/column/7456829086335107091">Android Weekly</a></li><li>X / Twitter：<a href="https://twitter.com/Gracker_Gao">Gracker_Gao</a></li><li>微博：<a href="https://weibo.com/gracker520">gracker520</a></li><li>RSS：<a href="https://androidperformance.com/atom.xml">订阅博客</a></li><li>邮箱：<a href="mailto:Dreamtale.jg@gmail.com">Dreamtale.jg@gmail.com</a></li></ul><p>微信和讨论群可以看<a href="https://www.androidperformance.com/about/">关于博主</a>页面，那里更适合长期更新联系方式。</p><h2><a href="https://androidperformance.com/2026/05/05/What-I-Am-Building/#%E6%80%8E%E4%B9%88%E8%AF%BB%E8%BF%99%E4%BB%BD%E7%B4%A2%E5%BC%95" class="headerlink" title="怎么读这份索引"></a>怎么读这份索引</h2><ul><li>想系统学 Android 性能：从<a href="https://androidperformance.com/2019/12/01/BlogMap/">博客文章目录</a>开始。</li><li>想用 AI 分析 Perfetto trace：看 <a href="https://github.com/Gracker/SmartPerfetto">SmartPerfetto</a> 和 <a href="https://www.androidperformance.com/2026/04/29/SmartPerfetto-Open-Source-Perfetto-AI-Assistant/">SmartPerfetto 开源介绍</a>。</li><li>想做 App 内存分析：看 <a href="https://github.com/Gracker/Android-App-Memory-Analysis">Android-App-Memory-Analysis</a>。</li><li>想给 App 自动加 Trace 点：看 <a href="https://github.com/Gracker/TraceFix">TraceFix</a>。</li><li>想找性能测试 Demo：看 <a href="https://github.com/Gracker/Friends-Circle-Demo-Apks-For-Power-and-Performance-Test">High Performance Friends Circle</a>。</li><li>想了解 AI 自动化系统：看 <a href="https://www.androidperformance.com/2026/03/08/OpenClaw-Local-Practice/">OpenClaw 本地实践</a> 和 <a href="https://godofgpt.com/">AI Field Notes</a>。</li><li>想联系我：看<a href="https://www.androidperformance.com/about/">关于博主</a>或上面的平台账号。</li></ul>
				<p><strong>您可能还对下面的文章感兴趣：</strong></p>
				<p><ol><li><a href="https://blogread.cn/it/article.php?id=8428" target="_blank">Android Perfetto 系列 07 - MainThread 和 RenderThread 解读</a> [2026-06-03 09:03:23]</li><li><a href="https://blogread.cn/it/article.php?id=8352" target="_blank">不变量及运算优化</a> [2021-05-28 08:32:57]</li><li><a href="https://blogread.cn/it/article.php?id=8071" target="_blank">JavaScript 代码执行效率对比工具</a> [2016-05-05 22:41:53]</li><li><a href="https://blogread.cn/it/article.php?id=7927" target="_blank">Akka简单性能分析</a> [2016-03-19 22:40:54]</li><li><a href="https://blogread.cn/it/article.php?id=7648" target="_blank">移动端图片格式调研</a> [2016-02-07 14:23:53]</li><li><a href="https://blogread.cn/it/article.php?id=7200" target="_blank">如何查找消耗资源较大的SQL</a> [2015-01-04 22:47:30]</li><li><a href="https://blogread.cn/it/article.php?id=7168" target="_blank">使用valgrind的callgrind工具进行多线程性能分析</a> [2014-12-08 23:23:54]</li><li><a href="https://blogread.cn/it/article.php?id=7151" target="_blank">当cpu飙升时，找出php中可能有问题的代码行</a> [2014-12-04 13:21:22]</li><li><a href="https://blogread.cn/it/article.php?id=7108" target="_blank">redis超时问题分析</a> [2014-12-01 23:38:03]</li><li><a href="https://blogread.cn/it/article.php?id=7074" target="_blank">HBase在单Column和多Column情况下批量Put的性能对比分析</a> [2014-11-28 23:28:08]</li><li><a href="https://blogread.cn/it/article.php?id=6774" target="_blank">Linux如何统计进程的CPU利用率</a> [2013-11-01 13:59:43]</li><li><a href="https://blogread.cn/it/article.php?id=6522" target="_blank">Linux下CPU的利用率</a> [2013-07-15 13:25:03]</li><li><a href="https://blogread.cn/it/article.php?id=6264" target="_blank">Linux Used内存到底哪里去了？</a> [2013-03-03 23:41:07]</li><li><a href="https://blogread.cn/it/article.php?id=6145" target="_blank">通过blktrace, debugfs分析磁盘IO</a> [2012-12-23 23:39:11]</li><li><a href="https://blogread.cn/it/article.php?id=6087" target="_blank">由浅入深探究mysql索引结构原理、性能分析与优化</a> [2012-12-11 22:23:20]</li><li><a href="https://blogread.cn/it/article.php?id=5368" target="_blank">实时计算引擎处理延迟的排查过程</a> [2012-05-22 13:15:11]</li><li><a href="https://blogread.cn/it/article.php?id=5165" target="_blank">关于sar的一个问题： Invalid system activity file</a> [2012-04-07 14:54:49]</li><li><a href="https://blogread.cn/it/article.php?id=4950" target="_blank">深入浅出Flashcache（五）</a> [2012-02-05 23:30:28]</li><li><a href="https://blogread.cn/it/article.php?id=3511" target="_blank">oprofile抓不到采样数据问题和解决方法</a> [2011-04-01 13:34:18]</li><li><a href="https://blogread.cn/it/article.php?id=2911" target="_blank">前端开发中的性能那点事（一）巧用xdebug</a> [2010-12-26 21:14:24]</li><li><a href="https://blogread.cn/it/article.php?id=2692" target="_blank">在Ubuntu上使用SystemTap</a> [2010-11-14 09:02:15]</li><li><a href="https://blogread.cn/it/article.php?id=2390" target="_blank">Array的push与unshift方法性能分析</a> [2010-09-14 08:53:23]</li><li><a href="https://blogread.cn/it/article.php?id=1914" target="_blank">WEB性能测试工具推荐</a> [2010-07-12 23:27:11]</li><li><a href="https://blogread.cn/it/article.php?id=1456" target="_blank">关于改善xhprof使用情况的设想</a> [2010-04-27 13:46:54]</li><li><a href="https://blogread.cn/it/article.php?id=1298" target="_blank">转载：cassandra读写性能原理分析</a> [2010-04-01 08:54:38]</li><li><a href="https://blogread.cn/it/article.php?id=1208" target="_blank">15个网站设计和开发的Chrome插件</a> [2010-03-15 09:39:04]</li><li><a href="https://blogread.cn/it/article.php?id=869" target="_blank">MySQLMonitor</a> [2009-12-23 09:35:56]</li><li><a href="https://blogread.cn/it/article.php?id=725" target="_blank">常用的mysql工具</a> [2009-11-28 23:28:47]</li><li><a href="https://blogread.cn/it/article.php?id=465" target="_blank">常用的数据库管理SQL语句（二）</a> [2009-11-06 13:28:26]</li><li><a href="https://blogread.cn/it/article.php?id=422" target="_blank">Xdebug使用指南</a> [2009-11-03 09:24:44]</li><li><a href="https://blogread.cn/it/article.php?id=323" target="_blank">在生产环境中使用php性能测试工具xhprof</a> [2009-10-27 08:58:40]</li></ol></p>]]></description>
		<content><![CDATA[本文是作者的个人技术项目总览，系统梳理了他长期维护的四大方向工作。在 Android 性能分析与工具链建设上，以 SmartPerfetto 为核心，构建了一套基于 Perfetto 的 AI 辅助分析体系，并配套开发了 Android App Memory Analysis、TraceFix（自动插桩）等专用工具，形成了从 Trace 采集、数据可视化到自动化分析的完整流程。AI 与自动化方向，重点介绍了本地运行的 OpenClaw 系统，它整合了多种模型与工具，用于知识管理、日报生成及工程协作，其公开成果如 AI Field Notes 展现了持续的自动化信息处理能力。此外，作者还开发了数款面向真实需求的 iOS 与 Android 应用，如健康预测 App 100Years。在技术内容输出方面，他通过维护 Android Performance 博客、Android Weekly 周刊及知识星球，沉淀了大量关于系统性能、工具使用及方法论的深度文章与案例，构成了公开的知识体系。整体而言，这些项目贯穿了从底层性能分析、工具开发、AI 实践到应用实现与知识分享的完整技术闭环。]]></content>
	</item>
	<item>
		<title>SmartPerfetto 两周更新：从 Perfetto AI Assistant 到可复用的 Trace 分析平台</title>
		<link>https://blogread.cn/it/article.php?id=8584</link>
		<author>Gracker</author>
		<pubDate>2026-06-03 09:03:24</pubDate>
		<category domain="https://blogread.cn/it/category.php?id=4">AI</category>
		<guid>https://blogread.cn/it/article.php?id=8584</guid>
		<comments>https://blogread.cn/it/article.php?id=8584#comment</comments>
		<description><![CDATA[<p><strong>标签：</strong>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=AI" target="_blank">AI</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=Perfetto" target="_blank">Perfetto</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=Trace" target="_blank">Trace</a></p><p><img src="https://androidperformance.com/images/SmartPerfetto-Two-Week-Update/smartperfetto-update-cover.png" alt="SmartPerfetto 更新封面"></p><p>4 月 29 日写 SmartPerfetto 开源介绍时，重点还是“在 Perfetto UI 里放一个能查 SQL、跑 Skill、生成报告的 AI Assistant”。两周后的仓库状态已经变了不少：功能从单条 trace 的问答，扩到了分析结果复用、多 trace 横向比较、Claude/OpenAI 双 runtime、SQL guardrail、证据来源索引、免安装包、渲染管线教学和更完整的 Provider 诊断。</p><p>本文基于 2026 年 5 月 17 日的 SmartPerfetto 当前仓库状态，补一篇新的功能说明。读者看完应该能知道三件事：这两周新增了什么、现在完整功能边界在哪里、报 bug 时该提供哪些信息。</p><p>项目地址：</p><ul><li>SmartPerfetto 主仓库：<a href="https://github.com/Gracker/SmartPerfetto">https://github.com/Gracker/SmartPerfetto</a></li><li>上一篇开源介绍：<a href="https://www.androidperformance.com/2026/04/29/SmartPerfetto-Open-Source-Perfetto-AI-Assistant/">https://www.androidperformance.com/2026/04/29/SmartPerfetto-Open-Source-Perfetto-AI-Assistant/</a></li></ul><h2><a href="https://androidperformance.com/2026/05/17/SmartPerfetto-Two-Week-Update/#%E4%B8%A4%E5%91%A8%E5%86%85%E5%8F%98%E5%8C%96%E6%9C%80%E5%A4%A7%E7%9A%84%E5%9C%B0%E6%96%B9" class="headerlink" title="两周内变化最大的地方"></a>两周内变化最大的地方</h2><p>上篇文章里写到的几个数字已经过时。那时仓库里是 165 个 YAML Skill、12 个场景策略；当前仓库状态下，<code>backend/skills/</code> 已经有 220 个 <code>*.skill.yaml</code>，去掉 <code>_template</code> 后是 216 个功能性 Skill 文件，<code>backend/strategies/</code> 里有 18 个 <code>.strategy.md</code> 和 26 个 <code>.template.md</code>。</p><p>这不是简单地把文件数堆上去。变化主要落在六类用户会感知到的地方：</p><table><thead><tr><th>方向</th><th>之前的主路径</th><th>当前状态</th></tr></thead><tbody><tr><td>Trace 分析</td><td>单条 trace 上提问、跑 Skill、看报告</td><td>保留原路径，并增加选区追问、结果快照、跨窗口结果对比</td></tr><tr><td>多 Trace 对比</td><td>当前窗口选择 reference trace，偏实时</td><td>新增分析结果 snapshot，对比已完成结果，不要求另一个窗口继续打开</td></tr><tr><td>模型接入</td><td>Claude Agent SDK 是主路径</td><td>Claude Agent SDK 与 OpenAI Agents SDK 都是一等 runtime</td></tr><tr><td>Provider 配置</td><td>主要靠 <code>.env</code> 和 README 说明</td><td>UI Provider Manager、active profile、env fallback、<code>/health</code> 诊断一起工作</td></tr><tr><td>证据可靠性</td><td>主要依赖 prompt 约束模型写 SQL 和引用证据</td><td>SQL stdlib guardrail、最终可执行 SQL、证据 ID、数据来源说明、逐句数据引用进入 contract</td></tr><tr><td>运行分发</td><td>Docker 和本地源码为主</td><td>Docker、Windows/macOS/Linux 免安装包、本地源码、CLI/API 都进入文档和发布流程</td></tr></tbody></table><p>过去两周还修了一批影响可用性的边界问题：大 trace 上传限制提升到 5 GiB，并增加 admission 和磁盘预检查；启动脚本会清理孤儿 <code>trace_processor_shell</code> 并自动打开浏览器；Linux glibc、IPv6-disabled host、Claude SDK native binary 选择、Docker env provider 优先级、OpenAI/MiMo tool calling 兼容性、Perfetto frontend 预构建资产校验都做了修复。</p><p>这类修复看起来不像新功能，但它们决定了普通用户能不能把第一条真实 trace 跑完。</p><h2><a href="https://androidperformance.com/2026/05/17/SmartPerfetto-Two-Week-Update/#%E5%BD%93%E5%89%8D%E5%AE%8C%E6%95%B4%E5%8A%9F%E8%83%BD%E5%9C%B0%E5%9B%BE" class="headerlink" title="当前完整功能地图"></a>当前完整功能地图</h2><p><img src="https://androidperformance.com/images/SmartPerfetto-Two-Week-Update/feature-map.png" alt="SmartPerfetto 功能地图"></p><p>SmartPerfetto 现在可以按“入口、分析、证据、输出、运行方式”五层理解。</p><table><thead><tr><th>功能面</th><th>当前能力</th><th>适合场景</th></tr></thead><tbody><tr><td>Perfetto UI 内 AI Assistant</td><td>加载 <code>.pftrace</code> / <code>.perfetto-trace</code> 后直接提问，支持 <code>fast</code>、<code>full</code>、<code>auto</code> 三种分析模式</td><td>日常看 trace，快速问包名、进程、启动、滑动、ANR</td></tr><tr><td>选区和事件上下文</td><td>Perfetto area selection / track event selection 会作为 <code>selectionContext</code> 传给后端</td><td>只分析某段时间、某一帧、某个可疑 slice 前后发生了什么</td></tr><tr><td>常见场景策略</td><td>18 个策略覆盖 startup、scrolling、ANR、interaction、touch、memory、power、network、media、game、pipeline、teaching、overview 等场景</td><td>把自然语言问题路由到合适的 SQL、Skill 和输出格式</td></tr><tr><td>YAML Skill 系统</td><td>216 个功能性 Skill 文件，覆盖 atomic、composite、deep、pipeline、comparison、module 等类型</td><td>把 Perfetto SQL、显示列、分层结果和边界处理写成可复用分析单元</td></tr><tr><td>SQL 与 Skill 证据</td><td>结果里保留 SQL、Skill 表格、时间戳、线程、slice、metric 来源</td><td>把“模型判断”落回 trace 数据，方便复核</td></tr><tr><td>SQL guardrail 与 stdlib 知识库</td><td>raw SQL 自动补齐 stdlib include，Skill validator 检查 table/function/macro 依赖，SQL 展示/复制使用最终可执行 SQL</td><td>降低 SQL 因 Perfetto stdlib 迁移、缺 include 或 unsafe create 造成的误判</td></tr><tr><td>全局 Trace Sanity</td><td><code>global_trace_sanity_check</code> 汇总最长 slice、D 状态、Runnable 等待、Runqueue 压力和 CPU 热点进程</td><td>开始场景分析前先看全局瓶颈，避免只盯住单个线程或单个 Skill</td></tr><tr><td>证据来源索引</td><td>DataEnvelope 带 <code>evidenceRefId</code>、<code>traceSide</code>、<code>sourceToolCallId</code>、plan phase、producer reason，报告支持逐句数据引用</td><td>追问“这个数字从哪张表哪一行来”时，有稳定 ID 和行列信息</td></tr><tr><td>HTML 分析报告</td><td>每次分析完成后生成报告，通用接口 <code>/api/reports/:reportId</code> 可读取</td><td>分享给团队、贴到 issue、留作回归记录</td></tr><tr><td>Trace 实时对比</td><td><code>compare_arrows</code> 入口选择 reference trace，在同一轮 AI 分析里查询 current/reference</td><td>两条 raw trace 都可访问，想临时比较当前窗口与参考 trace</td></tr><tr><td>多 Trace 分析结果对比</td><td><code>fact_check</code> 入口选择 baseline/candidates，或直接输入 Result ID</td><td>对比已经完成的多次分析结果，适合 A/B 测试、版本回归、多人协作</td></tr><tr><td>Provider Manager</td><td>UI 里创建、编辑、激活 provider profile，active profile 优先于 env fallback</td><td>多模型、多 provider、多协议测试，不想反复改 <code>.env</code></td></tr><tr><td>双 SDK runtime</td><td><code>claude-agent-sdk</code> 与 <code>openai-agents-sdk</code> 分开接入，支持 Anthropic/Claude-compatible、OpenAI/Ollama/OpenAI-compatible</td><td>根据 provider 的真实协议能力选择 runtime</td></tr><tr><td>渲染管线教学</td><td>基于当前 trace 观测到的 App、RenderThread、Producer、SurfaceFlinger/HWC 事件生成教学结果</td><td>学习 Android 出图路径，并把静态知识对回本次 trace</td></tr><tr><td>上游 Perfetto 诊断产品化</td><td>heap graph、bitmap heap metadata、critical blocking calls、lock contention owner、Chrome scroll jank frame timeline 等进入 YAML Skill</td><td>把 upstream Perfetto 的分析经验转成 SmartPerfetto 可执行证据</td></tr><tr><td>Mermaid 展示</td><td>AI Assistant 默认展开 Mermaid 源码块，优化渲染样式，支持点击放大预览</td><td>报告里出现流程图、因果图、对比图时可读性更好</td></tr><tr><td>API / CLI / MCP</td><td>后端 REST + SSE、<code>@gracker/smartperfetto</code> CLI、MCP 工具文档</td><td>接入脚本、CI、内部平台，或直接在终端分析 trace</td></tr><tr><td>运行与分发</td><td>Docker Hub、本地源码 <code>./start.sh</code>、Windows EXE、macOS App、Linux tarball</td><td>不同用户按环境选择最少依赖路径</td></tr><tr><td>企业/多租户基础</td><td>tenant/workspace、RBAC、provider isolation、scoped trace/report metadata、runtime dashboard、lease supervisor 等已经进入主干</td><td>团队部署和商业支持的基础能力；大规模外部 RSS/load 实测仍按文档标记为后续验证项</td></tr></tbody></table><p>这里最该强调的是证据边界。SmartPerfetto 不会把整个 trace 文件塞进 prompt。模型接触到的是后端工具返回的 SQL 结果、Skill 输出、报告摘要和结构化上下文。性能数字仍来自 <code>trace_processor_shell</code> 和 Skill 里的确定性计算。</p><h2><a href="https://androidperformance.com/2026/05/17/SmartPerfetto-Two-Week-Update/#%E6%96%B0%E5%8A%9F%E8%83%BD%E4%B8%80%EF%BC%9A%E5%A4%9A-Trace-%E5%88%86%E6%9E%90%E7%BB%93%E6%9E%9C%E5%AF%B9%E6%AF%94" class="headerlink" title="新功能一：多 Trace 分析结果对比"></a>新功能一：多 Trace 分析结果对比</h2><p><img src="https://androidperformance.com/images/SmartPerfetto-Two-Week-Update/multi-trace-comparison.png" alt="多 Trace 分析结果对比"></p><p>旧的 Trace 对比更像“当前窗口 + reference trace”的实时分析。这个模式仍然保留，适合在一次对话里让 AI 同时查询两条 raw trace。</p><p>新的多 Trace 分析结果对比换了一个对象：它比较的是已经完成的分析结果。每次 AI 分析结束后，SmartPerfetto 会把关键指标、证据引用、结论 contract 和报告入口保存成 analysis result snapshot。UI 顶部出现 <code>Ready result</code> 或 <code>Partial result</code> 时，说明这次分析已经有了可复用结果。</p><p>用户有两种入口：</p><ul><li>直接在 AI 输入框里说 <code>对比一下另外一份</code>、<code>对比 AR-1234abcd</code>，或者 <code>对比 AR-11111111 和 AR-22222222</code>。</li><li>点击顶部 <code>fact_check</code> 图标，打开结果选择器，手动选择 baseline 和一个或多个 candidates。</li></ul><p>这个功能解决的问题不在于同时打开两条 trace，而在于复用已经完成的分析结果。它不要求另一个 Perfetto UI 窗口继续打开，也支持同一个 workspace 内共享结果。默认结果是 private；用户显式共享后，同 workspace 用户可以把它作为候选结果参与对比。</p><p>输出分两层：</p><ul><li>聊天消息里给出 Comparison ID、baseline/candidates、显著变化数量和前几行关键指标。</li><li>HTML comparison report 展开标准指标、delta、输入 snapshot、显著变化和 AI 结论。</li></ul><p>当前标准化指标优先覆盖启动耗时、FPS、Jank、慢帧等可比较项。缺指标时，后端会尝试回填；回填失败也会完成对比，但会标出缺失原因。</p><p>这对性能回归很有用。一次启动优化、一次滑动手感调整、一次不同机型复测，都可以在各自 trace 上先完成 AI 分析，再把结果放到同一个 comparison report 里看差异。</p><h2><a href="https://androidperformance.com/2026/05/17/SmartPerfetto-Two-Week-Update/#%E6%96%B0%E5%8A%9F%E8%83%BD%E4%BA%8C%EF%BC%9ASQL%E3%80%81%E8%AF%81%E6%8D%AE%E6%9D%A5%E6%BA%90%E5%92%8C%E4%B8%8A%E6%B8%B8%E8%AF%8A%E6%96%AD%E8%83%BD%E5%8A%9B" class="headerlink" title="新功能二：SQL、证据来源和上游诊断能力"></a>新功能二：SQL、证据来源和上游诊断能力</h2><p>最近新增内容里最需要补充的一块，是 SmartPerfetto 对证据来源的处理。用户看到的仍然是对话、表格和报告，内部多了三层 contract：SQL 怎么变成最终可执行版本、表格/摘要从哪个工具调用产生、结论里的数值该回到哪一行证据。</p><p>第一层是 SQL guardrail。<code>execute_sql</code>、<code>execute_sql_on</code>、raw SQL auto include 和 Skill validator 现在共用同一套 stdlib dependency analyzer，识别 SQL 里的 table、function、macro 和 <code>INCLUDE PERFETTO MODULE</code>。这带来几个直接收益：</p><ul><li>raw SQL 引用了 Perfetto stdlib 表或函数时，后端会尽量自动补齐需要的 module。</li><li>Skill validator 会检查 Skill 里声明的 <code>prerequisites.modules</code> 是否覆盖实际 SQL 用到的 stdlib table/function/macro。</li><li>guardrail 会检查低噪声 SQL 风险，例如可重复执行的 <code>CREATE</code>、<code>SPAN_JOIN</code> 安全写法、直接解析 <code>args</code> 表等。</li><li>AI Assistant 展示和复制 SQL 时使用最终可执行 SQL，并经过 syntaqlite formatter；formatter 失败时降级到原 SQL，不阻断分析。</li></ul><p>边界也要写清楚：当前 guardrail 是工程 contract，不是完整 Perfetto SQL AST parser。它能降低高频误判，不能证明所有未来 Perfetto SQL 语法都被静态覆盖。</p><p>第二层是 stdlib docs 与 lineage 知识库。仓库新增了 <code>backend/data/perfettoSqlDocs.json</code>，由 upstream <code>stdlib_docs.json</code> 生成 module、entity、direct/transitive includes 和可选 <code>pfsql lineage</code> 状态。<code>lookup_sql_schema</code>、<code>list_stdlib_modules</code>、<code>query_perfetto_source</code> 可以把官方 stdlib 文档、include 关系和源码搜索结果一起返回给 Agent。这样模型写 SQL 前不再只靠记忆，也不需要把所有 stdlib 细节硬写进 prompt。</p><p>第三层是数据来源索引。SQL 和 Skill 产生的 DataEnvelope 可以携带 <code>evidenceRefId</code>、<code>traceSide</code>、<code>traceId</code>、<code>queryHash</code>、<code>sourceToolCallId</code>、<code>paramsHash</code>、plan phase、<code>toolNarration</code> 和 <code>producerReason</code>。HTML report 和 analysis result snapshot 会保留这些字段。当前报告 contract 还加入了“逐句数据引用（结构化来源）”：结论里出现关键数值、线程名、进程名、帧数或百分比时，可以把它映射到 <code>evidence_ref_id</code>、<code>source_ref</code>、<code>row_index</code> / <code>row_selector</code>、<code>column</code> 和 <code>value</code>。</p><p>快速回答也接入了同一套格式。内部会先用未清理的结论文本派生 conclusion contract，保留机器可读的 evidence id，再生成给用户看的清理版文本。analysis result snapshot 会持久化这个 contract，后续做多 Trace 对比或回看报告时，来源引用不会因为前端展示清理而丢掉。</p><p>这件事对排错很实用。用户不需要只说“AI 结论不对”，可以指向 <code>Q1</code>、某个 <code>evidenceRefId</code>、某个 Result ID、某张表的某一列，维护者也能判断问题在 SQL、Skill、trace 数据源、模型总结还是报告渲染。</p><p>这轮还把一批 upstream Perfetto 诊断经验产品化到 YAML Skill：</p><table><thead><tr><th>能力</th><th>SmartPerfetto 落点</th><th>用户价值</th></tr></thead><tbody><tr><td>全局 Trace Sanity</td><td><code>global_trace_sanity_check</code></td><td>开始分析前先看最长 slice、D 状态、Runnable 等待、Runqueue 压力和 CPU 热点进程</td></tr><tr><td>进程身份确认</td><td><code>process_identity_resolver</code> 和 process identity gate</td><td>避免同名进程、多进程 App、provider 进程导致 Skill 查错目标</td></tr><tr><td>Heap / Bitmap</td><td><code>android_heap_graph_summary</code>、<code>android_bitmap_memory_per_process</code></td><td>有 heap graph / bitmap 表时输出对象和 bitmap 维度；没有数据时明确降级</td></tr><tr><td>Blocking calls</td><td><code>frame_blocking_calls</code></td><td>区分 MainThread、RenderThread、Binder 等 thread role，并保留阻塞来源</td></tr><tr><td>Lock contention</td><td><code>lock_contention_in_range</code>、<code>lock_contention_analysis</code></td><td>输出 blocked thread、owner thread、owner TID、callsite 和 overlap duration</td></tr><tr><td>Chrome Scroll Jank</td><td><code>chrome_scroll_jank_frame_timeline</code></td><td>覆盖 Chrome v3/v4 scroll jank、tagging 和 preferred frame timeline availability</td></tr></tbody></table><p>这些能力不改变 SmartPerfetto 的基本原则：模型负责解释和排序，数值仍来自 <code>trace_processor_shell</code>、SQL、Skill 和报告里可追溯的数据来源。</p><h2><a href="https://androidperformance.com/2026/05/17/SmartPerfetto-Two-Week-Update/#%E6%96%B0%E5%8A%9F%E8%83%BD%E4%B8%89%EF%BC%9AProvider-Manager-%E4%B8%8E%E5%8F%8C-runtime" class="headerlink" title="新功能三：Provider Manager 与双 runtime"></a>新功能三：Provider Manager 与双 runtime</h2><p><img src="https://androidperformance.com/images/SmartPerfetto-Two-Week-Update/provider-runtime.png" alt="Provider 与 Runtime 配置"></p><p>SmartPerfetto 的模型配置现在有三条边界：</p><ul><li><code>Connection</code> 配 SmartPerfetto 后端地址和可选的 <code>SMARTPERFETTO_API_KEY</code>，它不是模型厂商 key。</li><li><code>Providers</code> 配模型 provider profile，包括 Base URL、API key/token、模型 ID、协议类型。</li><li>runtime 决定后端用哪个 SDK 编排工具调用：<code>claude-agent-sdk</code> 或 <code>openai-agents-sdk</code>。</li></ul><p>运行时选择优先级是：</p><table><thead><tr><th>优先级</th><th>来源</th></tr></thead><tbody><tr><td>1</td><td>请求或会话里的 <code>providerId</code></td></tr><tr><td>2</td><td>Provider Manager 当前 active provider</td></tr><tr><td>3</td><td><code>.env</code> 中的 <code>SMARTPERFETTO_AGENT_RUNTIME</code></td></tr><tr><td>4</td><td>默认 <code>claude-agent-sdk</code></td></tr></tbody></table><p>Claude Agent SDK 适合 Anthropic、Claude Code 本地认证、Bedrock、Vertex，以及 Anthropic/Claude-compatible provider。OpenAI Agents SDK 适合 OpenAI Responses API、Ollama，以及支持流式 tool/function calling 的 OpenAI-compatible gateway。</p><p>Provider Manager profile 优先于 <code>.env</code> fallback。已经创建的分析 session 会固定当时的 credential source；恢复这个 session 时，不会因为后来切换了 active provider 就换到另一个模型。这个约束很重要，因为 trace 分析里的多轮追问依赖前一轮的工具结果和 SDK 会话状态。</p><p>排障时不要只看 <code>.env</code>。打开 <code>http://localhost:3000/health</code>，看 <code>aiEngine.runtime</code>、<code>aiEngine.credentialSource</code>、<code>aiEngine.providerMode</code> 和 diagnostics。很多 provider preset 来自公开文档，可能随账号地区、套餐或控制台域名变化。连接失败、流式输出异常、tool call 不稳定时，应先核对 provider 控制台里的 Base URL、模型 ID 和协议类型。</p><h2><a href="https://androidperformance.com/2026/05/17/SmartPerfetto-Two-Week-Update/#%E6%96%B0%E5%8A%9F%E8%83%BD%E5%9B%9B%EF%BC%9A%E6%B8%B2%E6%9F%93%E7%AE%A1%E7%BA%BF%E6%95%99%E5%AD%A6%E4%BB%8E%E9%9D%99%E6%80%81%E6%96%87%E6%A1%A3%E8%BD%AC%E5%90%91%E5%BD%93%E5%89%8D-trace" class="headerlink" title="新功能四：渲染管线教学从静态文档转向当前 trace"></a>新功能四：渲染管线教学从静态文档转向当前 trace</h2><p>“出图教学”这两周做了重构。以前更像是检测一个主管线，展示对应 Mermaid、关键 slice 和教学文档。现在目标换成了：基于当前 trace 里真实观测到的事件，展示 App、Framework、RenderThread、Producer、BufferQueue/Transaction、SurfaceFlinger/HWC、present 这些角色之间发生了什么。</p><p>新的后端服务会构造 <code>observedFlow</code>：</p><ul><li>lanes 表示当前 trace 中可观测到的角色，例如 app、render_thread、producer、buffer_queue、surfaceflinger、hwc_present。</li><li>events 表示真实 slice/thread/process/layer 事件，带 <code>ts</code>、<code>dur</code>、<code>durMs</code>、evidence source 和可选 frame/layer 关联。</li><li>dependencies 表示可确认的依赖，例如 wakeup 或 critical path。</li><li>completeness 标明缺哪些信号，避免把静态知识伪装成本次 trace 的事实。</li></ul><p>这对混合渲染尤其重要。WebView、Flutter、React Native、TextureView、SurfaceView、OpenGL ES、Vulkan、Camera、Video、Game engine 这类 producer 不能简单归到一个“主管线”里。SmartPerfetto 现在会把 host HWUI 和 producer 分开展示，再根据证据说明二者有没有依赖。</p><p>教学功能的价值不在于替用户背 Android 出图机制，而是把知识点贴回本次 trace 里的实际事件。用户看完应该能知道：本次 trace 里哪些路径看到了证据，哪些路径因为采集缺口还不能确认。</p><h2><a href="https://androidperformance.com/2026/05/17/SmartPerfetto-Two-Week-Update/#%E8%BF%99%E4%B8%A4%E5%91%A8%E7%9A%84%E5%8F%AF%E7%94%A8%E6%80%A7%E4%BF%AE%E5%A4%8D" class="headerlink" title="这两周的可用性修复"></a>这两周的可用性修复</h2><p>新增功能之外，最近的修复主要集中在“真实用户把工具跑起来”这件事上。</p><table><thead><tr><th>修复方向</th><th>用户感知</th></tr></thead><tbody><tr><td>5 GiB trace 上传</td><td>更大的 trace 可以走上传路径；后端先做 admission 和磁盘预检查，避免上传到一半才失败</td></tr><tr><td>启动脚本清理孤儿进程</td><td>上次异常退出后残留的 <code>trace_processor_shell</code> 不容易占住端口</td></tr><tr><td>本地启动自动打开浏览器</td><td><code>./start.sh</code> 跑起来后更接近日常工具体验</td></tr><tr><td>Linux glibc / IPv6-disabled host</td><td>Ubuntu 20.04、禁用 IPv6 的环境更容易启动</td></tr><tr><td>Claude SDK native binary fallback</td><td>可选 native 包选错平台时，后端能走自动 fallback</td></tr><tr><td>OpenAI/MiMo 兼容性</td><td>修复 reasoning content、tool 参数、plan phases、<code>startup_slow_reasons</code> 等兼容问题</td></tr><tr><td>quick/full session 隔离</td><td>切换 fast/full/auto 时，轻量上下文和完整上下文不会混用</td></tr><tr><td>stale SDK conversation recovery</td><td>Claude/OpenAI 会话句柄过期时，后端能恢复或降级，避免第二轮追问直接断掉</td></tr><tr><td>process identity gate</td><td>Skill 执行前会校验目标进程身份，避免包名、进程名或多进程场景把 SQL 查到错误对象</td></tr><tr><td>SQL stdlib guardrail</td><td>缺失 stdlib include、unsafe create、SPAN_JOIN 和 args 解析问题能在 validator 或 guardrail 阶段暴露</td></tr><tr><td>跨窗口结果对比</td><td>多窗口下的结果选择、heartbeat、Result ID 使用更稳定</td></tr><tr><td>backend trace_processor 隔离</td><td>本地 trace 和 backend-created trace processor target 分开处理，降低第二条 trace 错用目标的概率</td></tr><tr><td>frontend prebuild 资产守卫</td><td><code>syntaqlite-*</code>、<code>trace_processor.wasm</code>、<code>trace_processor_memory64.wasm</code>、manifest hash 进入校验，降低免安装包和 Docker 漏资产风险</td></tr><tr><td>Mermaid 体验</td><td>源码默认展开、样式更清楚、图表支持点击放大</td></tr></tbody></table><p>这些问题很多来自真实 issue 和本地复现。SmartPerfetto 的困难不只在“模型会不会分析”，还在模型、Perfetto UI、后端 SSE、<code>trace_processor_shell</code>、浏览器窗口、provider 协议之间的状态是否一致。任何一个状态漂移，最终都会表现成“AI 结果不可靠”。</p><h2><a href="https://androidperformance.com/2026/05/17/SmartPerfetto-Two-Week-Update/#%E7%8E%B0%E5%9C%A8%E6%80%8E%E4%B9%88%E9%80%89%E8%BF%90%E8%A1%8C%E6%96%B9%E5%BC%8F" class="headerlink" title="现在怎么选运行方式"></a>现在怎么选运行方式</h2><p>普通用户优先选 Docker 或免安装包。</p><table><thead><tr><th>运行方式</th><th>适合谁</th><th>说明</th></tr></thead><tbody><tr><td>Docker Hub</td><td>只想快速试用或部署</td><td>不需要 Node.js，不需要初始化 submodule；需要在 <code>.env</code> 或 UI Provider Manager 配模型凭证</td></tr><tr><td>免安装包</td><td>不想安装 Docker 的用户</td><td>Windows 解压双击 <code>SmartPerfetto.exe</code>，macOS 双击 <code>SmartPerfetto.app</code>，Linux 运行 <code>./SmartPerfetto</code></td></tr><tr><td>本地源码 <code>./start.sh</code></td><td>开发者、想跟主干的人</td><td>使用仓库提交的预构建 frontend，日常后端/Skill/策略改动不需要构建 Perfetto UI</td></tr><tr><td>Dev 模式 <code>./scripts/start-dev.sh</code></td><td>修改 AI Assistant 插件 UI 的人</td><td>需要初始化 <code>perfetto/</code> submodule，保存前端代码后 watch 构建</td></tr><tr><td>CLI <code>smp</code></td><td>想在终端或脚本里分析 trace 的人</td><td>复用 agentv3、Skill、报告生成和本地 session 存储</td></tr></tbody></table><p>源码运行的 Node.js 要求是 24 LTS。仓库有 <code>.nvmrc</code> 和 <code>.node-version</code>，npm 开了 <code>engine-strict=true</code>；<code>./start.sh</code>、<code>./scripts/start-dev.sh</code>、<code>./scripts/restart-backend.sh</code> 会优先通过 nvm/fnm 切到 Node 24。</p><p>macOS 免安装包当前采用 ad-hoc signing，避免被系统直接判为 damaged；正式公证仍需要 Developer ID 和 notary profile。这个状态应在发布说明里写清楚，避免用户把 Gatekeeper 行为当作后端问题。</p><h2><a href="https://androidperformance.com/2026/05/17/SmartPerfetto-Two-Week-Update/#%E8%B5%9E%E5%8A%A9%E4%B8%8E%E5%95%86%E4%B8%9A%E6%94%AF%E6%8C%81" class="headerlink" title="赞助与商业支持"></a>赞助与商业支持</h2><p>SmartPerfetto 的开源维护成本主要来自四类地方：真实 trace 复现、模型 token、Provider 兼容性验证、跨平台发布包验证。项目接受个人赞助、企业赞助、AI Credits / Token 厂商赞助，也接受围绕 AGPL 的商业授权和企业支持咨询。</p><p>个人赞助适合支持开源维护、测试 trace、文档示例和公开 demo 的模型消耗。个人赞助者可以进入 README 的感谢名单；如果赞助者希望匿名，也可以只记录为匿名支持。</p><p>普通企业赞助适合支持长期维护、问题复现、公开文档和回归测试。企业赞助者也可以进入 README 感谢名单，并在 sponsor 页面展示企业名称和链接。更深的企业合作可以放到商业支持里处理，例如 Android 性能 trace 专家诊断、Perfetto / SmartPerfetto 团队培训、企业内部部署、定制 YAML Skill / Strategy、商业授权与集成咨询。</p><p>LLM / API / Token 厂商赞助更适合用 credits、token 套餐、试用账号或开发者额度支持 SmartPerfetto。SmartPerfetto 这类工具只会聊天不够，还要稳定支持流式输出、tool/function calling、长上下文恢复、结构化参数和真实 trace 分析。厂商赞助可以换来三类更直接的项目支持：</p><table><thead><tr><th>赞助类型</th><th>项目侧支持</th></tr></thead><tbody><tr><td>个人赞助</td><td>README 感谢名单，支持开源维护和公开示例成本</td></tr><tr><td>普通企业赞助</td><td>README 感谢名单，sponsor 页面展示，企业支持/培训/诊断合作入口</td></tr><tr><td>LLM / Token 厂商赞助</td><td>README 前部赞助展示，Provider 配置说明，模型推荐候选，第一时间适配和回归验证</td></tr></tbody></table><p>这里的“模型推荐”必须基于实际验证。赞助不会改变 SmartPerfetto 的默认 Provider 选择、兼容性结论或技术判断；如果某个模型在真实 trace 分析、工具调用或长程推理里不稳定，文档会如实说明。反过来，如果一个厂商提供了可持续 credits，并且模型在 SmartPerfetto 的真实分析任务中稳定跑通，就适合进入 README 更靠前的位置、Provider 配置指南和推荐模型说明。</p><p>联系方式仍然走当前 sponsor 页面和 README 里的微信 <code>553000664</code>。安全问题、商业授权和企业内部部署需求应单独沟通，不要混在公开 bug issue 里。</p><h2><a href="https://androidperformance.com/2026/05/17/SmartPerfetto-Two-Week-Update/#Bug-%E5%8F%8D%E9%A6%88%E8%AF%A5%E6%80%8E%E4%B9%88%E5%86%99" class="headerlink" title="Bug 反馈该怎么写"></a>Bug 反馈该怎么写</h2><p><img src="https://androidperformance.com/images/SmartPerfetto-Two-Week-Update/bug-feedback.png" alt="SmartPerfetto Bug 反馈清单"></p><p>SmartPerfetto 的 bug 反馈入口是 GitHub Issues。安全问题不要发公开 issue，走 GitHub private advisory 或安全邮箱。</p><p>普通 bug 里至少写清楚当前模板要求的六项：Description、Component、Steps to Reproduce、Trace Information、Logs / Screenshots、Environment。对 SmartPerfetto 来说，还应补齐版本、平台和 LLM 配置，因为很多问题由 provider 协议、模型 tool calling、trace 采集质量、runtime session 状态共同影响，不能只按前端或后端 bug 处理。</p><p>一份可定位的反馈建议包含这些字段：</p><table><thead><tr><th>类别</th><th>要写什么</th></tr></thead><tbody><tr><td>SmartPerfetto 版本</td><td>版本号、commit、Docker image tag、免安装包文件名，至少给出其中一种</td></tr><tr><td>运行方式</td><td>Docker Hub、源码 <code>./start.sh</code>、dev 模式、Windows/macOS/Linux 免安装包、CLI</td></tr><tr><td>平台环境</td><td>OS 版本、浏览器、Node.js 版本；Docker 路径还要写 Docker Desktop/Engine 和 WSL2 状态</td></tr><tr><td>问题组件</td><td>AI Analysis、Skills、Frontend UI Panel、Trace Processor、Backend API、Provider Manager、CLI 等</td></tr><tr><td>复现步骤</td><td>从加载 trace 到点击/输入/切换的最小步骤，写实际结果和期望结果</td></tr><tr><td>Trace 信息</td><td>设备、Android 版本、业务场景、trace category、是否包含 FrameTimeline，trace 大小</td></tr><tr><td>LLM / Provider</td><td>runtime 是 <code>claude-agent-sdk</code> 还是 <code>openai-agents-sdk</code>；provider 名称、模型 ID、Base URL、协议类型、配置来源是 Provider Manager 还是 <code>.env</code></td></tr><tr><td>分析选项</td><td><code>fast</code>、<code>full</code>、<code>auto</code>，是否在多轮追问中切换过模式</td></tr><tr><td>证据定位</td><td>Result ID、HTML report、<code>evidenceRefId</code>、<code>sourceToolCallId</code>、逐句数据引用里的 <code>Q1/C1</code>、相关 SQL 或 Skill 表格</td></tr><tr><td>证据材料</td><td>后端日志、<code>backend/logs/sessions/</code>、截图、HTML report、Result ID、<code>/health</code> 的 <code>aiEngine</code> 片段</td></tr><tr><td>隐私边界</td><td>trace 可能包含业务和用户数据，公开 issue 不要直接上传敏感 trace；可以先贴脱敏信息，必要时再私下沟通样本</td></tr></tbody></table><p>Provider 相关问题要把“模型能聊天”和“模型能稳定 tool call”分开描述。SmartPerfetto 依赖流式输出、tool/function calling、上下文恢复和结构化参数。一个 provider 在普通聊天里正常，不代表它能跑完整 trace 分析。</p><p>Trace 相关问题也要写采集条件。Android 12+ 且包含 FrameTimeline 的 trace 更适合 SmartPerfetto；滑动、启动、ANR、GPU/渲染各自需要不同 category。没有对应数据源时，正确行为应该是标出缺失信号，而不是编一个确定结论。</p><p>分析结论不符合预期时，优先贴报告中的证据位置。比如某个结论写了“主线程 Runnable 等待 120ms”，就把对应 <code>Q1/C1</code>、<code>evidenceRefId</code>、表格行、列名和值一起贴出来。这样反馈可以直接变成 SQL 修复、Skill 分支或报告 contract 修复。</p><h2><a href="https://androidperformance.com/2026/05/17/SmartPerfetto-Two-Week-Update/#%E5%BD%93%E5%89%8D%E6%9C%80%E9%9C%80%E8%A6%81%E7%9A%84%E5%8F%8D%E9%A6%88" class="headerlink" title="当前最需要的反馈"></a>当前最需要的反馈</h2><p>SmartPerfetto 当前缺的是能复现、能回归、能改进 Skill 的样本。泛泛评价很难转成代码修复或 Skill 改进。</p><p>更有价值的反馈通常长这样：</p><ul><li>某条滑动 trace 里，SmartPerfetto 把 jank 归到 RenderThread，但人工看是主线程 Binder 等待。请附上时间段、frame id、相关 SQL 或截图。</li><li>某条报告里的逐句数据引用指到了错误行或缺少关键数值。请附 <code>Q1/C1</code>、<code>evidenceRefId</code>、Result ID、HTML report 和对应表格截图。</li><li>某个 provider 在 <code>openai-agents-sdk</code> 下 tool call 参数变形。请附 runtime、provider、模型 ID、协议类型和 session log。</li><li>某个设备/厂商 trace 缺少常见表，导致 Skill 失败。请附 Android 版本、trace category、失败 Skill 名称和错误日志。</li><li>多 Trace 对比里某个 Result ID 找不到。请附 workspace、可见性、Result ID、当前窗口状态和操作步骤。</li></ul><p>一条好的 bug 反馈应该能变成三类东西之一：代码修复、Skill 分支、回归测试。只有截图和一句“结果不对”，很难判断问题在 trace、模型、provider、前端状态还是后端工具。</p><h2><a href="https://androidperformance.com/2026/05/17/SmartPerfetto-Two-Week-Update/#%E6%94%B6%E6%9D%9F" class="headerlink" title="收束"></a>收束</h2><p>SmartPerfetto 这两周的变化，方向很清楚：从“在 Perfetto 里加一个 AI 对话窗口”，走向“把 trace 分析变成可查询、可复用、可分享、可回归的工程系统”。</p><p>它仍处在快速开发阶段。公开 API、内部合约、Provider preset、企业部署面都会继续调整。对普通用户来说，最稳的路径是用 Docker 或免安装包跑一条自己的 trace；对贡献者来说，最有用的输入是可复现 trace、能说明错误归因的证据、能补进 Skill/策略的 SQL 和回归样本。</p><p>如果你已经在 Android 性能工作里使用 Perfetto，SmartPerfetto 现在值得再试一次。两周前的介绍已经不足以代表当前仓库状态。</p>
				<p><strong>您可能还对下面的文章感兴趣：</strong></p>
				<p><ol><li><a href="https://blogread.cn/it/article.php?id=8433" target="_blank">Android Perfetto 系列 4：使用命令行在本地打开超大 Trace</a> [2026-06-03 09:03:23]</li></ol></p>]]></description>
		<content><![CDATA[SmartPerfetto 在两周内完成了从单条 trace 的 AI 问答工具向可复用分析平台的演进。核心变化体现在多 Trace 分析结果对比、证据三层保障机制与双模型运行时支持。

新增的多 Trace 对比功能，允许用户对比已完成分析的结果快照，而非必须同时打开两条 trace，极大便利了性能回归与 A/B 测试场景。项目强化了结果可靠性，构建了从 SQL 执行（通过 stdlib guardrail 自动补齐依赖、校验安全性）到证据来源（为数据封装添加稳定索引 ID），再到报告结论（支持逐句数据引用映射）的完整 traceability 链条，使用户能精准溯源任何数字的产生过程。

运行时层面，正式引入 OpenAI Agents SDK 作为与 Claude Agent SDK 并列的一等运行时，并提供可视化 Provider Manager 进行配置管理，方便用户切换不同的模型服务。此外，渲染管线教学功能重构为基于当前 trace 实际观测事件生成，而非静态模板。一系列针对大文件上传、进程残留清理、多环境兼容性的修复，则显著提升了工具的部署与启动成功率。]]></content>
	</item>
	<item>
		<title>从企业版 Istio 迁移到社区版：一场给高速行驶汽车换轮胎的实践</title>
		<link>https://blogread.cn/it/article.php?id=8583</link>
		<author>crossoverJie</author>
		<pubDate>2026-06-03 09:03:24</pubDate>
		<category domain="https://blogread.cn/it/category.php?id=18">DevOps</category>
		<guid>https://blogread.cn/it/article.php?id=8583</guid>
		<comments>https://blogread.cn/it/article.php?id=8583#comment</comments>
		<description><![CDATA[<p><strong>标签：</strong>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=Istio" target="_blank">Istio</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=Kubernetes" target="_blank">Kubernetes</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=%E6%9C%8D%E5%8A%A1%E7%BD%91%E6%A0%BC" target="_blank">服务网格</a></p><h1><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#%E8%83%8C%E6%99%AF" class="headerlink" title="背景"></a>背景</h1><p>最近我们在做一件非常危险的大事——把用了好几年的腾讯云企业版 Istio 服务网格迁移到社区开源版。</p><p>事情的起因是腾讯云突然宣布不再维护 Istio 服务网格了，后续也不会推出新版本。这就导致我们的网格一直停留在旧版本，进而连带着 k8s 这些基础组件也很难升级。可以说是血的教训：用托管服务一时爽，一旦厂商放弃维护，迁移成本还是得自己扛。</p><p>这事儿其实拖了很久，毕竟迁移涉及到的系统非常多，相当于要对「高速行驶的汽车更换轮胎」，稍有不慎就是车毁人亡。虽然已经测试验证的七七八八了，但一直不敢动手。</p><p>直到最近，我们利用 AI 对 Istio 关键代码进行了深入分析，从源头来确保迁移的可靠性——这也算 AI 在实际工程中的一个应用案例了。</p><h1><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#%E8%BF%81%E7%A7%BB%E6%96%B9%E6%A1%88%E6%A6%82%E8%A7%88" class="headerlink" title="迁移方案概览"></a>迁移方案概览</h1><p>我们采用的是<strong>双控制面并行 + 按 namespace 灰度迁移</strong>的策略，核心思路是：</p><ol><li><strong>并行部署</strong>：在同一个集群里同时运行企业版和社区版两套控制面</li><li><strong>标签驱动</strong>：通过 namespace 的 <code>istio.io/rev</code> 标签决定 Pod 注入哪个版本的 sidecar</li><li><strong>discoverySelectors</strong>：社区版控制面只感知打了特定标签的 namespace，实现隔离</li><li><strong>灰度切换</strong>：逐个 namespace 切换，随时可回滚</li></ol><h2><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#%E5%AE%89%E8%A3%85%E7%A4%BE%E5%8C%BA%E7%89%88%E6%8E%A7%E5%88%B6%E9%9D%A2" class="headerlink" title="安装社区版控制面"></a>安装社区版控制面</h2><p>首先安装社区版 Istio 控制面，指定一个独立的 revision 和 namespace：</p><figure class="highlight yaml"><pre class="blogread-code language-yaml" data-lang="yaml"><code class="language-yaml">apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  namespace: istio-1-16-5
spec:
  profile: minimal
  revision: istio-1-16-5
  meshConfig:
    enablePrometheusMerge: false
    accessLogFile: /dev/stdout
    # 关键：只感知带特定标签的 namespace
    discoverySelectors:
      - matchLabels:
          usergroup: istio-1-16-5
  values:
    global:
      istioNamespace: istio-1-16-5</code></pre></figure><blockquote><p><code>discoverySelectors</code> 是这次迁移的安全保证，确保社区版和企业版控制面不会互相干扰。</p></blockquote><p>然后安装 IngressGateway：</p><figure class="highlight yaml"><pre class="blogread-code language-yaml" data-lang="yaml"><code class="language-yaml">apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  name: istio-public-api-ingressgateway
spec:
  profile: empty  # 不安装 CRD 或控制平面
  components:
    ingressGateways:
    - name: istio-ingressgateway
      namespace: istio-1-16-5
      enabled: true
      label:
        istio: oss-public-api-ingressgateway
  values:
    gateways:
      istio-ingressgateway:
        injectionTemplate: gateway
        runAsRoot: true</code></pre></figure><p>执行安装：</p><figure class="highlight bash"><pre class="blogread-code language-bash" data-lang="bash"><code class="language-bash">istioctl install -y -f istio-control-plane.yaml
istioctl install -f istio-gateway.yaml</code></pre></figure><blockquote><p>使用 istioctl 工具安装</p></blockquote><h2><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#Namespace-%E5%88%87%E6%8D%A2%E6%B5%81%E7%A8%8B" class="headerlink" title="Namespace 切换流程"></a>Namespace 切换流程</h2><p>给要迁移的 namespace 打上标签：</p><figure class="highlight yaml"><pre class="blogread-code language-yaml" data-lang="yaml"><code class="language-yaml">labels:
  istio.io/rev: istio-1-16-5
  usergroup: istio-1-16-5</code></pre></figure><blockquote><p>注意：标签打在 namespace 上之后，<strong>已有的 Pod 不会自动重启</strong>，需要手动 <code>rollout restart</code> 才会触发重新注入。</p></blockquote><p>切换的核心机制是：<strong>MutatingWebhookConfiguration 根据 namespace 标签匹配</strong>。当 Pod 创建时，K8s API Server 会根据 namespace 的 <code>istio.io/rev</code> 标签路由到对应的 webhook，从而注入对应版本的 sidecar。</p><h2><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#%E7%BD%91%E5%85%B3%E9%85%8D%E7%BD%AE" class="headerlink" title="网关配置"></a>网关配置</h2><p>Gateway CR 的 selector 与 Pod 标签做等值匹配：</p><figure class="highlight yaml"><pre class="blogread-code language-yaml" data-lang="yaml"><code class="language-yaml">apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: istio-public-api-ingressgateway
  namespace: default
spec:
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - '*.y7test.com'
  selector:
    istio: ingressgateway</code></pre></figure><p>迁移期间两套网关并存，各自连接自己的控制面：</p><table><thead><tr><th>控制面</th><th>网关 Pod</th><th>感知的 VirtualService 范围</th></tr></thead><tbody><tr><td>企业版</td><td>旧网关（istio-system）</td><td>全量</td></tr><tr><td>社区版</td><td>新网关（istio-1-16-5）</td><td>仅 <code>usergroup: istio-1-16-5</code> 的 namespace</td></tr></tbody></table><blockquote><p>DNS 切换时机：等新网关稳定后，修改 DNS 指向新 IP。TTL 期间两套网关同时承接流量。</p></blockquote><h1><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#%E5%85%B3%E9%94%AE%E6%BA%90%E7%A0%81%E9%AA%8C%E8%AF%81" class="headerlink" title="关键源码验证"></a>关键源码验证</h1><p>这次迁移最大的不同是，我们不只是「试试能不能跑」，而是<strong>深入到源码层面验证每个环节的可行性</strong>。</p><h2><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#1-Sidecar-%E6%B3%A8%E5%85%A5%E7%9A%84-Revision-%E9%80%89%E6%8B%A9" class="headerlink" title="1. Sidecar 注入的 Revision 选择"></a>1. Sidecar 注入的 Revision 选择</h2><p>注入由 <code>MutatingWebhookConfiguration</code> 的 <code>namespaceSelector</code> 决定。源码在 <code>istioctl/pkg/injector/injector-list.go</code>：</p><figure class="highlight go"><pre class="blogread-code language-go" data-lang="go"><code class="language-go">func getInjector(namespace *corev1.Namespace, hooks []admitv1.MutatingWebhookConfiguration) *admitv1.MutatingWebhookConfiguration {
    for _, hook := range hooks {
        for _, webhook := range hook.Webhooks {
            nsSelector, err := metav1.LabelSelectorAsSelector(webhook.NamespaceSelector)
            if err != nil { continue }
            // 关键：用 namespace 的当前标签做匹配
            if nsSelector.Matches(api_pkg_labels.Set(namespace.ObjectMeta.Labels)) {
                return &amp;hook
            }
        }
    }
    return nil
}</code></pre></figure><p><strong>结论</strong>：<code>kubectl label ns &lt;ns&gt; istio.io/rev=self-1-16-5</code> 修改标签后，新建的 Pod 会自动命中社区版的 webhook。</p><h2><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#2-DiscoverySelectors-%E9%9A%94%E7%A6%BB%E6%9C%BA%E5%88%B6" class="headerlink" title="2. DiscoverySelectors 隔离机制"></a>2. DiscoverySelectors 隔离机制</h2><p>社区版 istiod 通过 <code>discoverySelectors</code> 决定感知哪些 namespace：</p><figure class="highlight go"><pre class="blogread-code language-go" data-lang="go"><code class="language-go">func (d *discoveryNamespacesFilter) SelectorsChanged(
    discoverySelectors []*metav1.LabelSelector,
) (selectedNamespaces []string, deselectedNamespaces []string) {
    // 遍历所有 Namespace，匹配 selector 的入选
    for _, ns := range namespaceList {
        for _, selector := range selectors {
            if selector.Matches(labels.Set(ns.Labels)) {
                newDiscoveryNamespaces.Insert(ns.Name)
            }
        }
    }
    // ...
}

func (d *discoveryNamespacesFilter) Filter(obj any) bool {
    // 未配置 discoverySelectors 则允许所有
    if len(d.discoverySelectors) == 0 {
        return true
    }
    // 只处理选中 namespace 的资源
    return d.discoveryNamespaces.Contains(object.GetNamespace())
}</code></pre></figure><p><strong>结论</strong>：标签变更实时生效，无需重启 istiod。</p><h2><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#3-CA-%E6%A0%B9%E8%AF%81%E4%B9%A6%E7%9A%84%E8%87%AA%E5%8A%A8%E4%B8%8B%E5%8F%91" class="headerlink" title="3. CA 根证书的自动下发"></a>3. CA 根证书的自动下发</h2><p>Namespace 入选后，<code>NamespaceController</code> 会自动将社区版 istiod 的 CA 证书写入该 namespace 的 <code>istio-ca-root-cert</code> ConfigMap：</p><figure class="highlight go"><pre class="blogread-code language-go" data-lang="go"><code class="language-go">func (nc *NamespaceController) insertDataForNamespace(o types.NamespacedName) error {
    meta := metav1.ObjectMeta{
        Name:      CACertNamespaceConfigMap,  // "istio-ca-root-cert"
        Namespace: ns,
    }
    // 写入自建 istiod 的根证书
    return k8s.InsertDataToConfigMap(nc.client, nc.configmapLister, meta,
        nc.caBundleWatcher.GetCABundle())
}</code></pre></figure><p><strong>为什么关键</strong>：sidecar 的 pilot-agent 用这个证书验证 istiod 的 TLS 身份，证书对了才能建立 XDS 连接。</p><h2><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#4-Sidecar-%E8%BF%9E%E6%8E%A5%E6%96%B0-Istiod-%E7%9A%84%E8%B7%AF%E5%BE%84" class="headerlink" title="4. Sidecar 连接新 Istiod 的路径"></a>4. Sidecar 连接新 Istiod 的路径</h2><p>注入模板中的 <code>DiscoveryAddress</code> 由 revision 和 namespace 计算得出：</p><figure class="highlight go"><pre class="blogread-code language-go" data-lang="go"><code class="language-go">func IstiodHost(ns string, revision string) string {
    istiod := "istiod"
    if isRevisioned(revision) {
        istiod = fmt.Sprintf("%s-%s", istiod, revision)
    }
    return fmt.Sprintf("%s.%s.svc", istiod, ns)
}

// 结果：istiod-self-1-16-5.istio-self.svc:15012</code></pre></figure><p>pilot-agent 启动时从挂载的 ConfigMap 读取根证书：</p><figure class="highlight go"><pre class="blogread-code language-go" data-lang="go"><code class="language-go">func (a *Agent) FindRootCAForXDS() (string, error) {
    // 默认路径：/var/run/secrets/istio/root-cert.pem
    rootCAPath = path.Join(CitadelCACertPath, constants.CACertNamespaceConfigMapDataName)
    // ...
}</code></pre></figure><p><strong>结论</strong>：只要 webhook 注入正确，新 Pod 会自动连接到社区版 istiod，无需额外配置。</p><h2><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#5-%E8%B7%A8%E6%8E%A7%E5%88%B6%E9%9D%A2%E4%BA%92%E9%80%9A%EF%BC%88ALLOW-ANY%EF%BC%89" class="headerlink" title="5. 跨控制面互通（ALLOW_ANY）"></a>5. 跨控制面互通（ALLOW_ANY）</h2><p>迁移期间，新 sidecar 可能需要访问旧 namespace 的服务。由于社区版 istiod 不感知旧 namespace，不会生成对应的 Cluster/Endpoint。此时流量会走 <code>PassthroughCluster</code>：</p><figure class="highlight go"><pre class="blogread-code language-go" data-lang="go"><code class="language-go">func buildOutboundCatchAllNetworkFiltersOnly(...) []*listener.Filter {
    var egressCluster string
    if util.IsAllowAnyOutbound(node) {
        // ALLOW_ANY 模式：未知流量直接透传到原始目标
        egressCluster = util.PassthroughCluster
    } else {
        // REGISTRY_ONLY 模式：未知流量丢弃
        egressCluster = util.BlackHoleCluster
    }
    // ...
}</code></pre></figure><p><strong>结论</strong>：<code>meshConfig.outboundTrafficPolicy.mode: ALLOW_ANY</code> 确保迁移期间跨控制面的流量可以正常通行。</p><h2><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#6-%E7%BD%91%E5%85%B3%E8%B7%AF%E7%94%B1%E9%9A%94%E7%A6%BB" class="headerlink" title="6. 网关路由隔离"></a>6. 网关路由隔离</h2><p>新网关的路由只包含已迁移 namespace 的 VirtualService：</p><figure class="highlight go"><pre class="blogread-code language-go" data-lang="go"><code class="language-go">func (configgen *ConfigGeneratorImpl) buildGatewayHTTPRouteConfig(...) *route.RouteConfiguration {
    // ...
    for _, server := range servers {
        // PushContext 中的 VS 已经被 discoverySelectors 过滤过
        virtualServices = push.VirtualServicesForGateway(node.ConfigNamespace, gatewayName)
        // 旧 namespace 的 VS 不在其中 → 路由为空
    }
}</code></pre></figure><p><strong>结论</strong>：新旧网关的路由天然隔离，不会出现流量错乱。</p><h1><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#%E8%B8%A9%E8%BF%87%E7%9A%84%E5%9D%91" class="headerlink" title="踩过的坑"></a>踩过的坑</h1><h2><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#%E8%AF%81%E4%B9%A6%E4%B8%8D%E5%8C%B9%E9%85%8D" class="headerlink" title="证书不匹配"></a>证书不匹配</h2><p>已经安装社区版 istio 后再安装企业版网关，启动失败，提示证书不匹配。原因是 sidecar 注入时使用了错误的 CA 证书。</p><p><img src="https://cdn.jsdelivr.net/gh/crossoverJie/images@main/images/images20260414170958.png"></p><blockquote><p>证书不匹配错误</p></blockquote><p><strong>解决方案</strong>：手动修改企业版 deployment 的 label，使其匹配社区版的 revision。</p><h2><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#503-%E9%94%99%E8%AF%AF" class="headerlink" title="503 错误"></a>503 错误</h2><p>社区版网关出现 503，查看日志发现 upstream 连接失败。</p><p><img src="https://cdn.jsdelivr.net/gh/crossoverJie/images@main/images/images20260414171224.png"></p><p><img src="https://cdn.jsdelivr.net/gh/crossoverJie/images@main/images/images20260414171230.png"></p><blockquote><p>503 错误及日志</p></blockquote><p><strong>解决方案</strong>：namespace 需要匹配 <code>discoverySelectors</code> 配置的 label，确保 istiod 能感知到该 namespace 的服务。</p><p><img src="https://cdn.jsdelivr.net/gh/crossoverJie/images@main/images/images20260414171242.png"></p><p><img src="https://cdn.jsdelivr.net/gh/crossoverJie/images@main/images/images20260414171249.png"></p><blockquote><p>namespace 打上对应 label 后问题解决</p></blockquote><h2><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#%E4%B8%8D%E8%83%BD%E7%94%A8-purge-%E5%8D%B8%E8%BD%BD" class="headerlink" title="不能用 --purge 卸载"></a>不能用 <code>--purge</code> 卸载</h2><p>安装社区版 istio 之后不能用 <code>istioctl uninstall --purge</code> 卸载，会把企业版的 CRD 也一并删掉。</p><p><strong>解决方案</strong>：只能手动删除社区版相关的 deployment 和 webhook。</p><h2><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#%E5%9B%9E%E6%BB%9A%E5%A4%B1%E8%B4%A5" class="headerlink" title="回滚失败"></a>回滚失败</h2><p>如果回滚到企业版失败，通常是社区版的 webhook 还在拦截请求。</p><p><strong>解决方案</strong>：删除社区版的 <code>MutatingWebhookConfiguration</code> 和相关的 CRD。</p><h1><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#%E8%BF%81%E7%A7%BB%E6%A3%80%E6%9F%A5%E6%B8%85%E5%8D%95" class="headerlink" title="迁移检查清单"></a>迁移检查清单</h1><h3><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#%E8%BF%81%E7%A7%BB%E5%89%8D" class="headerlink" title="迁移前"></a>迁移前</h3><ul><li> 备份 CRD、namespace 标签、Gateway 配置</li><li> 社区版 istiod 和网关启动并健康</li><li> 确认 <code>outboundTrafficPolicy: ALLOW_ANY</code> 已配置</li><li> 社区版 <code>proxy-status</code> 无 STALE</li></ul><h3><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#%E8%BF%81%E7%A7%BB%E5%8D%95%E4%B8%AA-namespace" class="headerlink" title="迁移单个 namespace"></a>迁移单个 namespace</h3><ul><li> 打上标签：<code>istio.io/rev=self-1-16-5</code>、<code>usergroup=istio-1-16-5</code></li><li> 确认 <code>istio-ca-root-cert</code> ConfigMap 已自动创建</li><li> 滚动重启 deployment</li><li> 验证 sidecar 连接新 istiod：<code>istioctl proxy-status</code></li><li> 验证跨命名空间调用正常</li><li> 通过新网关访问该 namespace 服务正常</li></ul><h3><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#DNS-%E5%88%87%E6%8D%A2" class="headerlink" title="DNS 切换"></a>DNS 切换</h3><ul><li> 新网关 External IP 稳定</li><li> 修改 DNS 指向新 IP</li><li> TTL 到期后监控新网关流量</li><li> 保留旧网关至少 1 个 TTL 周期</li></ul><h3><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#%E8%BF%81%E7%A7%BB%E5%90%8E" class="headerlink" title="迁移后"></a>迁移后</h3><ul><li> 所有 namespace 的 <code>proxy-status</code> 显示新 istiod</li><li> <code>pilot_xds_push_errors_total</code> 无增长</li><li> 错误率与迁移前一致</li><li> 旧网关流量降为 0 后下线企业版控制面</li></ul><h1><a href="http://crossoverjie.top/2026/04/15/istio-enterprise-to-community-migration/#%E6%80%BB%E7%BB%93" class="headerlink" title="总结"></a>总结</h1><p>这次迁移从筹备到最终执行拖了挺久，主要是涉及面广、风险高。但通过深入源码分析每个关键环节，我们对整个迁移过程有了更清晰的把控。</p><p>几个核心经验：</p><ol><li><strong>discoverySelectors 是隔离的关键</strong>：确保两套控制面互不干扰</li><li><strong>Webhook 标签匹配决定注入版本</strong>：namespace 标签变更后要重启 Pod 才生效</li><li><strong>ALLOW_ANY 保障灰度期间的互通</strong>：新 sidecar 可以访问旧服务</li><li><strong>网关路由天然隔离</strong>：新旧网关各自连接自己的控制面</li></ol><p>当然，实际的迁移操作还是由我们人工来执行的，AI 在这个过程中主要提供了「理论支持」——帮我们快速定位源码逻辑、验证方案可行性。</p><p>这也让我感受到，AI 在复杂工程问题上的价值不只是「写代码」，更重要的是<strong>辅助理解复杂系统的工作原理</strong>，让我们在做高风险变更时更有底气。</p><p>毕竟，给高速行驶的汽车换轮胎，光靠胆子大是不够的，还得对汽车的每个零件都了如指掌。</p><hr><p>参考链接：</p><ul><li><a href="https://istio.io/v1.18/docs/setup/install/istioctl">Istio 安装文档</a></li><li><a href="https://preliminary.istio.io/latest/docs/ops/common-problems/injection/">Sidecar 注入问题排查</a></li></ul>
				<p><strong>您可能还对下面的文章感兴趣：</strong></p>
				<p><ol><li><a href="https://blogread.cn/it/article.php?id=8577" target="_blank">k3s 容器 mirror 配置方法</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8398" target="_blank">Ack集群Pod独占EIP实践</a> [2026-06-03 09:03:23]</li><li><a href="https://blogread.cn/it/article.php?id=8362" target="_blank">70 后都跑哪去了？</a> [2021-06-13 23:12:10]</li><li><a href="https://blogread.cn/it/article.php?id=8105" target="_blank">状况共有</a> [2016-07-18 00:10:43]</li><li><a href="https://blogread.cn/it/article.php?id=7520" target="_blank">“集群和负载均衡”的通俗版解释</a> [2015-07-23 14:03:51]</li><li><a href="https://blogread.cn/it/article.php?id=7214" target="_blank">Kubernetes – Google分布式容器技术初体验</a> [2015-01-04 23:20:13]</li><li><a href="https://blogread.cn/it/article.php?id=7121" target="_blank">中大型移动互联网公司技术架构选择</a> [2014-12-02 00:04:44]</li><li><a href="https://blogread.cn/it/article.php?id=7029" target="_blank">如何对待开发团队中那个拖后腿的人？</a> [2014-11-26 22:57:18]</li><li><a href="https://blogread.cn/it/article.php?id=6692" target="_blank">敏捷就是“团队快乐”</a> [2013-09-15 22:39:34]</li><li><a href="https://blogread.cn/it/article.php?id=6616" target="_blank">想法与方法</a> [2013-08-15 12:53:50]</li><li><a href="https://blogread.cn/it/article.php?id=6476" target="_blank">各就各位，各司其职</a> [2013-06-18 13:49:07]</li><li><a href="https://blogread.cn/it/article.php?id=5762" target="_blank">基础设施之殇</a> [2012-09-02 21:22:49]</li><li><a href="https://blogread.cn/it/article.php?id=5238" target="_blank">那些年，我们一起合作时头痛的事</a> [2012-04-22 14:51:02]</li><li><a href="https://blogread.cn/it/article.php?id=4953" target="_blank">云计算的技术架构与实现分析</a> [2012-02-07 23:19:31]</li><li><a href="https://blogread.cn/it/article.php?id=4682" target="_blank">管道工程序员</a> [2011-12-18 22:23:02]</li><li><a href="https://blogread.cn/it/article.php?id=3862" target="_blank">让重复变的机械化</a> [2011-06-22 00:02:25]</li><li><a href="https://blogread.cn/it/article.php?id=3386" target="_blank">Twitter新员工的入职过程是怎样的？</a> [2011-03-02 23:05:57]</li><li><a href="https://blogread.cn/it/article.php?id=3363" target="_blank">今年，我们二十七八岁</a> [2011-03-01 22:41:16]</li><li><a href="https://blogread.cn/it/article.php?id=3350" target="_blank">心目中的容量规划平台</a> [2011-02-28 23:12:49]</li><li><a href="https://blogread.cn/it/article.php?id=3318" target="_blank">焦虑的意义</a> [2011-02-22 23:28:02]</li><li><a href="https://blogread.cn/it/article.php?id=2799" target="_blank">大公司与风险管理</a> [2010-12-06 21:25:11]</li><li><a href="https://blogread.cn/it/article.php?id=2461" target="_blank">职场的选择之道</a> [2010-10-07 08:29:06]</li><li><a href="https://blogread.cn/it/article.php?id=1986" target="_blank">说说产品开发到发布过程中的问题</a> [2010-07-19 22:37:05]</li><li><a href="https://blogread.cn/it/article.php?id=1512" target="_blank">我们需要一条Web开发的流水线</a> [2010-05-05 13:28:54]</li><li><a href="https://blogread.cn/it/article.php?id=965" target="_blank">攻山头的故事</a> [2010-01-13 09:08:24]</li><li><a href="https://blogread.cn/it/article.php?id=288" target="_blank">互联网产业链分析【图】</a> [2009-10-22 21:55:21]</li></ol></p>]]></description>
		<content><![CDATA[针对腾讯云企业版Istio停止维护的情况，团队需将服务网格迁移至社区开源版，此过程如同为高速行驶的汽车更换轮胎，风险极高。为确保可靠性，迁移采用了双控制面并行与按namespace灰度切换的策略：在集群内同时运行企业版和社区版控制面，通过istio.io/rev和usergroup标签驱动sidecar注入版本，并利用discoverySelectors实现控制面隔离，仅感知特定标签的namespace，保障并行环境互不干扰。迁移中深入源码验证关键机制，包括MutatingWebhookConfiguration如何根据namespace标签动态匹配注入版本、discoverySelectors的实时过滤与证书自动下发逻辑，以及ALLOW_ANY流量策略确保跨控制面互通。实践遇到了证书不匹配、503错误等问题，通过调整标签和确保discoverySelectors配置解决。AI技术被用于辅助分析Istio源码，快速定位逻辑并验证方案可行性，提升了高风险变更的把控能力。整体迁移依赖详细的检查清单和渐进式操作，最终实现了控制面平滑过渡与流量安全切换。]]></content>
	</item>
	<item>
		<title>手搓一个 Agent 驱动的项目 Wiki 生成方案</title>
		<link>https://blogread.cn/it/article.php?id=8582</link>
		<author>crossoverJie</author>
		<pubDate>2026-06-03 09:03:24</pubDate>
		<category domain="https://blogread.cn/it/category.php?id=4">AI</category>
		<guid>https://blogread.cn/it/article.php?id=8582</guid>
		<comments>https://blogread.cn/it/article.php?id=8582#comment</comments>
		<description><![CDATA[<p><strong>标签：</strong>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=Agent" target="_blank">Agent</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=Claude%20Code" target="_blank">Claude Code</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=DeepWiki" target="_blank">DeepWiki</a></p><h1><a href="http://crossoverjie.top/2026/05/18/AI/cc-generate-wiki/#%E8%83%8C%E6%99%AF" class="headerlink" title="背景"></a>背景</h1><p>最近我一直在折腾项目文档生成的事情。之前写过两篇关于 deepwiki 的文章：<a href="https://crossoverjie.top/2025/12/25/AI/deepwiki-rag-principle/">deepwiki-rag-principle</a> 讲了 RAG 原理，<a href="https://crossoverjie.top/2026/03/17/AI/deepwiki-optimize-line-number/">deepwiki-optimize-line-number</a> 聊了给代码加行号的优化。</p><p>经过几轮迭代，搞了两个优化：</p><ul><li>代码加上行号前缀</li><li>基于 Proto 文件生成确定性目录</li></ul><p>这两个优化背后其实是同一个思路：<strong>把确定的东西明确告诉 AI，不确定的才让 AI 来发挥</strong>。</p><table><thead><tr><th>类型</th><th>内容</th><th>处理方式</th></tr></thead><tbody><tr><td>确定的</td><td>代码行号</td><td>直接给 LLM 标注好</td></tr><tr><td>确定的</td><td>gRPC 接口列表、目录结构</td><td>代码解析，不经过 LLM</td></tr><tr><td>不确定的</td><td>函数功能解释</td><td>交给 LLM 归纳</td></tr><tr><td>不确定的</td><td>项目架构分析</td><td>交给 LLM 总结</td></tr><tr><td>不确定的</td><td>代码关联关系</td><td>交给 LLM 推理</td></tr></tbody></table><p>LLM 擅长理解、归纳和总结，但精准计算和结构化数据生成这块确实不太行。分开处理，各取所长，效果就好很多了。</p><p>这些都是用开源的 deepwiki-open 来做的。</p><h1><a href="http://crossoverjie.top/2026/05/18/AI/cc-generate-wiki/#%E9%97%AE%E9%A2%98" class="headerlink" title="问题"></a>问题</h1><p>虽然最终生成的内容效果还不错，但还有个让人头疼的问题：</p><blockquote><p>需要为整个项目生成总结性的内容，比如项目架构、流程图、ER 图等。</p></blockquote><p>这些数据得根据之前已经生成的内容来总结，但 deepwiki 的架构是每个页面独立生成的。而 ER 图这种，我们希望是基于已生成的内容再汇总生成。</p><p>在现有架构下实现这个比较困难，索性换个思路。</p><h1><a href="http://crossoverjie.top/2026/05/18/AI/cc-generate-wiki/#%E6%96%B0%E6%96%B9%E6%A1%88" class="headerlink" title="新方案"></a>新方案</h1><p>日常用 Claude Code（后面简称 CC）的时候发现，它可以精准定位到具体业务逻辑所在的代码片段，也能帮我们分析项目、提炼内容。</p><p>这不就是个完美的 Wiki 系统吗？直接让 CC 分析项目内容，生成静态页面，就能得到一个精准的 Wiki 了。</p><p>CC 也是通过一些内置 tools 来实现精准代码检索的，不需要 deepwiki 那种向量数据库，架构简单很多。</p><p>这里简单聊下 CC 的代码搜索原理。传统 RAG 方案会先把代码向量化存入数据库，然后通过语义相似度检索。但 CC 并没有走这条路，而是直接用了一套<strong>工具驱动（Tool-based）</strong>的检索机制：</p><table><thead><tr><th>工具</th><th>功能</th><th>使用场景</th></tr></thead><tbody><tr><td><code>Read</code></td><td>直接读取文件内容</td><td>已知文件路径时</td></tr><tr><td><code>Bash(grep)</code></td><td>基于正则匹配搜索代码</td><td>按关键字/符号查找</td></tr><tr><td><code>Bash(find)</code></td><td>遍历文件系统</td><td>发现文件、按模式筛选</td></tr><tr><td><code>LSP</code></td><td>语言服务器协议导航</td><td>跳转到定义、查找引用</td></tr><tr><td><code>Agent</code></td><td>子 Agent 并行搜索</td><td>大规模代码库分治检索</td></tr></tbody></table><p>这种设计的巧妙之处在于：LLM 不依赖向量化后的”模糊记忆”，而是像人类开发者一样，通过<strong>精确的工具调用</strong>来定位代码。比如要找某个函数定义，CC 可能会先 <code>grep</code> 找到候选文件，再用 <code>Read</code> 精读确认，最后用 <code>LSP</code> 验证引用关系——整个过程是<strong>确定性的、可解释的</strong>。</p><blockquote><p>想了解更多细节可以参考 Anthropic 官方文档：<a href="https://docs.anthropic.com/en/docs/claude-code/overview">Claude Code Overview</a></p></blockquote><p>后续 repo 有更新，只需要让 CC 读取 git log 变更记录，自动更新修改的内容就行。</p><p><img src="https://cdn.jsdelivr.net/gh/crossoverJie/images@main/images/images20260518180243.png" alt="CC Wiki 架构"></p><h2><a href="http://crossoverjie.top/2026/05/18/AI/cc-generate-wiki/#%E6%8F%90%E7%82%BC-Skill" class="headerlink" title="提炼 Skill"></a>提炼 Skill</h2><p>考虑内部项目众多，为了让其他项目也能复用这个能力，我把生成静态网站的过程写成了一个 Skill。其他项目只需要在 CC 里调用这个 Skill 即可。</p><p>目录结构大概长这样：</p><figure class="highlight dos"><pre class="blogread-code language-dos" data-lang="dos"><code class="language-dos">├── SKILL.md
├── skill.json
├── templates/
│   ├── page-architecture.md
│   ├── page-er.md
│   ├── page-features.md
│   └── page-service.md
└── wiki/
    ├── 01-系统架构.md
    ├── 02-核心功能.md
    ├── 03-ER图.md
    ├── index.html
    └── service/
        └── *.md</code></pre></figure><h1><a href="http://crossoverjie.top/2026/05/18/AI/cc-generate-wiki/#%E4%BC%98%E7%BC%BA%E7%82%B9%E5%AF%B9%E6%AF%94" class="headerlink" title="优缺点对比"></a>优缺点对比</h1><h2><a href="http://crossoverjie.top/2026/05/18/AI/cc-generate-wiki/#deepwiki" class="headerlink" title="deepwiki"></a>deepwiki</h2><p><strong>优点：</strong></p><ul><li>可以一键生成整个项目，生成过程中不需要人工干预</li></ul><p><strong>缺点：</strong></p><ul><li>无法精准调整某个页面</li><li>对于需要汇总已生成数据的需求，架构无法满足</li></ul><h2><a href="http://crossoverjie.top/2026/05/18/AI/cc-generate-wiki/#Claude-Code-%E6%96%B9%E6%A1%88" class="headerlink" title="Claude Code 方案"></a>Claude Code 方案</h2><p><strong>优点：</strong></p><ul><li>可以精准调整每一个页面</li><li>数据可以做到非常精准</li></ul><p><strong>缺点：</strong></p><ul><li>无法一键生成结果，需要多轮对话调试</li><li>如果部署到服务器上，需要外部工具对 CC 进行管理</li></ul><h1><a href="http://crossoverjie.top/2026/05/18/AI/cc-generate-wiki/#%E6%80%BB%E7%BB%93" class="headerlink" title="总结"></a>总结</h1><p>其实这两个方案并不冲突，可以看成不同阶段的选择：</p><ul><li>项目初期需要快速搭个文档框架 → deepwiki 一键生成</li><li>项目成熟需要精准可控的文档 → CC 方案慢慢打磨</li></ul><p>CC 方案的核心优势在于<strong>可控性</strong>。虽然要多花点时间调试，但生成的内容质量确实更高，特别是涉及到跨文件关联分析的时候。</p><p>当然，CC 方案目前还不能完全自动化，这是最大的限制。不过随着 CC 生态的发展，相信后面会有更好的解法。让子弹飞一会。</p>
				<p><strong>您可能还对下面的文章感兴趣：</strong></p>
				<p><ol><li><a href="https://blogread.cn/it/article.php?id=8586" target="_blank">了解 Claude Code 的提示词工程</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8517" target="_blank">Claude Code 从 AWS Bedrock 切换到 Team 订阅指南</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8497" target="_blank">SmartPerfetto 架构文章 Q&amp;amp;A：8 个深度技术问答</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8494" target="_blank">别再傻等了，给 Claude Code 装个通知铃铛</a> [2026-06-03 09:03:24]</li><li><a href="https://blogread.cn/it/article.php?id=8493" target="_blank">全程用 Claude Code 搓了一个 macOS 原生应用：SkillDeck</a> [2026-06-03 09:03:24]</li></ol></p>]]></description>
		<content><![CDATA[作者在项目文档生成实践中，发现传统RAG方案如deepwiki在处理确定性结构（如目录、接口列表）与不确定性分析（如架构总结、ER图）时存在局限。其核心思路是：将确定性信息（如行号、Proto文件）明确处理，仅将归纳、推理等任务交由LLM，以实现各取所长。然而，deepwiki的独立页面架构难以满足基于已生成内容进行汇总的需求。

为此，作者转向基于Claude Code的方案。该工具采用工具驱动检索机制，通过Read、grep、LSP等确定性工具链精准定位代码，而非依赖向量化索引。这使生成的Wiki内容更准确可控，并可复用为跨项目Skill。尽管需要多轮调试且自动化程度较低，但其在内容质量、尤其是跨文件关联分析上优势明显。文章最终提出互补策略：项目初期用deepwiki快速搭建框架，成熟阶段则用CC方案精细打磨可控的文档体系。]]></content>
	</item>
	<item>
		<title>Terraform 极简入门：从 AWS-CLI 到基础设施即代码（IaC）</title>
		<link>https://blogread.cn/it/article.php?id=8581</link>
		<author>元视角</author>
		<pubDate>2026-06-03 09:03:24</pubDate>
		<category domain="https://blogread.cn/it/category.php?id=18">DevOps</category>
		<guid>https://blogread.cn/it/article.php?id=8581</guid>
		<comments>https://blogread.cn/it/article.php?id=8581#comment</comments>
		<description><![CDATA[<p><strong>标签：</strong>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=AWS-CLI" target="_blank">AWS-CLI</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=IaC" target="_blank">IaC</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=Terraform" target="_blank">Terraform</a></p>缘起：为什么需要 Terraform 最近，我参与了一个 AWS Serverless 项目。业务需求本身并不复杂：几个 Lambda 函数、一个 S3 存储、一个 EventBridge 定时触发，再加上精细化的 IAM 权限控制。在部署这套服务的过程中，我先后尝试了三种方案，几乎踩遍了云基础设施管理中的经典巨坑：
AWS Console：一开始为了快，直接上控制台点鼠标。创建 S3 Bucket、手动上传 Lambda zip 包、配置 EventBridge 规则。问题是：项目要部署到 dev、staging、prod 三个环境，在控制台里点一遍要花半小时，三个环境配置完一个半小时。两个月后，当有人问“这个安全组是谁配的，为什么开了 443端口”时，没人说得清。
SAM：手动上传 zip 太繁琐，同事推荐了 SAM，通过一个 template.yaml 定义 Lambda 和权限，结合 sam build &amp;&amp; sam deploy 确实省心。但当面对 VPC、安全组、S3 高级配置、更精细的 IAM 策略时，SAM 显得力不从心。于是我变成了“混合打法”：SAM 管理 Lambda，其余资源还是在控制台管理。两个工具，两套流程，让人身心俱疲。
Terraform：运维同事终于看不下去了：“你这些资源应该用 Terraform 管理起来”。我一开始是抗拒的——一个 S3 Bucket 要写好几行代码，还要声明 Provider、定义变量，控制台里点几下搞定的事，为什么要大费周章写代码？
但是，很快一次意外说服了我。某天，有人在控制台里偷偷修改了路由表，却没有同步到代码中。第二天跑 terraform plan，配置漂移直接暴露。那一刻我才真正顿悟：Terraform 不仅仅是帮你创建资源的工具，更是帮你锁定“期望状态”的终极防线。
故事到这里，你以为我全面拥抱 Terraform 了？并没有。对于 Lambda 函数的代码部署，我最后还是选择用 GitHub Actions + AWS CLI。因为：Terraform 擅长管理静态的基础设施，而高频的代码迭代更适合放在专业的 CI/CD 流水线中。所以，我最终的工程实践是：Terraform 掌管资源拓扑，CI/CD 流水线负责代码交付。架构没有银弹，关键在于各司其职。
				<p><strong>您可能还对下面的文章感兴趣：</strong></p>
				<p><ol><li><a href="https://blogread.cn/it/article.php?id=3386" target="_blank">Twitter新员工的入职过程是怎样的？</a> [2011-03-02 23:05:57]</li></ol></p>]]></description>
		<content><![CDATA[在云原生开发中，基础设施管理常陷入两难困境：AWS控制台操作直观但难以复现且缺乏审计，SAM等专用工具对复杂资源支持有限。作者通过实际Serverless项目经历，对比了三种主流方案：控制台手动配置导致多环境部署耗时且配置来源不清；SAM在管理VPC、高级IAM策略时力不从心，形成“混合打法”增加复杂度；而Terraform通过基础设施即代码，实现了资源状态的版本化与声明式管理。

关键转折点在于Terraform的“配置漂移”检测能力。当有人通过控制台修改路由表后，`terraform plan`能立即发现实际状态与代码定义的偏差，从而有效锁定基础设施的“期望状态”，这是手动操作无法实现的可靠性保障。实践中，作者最终采用分层架构：Terraform负责核心云资源（如VPC、S3、IAM策略）的拓扑定义与状态管理，确保基础设施的确定性；Lambda等应用代码的频繁迭代则通过GitHub Actions与AWS CLI在CI/CD流水线中处理。这种组合既发挥了Terraform在基础设施状态管理上的优势，又兼顾了应用部署的敏捷性，体现了工具选型中“各司其职”的实用主义思路。]]></content>
	</item>
	<item>
		<title>对 tail -f 使用管道</title>
		<link>https://blogread.cn/it/article.php?id=8580</link>
		<author>Frytea</author>
		<pubDate>2026-06-03 09:03:24</pubDate>
		<category domain="https://blogread.cn/it/category.php?id=18">DevOps</category>
		<guid>https://blogread.cn/it/article.php?id=8580</guid>
		<comments>https://blogread.cn/it/article.php?id=8580#comment</comments>
		<description><![CDATA[<p><strong>标签：</strong>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=grep" target="_blank">grep</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=sed" target="_blank">sed</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=tail" target="_blank">tail</a>&nbsp;&nbsp;<a href="https://blogread.cn/it/tags.php?tag=%E7%AE%A1%E9%81%93" target="_blank">管道</a></p><blockquote>
<p>来源： <a href="https://harttle.land/2020/06/06/tail-f-pipe.html">对 tail -f 使用管道</a></p></blockquote>
<p>最近发现 <code>tail -f</code> 时管道后面的程序都会被卡住，才发现 grep，sed，awk 不直接输出到 TTY 时都是带缓冲的。平时跟在 <code>cat</code> 后使用没问题是因为输入管道关闭触发了 flush。本文详细解释其中的坑，以及怎么让 sed, awk, grep 立即 flush。</p>
				<p><strong>您可能还对下面的文章感兴趣：</strong></p>
				<p><ol><li><a href="https://blogread.cn/it/article.php?id=4695" target="_blank">大文件重定向和管道的效率对比</a> [2011-12-20 23:59:22]</li><li><a href="https://blogread.cn/it/article.php?id=3994" target="_blank">xargs 用法点滴</a> [2011-07-14 23:55:10]</li></ol></p>]]></description>
		<content><![CDATA[在使用 `tail -f` 监控日志文件时，若将输出通过管道传递给 `grep`、`sed` 或 `awk` 等工具，经常会遇到管道程序被卡住、无输出的情况。其根本原因在于这些文本处理工具默认采用了缓冲区机制。当它们判断输出目标不是交互式终端（TTY）时，会将数据暂存在缓冲区中，而非立即输出，这就导致了监控流被阻塞的假象。通常情况下，通过管道连接 `cat` 命令时不会遇到此问题，这是因为输入管道被关闭时，会触发缓冲区的刷新（flush）。要解决此问题，核心思路是需要让 `sed`、`awk` 等工具在执行时禁用缓冲或强制立即刷新输出。常见的方法包括为相应命令添加特定选项（例如 `awk` 的 `-W interactive` 或 `sed` 的 `-u` 选项），或者利用其他工具（如 `unbuffer` 或管道 `cat`）来强制输出为无缓冲的流，从而实现 `tail -f` 后内容的实时传递与处理。]]></content>
	</item>
</channel>
</rss>