<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>毅白の博客</title><description>记录折腾、技术与成长</description><link>https://blog.yib.lol/</link><language>zh-CN</language><item><title>从零到一：小米手环 9 (Vela OS) 快应用开发避坑与优化实战总结</title><link>https://blog.yib.lol/posts/%E5%B0%8F%E7%B1%B3%E6%89%8B%E7%8E%AF9_velaos_%E5%BF%AB%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E9%81%BF%E5%9D%91%E4%B8%8E%E4%BC%98%E5%8C%96%E5%AE%9E%E6%88%98%E6%80%BB%E7%BB%93/</link><guid isPermaLink="true">https://blog.yib.lol/posts/%E5%B0%8F%E7%B1%B3%E6%89%8B%E7%8E%AF9_velaos_%E5%BF%AB%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E9%81%BF%E5%9D%91%E4%B8%8E%E4%BC%98%E5%8C%96%E5%AE%9E%E6%88%98%E6%80%BB%E7%BB%93/</guid><description>在智能穿戴设备日益普及的今天，为小米手环 9 开发快应用面临硬件极度受限（JerryScript 引擎）与胶囊椭圆屏适配的挑战。本文总结了开发实战中的核心避坑指南与优化方案。</description><pubDate>Thu, 02 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在智能穿戴设备日益普及的今天，为手环等超轻量级可穿戴设备开发应用成为了一项有趣的挑战。最近，我为 &lt;strong&gt;小米手环 9&lt;/strong&gt;（搭载 Vela OS，使用快应用 QuickApp 框架）开发和重构了两个数学/物理计算器应用（「初中物理计算器」与「云学计算器」）。&lt;/p&gt;
&lt;p&gt;手环开发看似与传统的移动端前端开发类似（都是 HTML/CSS/JS），但由于其&lt;strong&gt;极度苛刻的硬件资源限制（JerryScript 引擎）&lt;strong&gt;以及&lt;/strong&gt;特殊的椭圆胶囊屏形态&lt;/strong&gt;，实际开发中隐藏着无数的“深坑”。&lt;/p&gt;
&lt;p&gt;本文将倾囊相授我在开发过程中的核心避坑指南、性能优化方案以及 UI 适配经验。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;🛠️ 一、 穿戴设备的“戴着镣铐跳舞”：硬件与编译约束&lt;/h2&gt;
&lt;p&gt;小米手环 9 的底层快应用 environment 运行在 &lt;strong&gt;JerryScript&lt;/strong&gt; 引擎上。这与我们熟知的 V8 引擎有着天壤之别，它的资源限制可以用“苛刻”来形容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;内存极小&lt;/strong&gt;：JerryScript 引擎的堆内存往往只有几百 KB。未压缩混淆的 JS 代码如果在解析阶段体积过大，会直接触发 &lt;strong&gt;OOM（Out of Memory）&lt;/strong&gt; 导致手环系统闪退或重启。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RPK 包体积限制&lt;/strong&gt;：虽然官方上限更大，但在实际开发中，&lt;strong&gt;RPK 包编译压缩后的大小建议严格控制在 300KB 以下&lt;/strong&gt;，越小加载越快、运行越安全。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;⚠️ 避坑 1：编译报错 &lt;code&gt;PseudoClassSelector unsupport&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;快应用的 CSS 编译器对伪类选择器的支持非常有限。如果你在 CSS 中写了类似于：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.btn:active {
  background-color: #333;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;编译链会直接抛出 &lt;code&gt;Selector type unsupport PseudoClassSelector, name: active&lt;/code&gt; 的报错并导致构建中断。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;解决方案&lt;/strong&gt;：剔除所有不被支持的 &lt;code&gt;:active&lt;/code&gt; 伪类样式。如果需要点击态反馈，应该依靠快应用组件的 &lt;code&gt;active&lt;/code&gt; 属性或者在 JS 中动态绑定 Class，或者使用系统自带的震动反馈（&lt;code&gt;system.vibrator&lt;/code&gt;）来替代视觉点击态。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;🛑 二、 避坑指南：手环真机“点进去啥都没有”与黑屏卡死&lt;/h2&gt;
&lt;p&gt;在模拟器上运行良好的代码，侧载到真机上经常会遇到“进入页面一片空白”或者“直接卡死黑屏”的现象。这主要是由于以下两个原因：&lt;/p&gt;
&lt;h3&gt;1. 致命的 &lt;code&gt;&amp;lt;list&amp;gt;&lt;/code&gt; 组件与 &lt;code&gt;&amp;lt;block&amp;gt;&lt;/code&gt; 条件渲染冲突&lt;/h3&gt;
&lt;p&gt;在很多前端框架中，我们习惯用 &lt;code&gt;&amp;lt;list&amp;gt;&lt;/code&gt; 结合条件渲染标签 &lt;code&gt;&amp;lt;block&amp;gt;&lt;/code&gt; 来动态展示组件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- ❌ 坏代码：会导致真机列表完全空白 --&amp;gt;
&amp;lt;list&amp;gt;
  &amp;lt;block if=&quot;{{currentFormula === 1}}&quot;&amp;gt;
    &amp;lt;list-item type=&quot;input&quot;&amp;gt;...&amp;lt;/list-item&amp;gt;
  &amp;lt;/block&amp;gt;
&amp;lt;/list&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;原因分析&lt;/strong&gt;：Vela OS 的 &lt;code&gt;&amp;lt;list&amp;gt;&lt;/code&gt; 属于&lt;strong&gt;惰性按需渲染组件&lt;/strong&gt;。其内部只允许 &lt;code&gt;&amp;lt;list-item&amp;gt;&lt;/code&gt; 作为直系子元素。如果将其包在 &lt;code&gt;&amp;lt;block&amp;gt;&lt;/code&gt; 中，列表渲染引擎会在高度计算和节点挂载时发生严重错乱，导致列表项渲染为 0，页面呈现一片死黑/空白。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;黄金法则&lt;/strong&gt;：在手环快应用开发中，&lt;strong&gt;尽量放弃使用 &lt;code&gt;&amp;lt;list&amp;gt;&lt;/code&gt; 布局，全面改用 &lt;code&gt;&amp;lt;scroll scroll-y=&quot;true&quot;&amp;gt;&lt;/code&gt; 滚动容器 + 普通 &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; 容器进行排版&lt;/strong&gt;。&lt;code&gt;&amp;lt;scroll&amp;gt;&lt;/code&gt; 属于静态流式布局，渲染绝对稳定，而且支持顺滑的上下滑动，没有任何数据懒加载的内存副作用。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. ES6 模板字符串（反引号）导致语法解析崩溃&lt;/h3&gt;
&lt;p&gt;我们习惯在 JS 中写这种优雅的模板字符串：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// ❌ 坏代码：会导致 JerryScript 解析失败，脚本静默挂起（页面白屏）
const substitution = `${mSI}kg × ${g}N/kg`;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;原因分析&lt;/strong&gt;：手环的 JerryScript 引擎对 ES6 的反引号（&lt;code&gt;）以及 &lt;/code&gt;${}` 插值的支持存在缺陷。当它在初始化阶段遇到反引号时，会静默抛出解析错误，导致页面关联 of JS 脚本完全不执行。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;解决方案&lt;/strong&gt;：在手环项目中，&lt;strong&gt;永远使用传统的 ES5 字符串拼接（&lt;code&gt;+&lt;/code&gt; 运算符）&lt;/strong&gt;：&lt;pre&gt;&lt;code&gt;const substitution = mSI + &quot;kg × &quot; + g + &quot;N/kg&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;⚡ 三、 体积与内存的极致优化：第三方轮子的裁减&lt;/h2&gt;
&lt;p&gt;为了提升输入体验，我引入了一个非常优秀的第三方全键盘输入法轮子（&lt;code&gt;Vela_input_method&lt;/code&gt;），但遇到到了严重的体积问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;引入后，RPK 包大小直接从 &lt;strong&gt;70KB 暴涨到 614KB&lt;/strong&gt;！&lt;/li&gt;
&lt;li&gt;究其原因，是输入法自带了用于拼音匹配的 &lt;code&gt;dic.js&lt;/code&gt;（中文词库）和日文罗马字匹配的 &lt;code&gt;dic_jp.js&lt;/code&gt;，大小达数百 KB。这些字典在手环启动加载时，会直接撑满 JerryScript 堆栈引起 OOM 崩溃。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;💡 核心优化方案（按需裁剪）&lt;/h3&gt;
&lt;p&gt;由于我们的应用是“计算器”，用户在输入框中&lt;strong&gt;只需要输入数字、小数点和基本运算符，根本不需要中文和日语汉字联想&lt;/strong&gt;。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;重写查词逻辑&lt;/strong&gt;：修改输入法的 &lt;code&gt;dicUtil.js&lt;/code&gt;，将其中的查词函数直接 mock 掉，使其直接返回空数组，断开对大字典文件的依赖。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;彻底删除垃圾文件&lt;/strong&gt;：直接删掉 &lt;code&gt;dic.js&lt;/code&gt; 和 &lt;code&gt;dic_jp.js&lt;/code&gt; 两个大文件。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;成果&lt;/strong&gt;：包体积瞬间从 &lt;strong&gt;614 KB 锐减至 241 KB&lt;/strong&gt;，完全退回到安全线以内，运行极其顺畅，彻底消除了 OOM 隐患。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;📱 四、 胶囊屏（椭圆屏）的 UX 视觉与触控适配&lt;/h2&gt;
&lt;p&gt;小米手环 9 采用的是 192×490px 的胶囊形屏幕，这种屏幕在顶部和底部具有非常明显的圆角弧度遮挡。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;┌──────────────┐
│  ❌ 0-20px   │  ← 顶部椭圆边缘（无法显示完整字，触控盲区）
├──────────────┤
│              │
│  ✅ 20-470px │  ← 安全交互触控区（平坦，好点）
│              │
├──────────────┤
│  ❌ 470-490px│  ← 底部圆角遮挡区
└──────────────┘
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;为了给用户提供 premium（高级）的交互质感，我们遵循了以下适配规范：&lt;/p&gt;
&lt;h3&gt;1. 彻底解决“上下边缘遮挡”&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;顶部防碰&lt;/strong&gt;: 页面的 Header 部分统一设置 &lt;strong&gt;&lt;code&gt;margin-top: 32px;&lt;/code&gt;&lt;/strong&gt;，确保返回按钮和标题完全避开顶部 20px 的物理弧度截断区。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;底部弹跳&lt;/strong&gt;: 当输入法键盘弹起时，底部 Spacer 高度由 &lt;code&gt;200px&lt;/code&gt; 拓宽至 &lt;strong&gt;&lt;code&gt;280px&lt;/code&gt;&lt;/strong&gt;，这保证了用户可以把&lt;strong&gt;任意一个当前正在输入的输入框，轻松地滚动到屏幕正中央的“平坦区”进行打字&lt;/strong&gt;，绝对不会被下边缘遮挡。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;列表留白&lt;/strong&gt;: 滚动列表的最底端设置 &lt;strong&gt;&lt;code&gt;60px&lt;/code&gt; 的占位 Spacer&lt;/strong&gt;，使得最后一项内容能被推上去，不被下圆角切边。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 扩大交互热区（防盲操点错）&lt;/h3&gt;
&lt;p&gt;手环屏幕极小，如果按钮做得很精致，用户会点得非常痛苦。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;页面的&lt;strong&gt;返回按钮热区扩大为 &lt;code&gt;48×48px&lt;/code&gt;&lt;/strong&gt;，设置 &lt;code&gt;line-height&lt;/code&gt; 居中，极大方便了大拇指侧向返回。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;输入框与按钮的高度统一设为 &lt;code&gt;52px&lt;/code&gt;&lt;/strong&gt;（接近官方最舒适的 &lt;code&gt;55px&lt;/code&gt; 限制），宽度拉伸至 &lt;code&gt;180px&lt;/code&gt;（两侧仅留 6px 呼吸空置），最大化触控面积。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;字号适当放大&lt;/strong&gt;：主标题使用 &lt;code&gt;20px&lt;/code&gt;，输入文字使用 &lt;code&gt;16px&lt;/code&gt;，确保在手臂晃动时也能看清。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 右滑返回防止应用卡死&lt;/h3&gt;
&lt;p&gt;快应用如果不支持右滑返回，用户在某些特殊界面可能因为找不到返回键而卡死在应用内。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;做法：在每个页面的根 &lt;code&gt;div&lt;/code&gt; 上绑定 &lt;code&gt;@swipe=&quot;handleSwipe&quot;&lt;/code&gt; 事件，一旦检测到 &lt;code&gt;direction === &apos;right&apos;&lt;/code&gt;，立即触发 &lt;code&gt;router.back()&lt;/code&gt;，给用户最自然的原生体验。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;五、 进阶炫技：手环上的 Canvas 动态绘图&lt;/h2&gt;
&lt;p&gt;在重构「云学计算器」的函数图像模块（&lt;code&gt;pages/func&lt;/code&gt;）时，为了让应用显得非常高级，我利用了快应用的 &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; 画布组件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在手环上渲染出了一个 $10 \times 10$ 格的动态坐标轴网格。&lt;/li&gt;
&lt;li&gt;通过在特定区间内（如 $x \in [-5, 5]$）以 18 像素为 1单位进行高精度点采样，计算 $y = f(x)$ 的值，最后在画布上连接成线，绘制出了一条条平滑的&lt;strong&gt;二次函数、三次函数和三角函数几何曲线&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在 192px 宽的微型屏幕上看着函数曲线随着输入的改变而实时重绘，这种视觉震撼感是传统极简计算器完全无法比拟的。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;📝 结语&lt;/h2&gt;
&lt;p&gt;开发手环应用是一个“&lt;strong&gt;做减法&lt;/strong&gt;”的过程。它需要开发者：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;精准控制每一行 JS 的大小，避开 ES6 的语法陷阱。&lt;/li&gt;
&lt;li&gt;警惕 &lt;code&gt;&amp;lt;list&amp;gt;&lt;/code&gt; 布局在低端虚拟机上的解析缺陷，多使用 &lt;code&gt;&amp;lt;scroll&amp;gt;&lt;/code&gt; 自适应容器。&lt;/li&gt;
&lt;li&gt;充分考虑胶囊圆角屏的物理遮挡，把所有重要的交互区域保留在屏幕正中，并加宽加高交互热区。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;希望这篇实战总结能为准备涉足 Vela OS 快应用开发的开发者们提供一些有价值的参考，少走弯路！&lt;/p&gt;
</content:encoded></item><item><title>第一篇博客</title><link>https://blog.yib.lol/posts/%E7%AC%AC%E4%B8%80%E7%AF%87%E5%8D%9A%E5%AE%A2/</link><guid isPermaLink="true">https://blog.yib.lol/posts/%E7%AC%AC%E4%B8%80%E7%AF%87%E5%8D%9A%E5%AE%A2/</guid><description>第一篇博客</description><pubDate>Fri, 16 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;hr /&gt;
&lt;h2&gt;写在前面&lt;/h2&gt;
&lt;p&gt;这是我博客的第一篇文章。&lt;/p&gt;
&lt;p&gt;一直想搭一个属于自己的博客，把折腾过的东西、踩过的坑、学到的技术记录下来，于是有了这个站点。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;为什么要写博客？&lt;/h2&gt;
&lt;p&gt;对我来说，写博客主要有几个目的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;把零散的知识系统化&lt;/li&gt;
&lt;li&gt;记录折腾过程，避免重复踩坑&lt;/li&gt;
&lt;li&gt;给未来的自己留下些什么&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;有些东西当下觉得“记住了”，过一段时间就忘了，写下来反而更踏实。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;这个博客会写什么？&lt;/h2&gt;
&lt;p&gt;接下来这个博客主要会记录：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Web 技术学习笔记&lt;/li&gt;
&lt;li&gt;网站部署、优化、踩坑记录&lt;/li&gt;
&lt;li&gt;一些个人思考与阶段总结&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不追求更新频率，只希望每一篇对自己有用。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;结语&lt;/h2&gt;
&lt;p&gt;第一篇博客就先写到这里。&lt;/p&gt;
&lt;p&gt;如果你正在阅读这段文字，希望这里的内容也能对你有所帮助。&lt;/p&gt;
</content:encoded></item></channel></rss>