<?xml version="1.0" encoding="utf-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>Resmic's | BLOG</title><link>https://blog.resmic.cn/</link><description>个人博客</description><item><title>Jetpack Compose 动画系统深度实践：从入门到丝滑</title><link>https://blog.resmic.cn/post/395.html</link><description>&lt;p&gt;&lt;img src=&quot;https://blog.resmic.cn/zb_users/upload/2026/10/20261029080337179323221781586.jpg&quot; alt=&quot;封面&quot; style=&quot;width:100%;&quot;/&gt;&lt;/p&gt;&lt;h2&gt;一、为什么选择 Compose 动画系统？&lt;/h2&gt;&lt;p&gt;在传统 View 体系中，实现一个复杂动画往往需要 ObjectAnimator、ValueAnimator、TransitionManager 多套 API 组合使用，代码量大且难以维护。Jetpack Compose 通过统一的声明式动画 API，把&amp;quot;状态变化 → 动画过渡&amp;quot;这一过程抽象成简单的函数调用，极大降低了开发门槛。&lt;/p&gt;&lt;p&gt;Compose 动画系统的核心设计理念是：&lt;strong&gt;动画本质上是状态的插值过渡&lt;/strong&gt;。当某个状态值发生变化时，Compose 会自动在新旧值之间进行插值，驱动重组并产生平滑动画，而无需开发者手动管理动画的生命周期。&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;声明式：描述&amp;quot;目标状态&amp;quot;而不是&amp;quot;动画步骤&amp;quot;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;协程友好：基于 Kotlin 协程，天然支持挂起与取消&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;可组合：多个动画可自由嵌套与组合&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;高性能：默认跑在 RenderThread，不阻塞主线程&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;二、基础 API：animate*AsState 一行代码搞定过渡&lt;/h2&gt;&lt;p&gt;&lt;code&gt;animate*AsState&lt;/code&gt; 是最简单的动画 API，适合对单一值做平滑过渡。它返回一个 &lt;code&gt;State&amp;lt;T&amp;gt;&lt;/code&gt;，Compose 在状态改变时自动驱动动画。&lt;/p&gt;&lt;pre&gt;@Composable
fun&amp;nbsp;ExpandableCard(expanded:&amp;nbsp;Boolean)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;height&amp;nbsp;by&amp;nbsp;animateDpAsState(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;targetValue&amp;nbsp;=&amp;nbsp;if&amp;nbsp;(expanded)&amp;nbsp;240.dp&amp;nbsp;else&amp;nbsp;80.dp,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;animationSpec&amp;nbsp;=&amp;nbsp;spring(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dampingRatio&amp;nbsp;=&amp;nbsp;Spring.DampingRatioMediumBouncy,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stiffness&amp;nbsp;=&amp;nbsp;Spring.StiffnessLow
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;label&amp;nbsp;=&amp;nbsp;&amp;quot;cardHeight&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Card(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier&amp;nbsp;=&amp;nbsp;Modifier
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.fillMaxWidth()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.height(height)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;card&amp;nbsp;content
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;常用的 animate*AsState 变体包括：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;animateFloatAsState&lt;/code&gt;：透明度、旋转角度等 Float 值&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;animateDpAsState&lt;/code&gt;：尺寸、间距等 Dp 值&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;animateColorAsState&lt;/code&gt;：颜色渐变&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;animateOffsetAsState&lt;/code&gt;：位置偏移&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;animateIntAsState&lt;/code&gt;：整数计数动画&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;对于自定义数据类型，可以使用 &lt;code&gt;animateValueAsState&lt;/code&gt; 并提供自定义的 &lt;code&gt;TwoWayConverter&lt;/code&gt;。&lt;/p&gt;&lt;h2&gt;三、AnimatedVisibility：优雅处理显示/隐藏动画&lt;/h2&gt;&lt;p&gt;&lt;code&gt;AnimatedVisibility&lt;/code&gt; 专门用于处理组件的进场/退场动画，支持自定义进入和退出的动画效果。&lt;/p&gt;&lt;pre&gt;@Composable
fun&amp;nbsp;NotificationBanner(visible:&amp;nbsp;Boolean,&amp;nbsp;message:&amp;nbsp;String)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;AnimatedVisibility(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;visible&amp;nbsp;=&amp;nbsp;visible,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enter&amp;nbsp;=&amp;nbsp;slideInVertically(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;initialOffsetY&amp;nbsp;=&amp;nbsp;{&amp;nbsp;-it&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;animationSpec&amp;nbsp;=&amp;nbsp;tween(300,&amp;nbsp;easing&amp;nbsp;=&amp;nbsp;EaseOutCubic)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;+&amp;nbsp;fadeIn(animationSpec&amp;nbsp;=&amp;nbsp;tween(300)),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;exit&amp;nbsp;=&amp;nbsp;slideOutVertically(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;targetOffsetY&amp;nbsp;=&amp;nbsp;{&amp;nbsp;-it&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;animationSpec&amp;nbsp;=&amp;nbsp;tween(200)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;+&amp;nbsp;fadeOut(animationSpec&amp;nbsp;=&amp;nbsp;tween(200))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Surface(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier&amp;nbsp;=&amp;nbsp;Modifier.fillMaxWidth(),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;color&amp;nbsp;=&amp;nbsp;MaterialTheme.colorScheme.primaryContainer,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tonalElevation&amp;nbsp;=&amp;nbsp;4.dp
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Text(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;text&amp;nbsp;=&amp;nbsp;message,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier&amp;nbsp;=&amp;nbsp;Modifier.padding(16.dp)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;进场动画（&lt;code&gt;EnterTransition&lt;/code&gt;）和退场动画（&lt;code&gt;ExitTransition&lt;/code&gt;）可以用 &lt;code&gt;+&lt;/code&gt; 操作符组合，常用组合：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;fadeIn() + scaleIn()&lt;/code&gt;：缩放淡入，适合弹窗&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;slideInHorizontally() + fadeIn()&lt;/code&gt;：侧滑淡入，适合侧边栏&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;expandVertically() + fadeIn()&lt;/code&gt;：展开淡入，适合折叠面板&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;在 &lt;code&gt;AnimatedVisibility&lt;/code&gt; 的子组件内部，可以使用 &lt;code&gt;animateEnterExit&lt;/code&gt; 修饰符为子组件单独定制动画，实现错落有致的交错动画效果。&lt;/p&gt;&lt;h2&gt;四、Transition API：多属性状态机动画&lt;/h2&gt;&lt;p&gt;当需要根据同一状态枚举同步控制多个属性的动画时，&lt;code&gt;Transition&lt;/code&gt; 是最佳选择。它把多个 animate* 调用统一管理，确保所有属性同步开始和结束。&lt;/p&gt;&lt;pre&gt;enum&amp;nbsp;class&amp;nbsp;ButtonState&amp;nbsp;{&amp;nbsp;Idle,&amp;nbsp;Pressed&amp;nbsp;}

@Composable
fun&amp;nbsp;AnimatedButton(onClick:&amp;nbsp;()&amp;nbsp;-&amp;gt;&amp;nbsp;Unit)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;buttonState&amp;nbsp;by&amp;nbsp;remember&amp;nbsp;{&amp;nbsp;mutableStateOf(ButtonState.Idle)&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;transition&amp;nbsp;=&amp;nbsp;updateTransition(targetState&amp;nbsp;=&amp;nbsp;buttonState,&amp;nbsp;label&amp;nbsp;=&amp;nbsp;&amp;quot;button&amp;quot;)

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;scale&amp;nbsp;by&amp;nbsp;transition.animateFloat(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;label&amp;nbsp;=&amp;nbsp;&amp;quot;scale&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;transitionSpec&amp;nbsp;=&amp;nbsp;{&amp;nbsp;spring(stiffness&amp;nbsp;=&amp;nbsp;Spring.StiffnessMedium)&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{&amp;nbsp;state&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;when&amp;nbsp;(state)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ButtonState.Idle&amp;nbsp;-&amp;gt;&amp;nbsp;1f
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ButtonState.Pressed&amp;nbsp;-&amp;gt;&amp;nbsp;0.92f
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;backgroundColor&amp;nbsp;by&amp;nbsp;transition.animateColor(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;label&amp;nbsp;=&amp;nbsp;&amp;quot;bgColor&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;transitionSpec&amp;nbsp;=&amp;nbsp;{&amp;nbsp;tween(150)&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{&amp;nbsp;state&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;when&amp;nbsp;(state)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ButtonState.Idle&amp;nbsp;-&amp;gt;&amp;nbsp;MaterialTheme.colorScheme.primary
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ButtonState.Pressed&amp;nbsp;-&amp;gt;&amp;nbsp;MaterialTheme.colorScheme.primaryContainer
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;elevation&amp;nbsp;by&amp;nbsp;transition.animateDp(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;label&amp;nbsp;=&amp;nbsp;&amp;quot;elevation&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;transitionSpec&amp;nbsp;=&amp;nbsp;{&amp;nbsp;tween(150)&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{&amp;nbsp;state&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;when&amp;nbsp;(state)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ButtonState.Idle&amp;nbsp;-&amp;gt;&amp;nbsp;6.dp
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ButtonState.Pressed&amp;nbsp;-&amp;gt;&amp;nbsp;1.dp
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Button(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onClick&amp;nbsp;=&amp;nbsp;onClick,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier&amp;nbsp;=&amp;nbsp;Modifier.scale(scale),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;colors&amp;nbsp;=&amp;nbsp;ButtonDefaults.buttonColors(containerColor&amp;nbsp;=&amp;nbsp;backgroundColor),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;elevation&amp;nbsp;=&amp;nbsp;ButtonDefaults.buttonElevation(defaultElevation&amp;nbsp;=&amp;nbsp;elevation),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;interactionSource&amp;nbsp;=&amp;nbsp;remember&amp;nbsp;{&amp;nbsp;MutableInteractionSource()&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.also&amp;nbsp;{&amp;nbsp;source&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LaunchedEffect(source)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;source.interactions.collect&amp;nbsp;{&amp;nbsp;interaction&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;buttonState&amp;nbsp;=&amp;nbsp;when&amp;nbsp;(interaction)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is&amp;nbsp;PressInteraction.Press&amp;nbsp;-&amp;gt;&amp;nbsp;ButtonState.Pressed
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;-&amp;gt;&amp;nbsp;ButtonState.Idle
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Text(&amp;quot;点击我&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;Transition 的优势在于 Android Studio 的动画预览工具可以直接调试多状态动画时间线，极大提升开发效率。&lt;/p&gt;&lt;h2&gt;五、AnimatedContent：内容切换动画&lt;/h2&gt;&lt;p&gt;&lt;code&gt;AnimatedContent&lt;/code&gt; 用于在不同内容之间做切换动画，比 AnimatedVisibility 更强大，支持自定义进出内容时的组合动画。&lt;/p&gt;&lt;pre&gt;@Composable
fun&amp;nbsp;CounterDisplay(count:&amp;nbsp;Int)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;AnimatedContent(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;targetState&amp;nbsp;=&amp;nbsp;count,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;transitionSpec&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;数字增大时向上滑入，减小时向下滑入
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(targetState&amp;nbsp;&amp;gt;&amp;nbsp;initialState)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;slideInVertically&amp;nbsp;{&amp;nbsp;height&amp;nbsp;-&amp;gt;&amp;nbsp;height&amp;nbsp;}&amp;nbsp;+&amp;nbsp;fadeIn()&amp;nbsp;togetherWith
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;slideOutVertically&amp;nbsp;{&amp;nbsp;height&amp;nbsp;-&amp;gt;&amp;nbsp;-height&amp;nbsp;}&amp;nbsp;+&amp;nbsp;fadeOut()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;else&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;slideInVertically&amp;nbsp;{&amp;nbsp;height&amp;nbsp;-&amp;gt;&amp;nbsp;-height&amp;nbsp;}&amp;nbsp;+&amp;nbsp;fadeIn()&amp;nbsp;togetherWith
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;slideOutVertically&amp;nbsp;{&amp;nbsp;height&amp;nbsp;-&amp;gt;&amp;nbsp;height&amp;nbsp;}&amp;nbsp;+&amp;nbsp;fadeOut()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}.using(SizeTransform(clip&amp;nbsp;=&amp;nbsp;false))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;label&amp;nbsp;=&amp;nbsp;&amp;quot;counter&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{&amp;nbsp;targetCount&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Text(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;text&amp;nbsp;=&amp;nbsp;&amp;quot;$targetCount&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;style&amp;nbsp;=&amp;nbsp;MaterialTheme.typography.displayLarge
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;实际项目中，&lt;code&gt;AnimatedContent&lt;/code&gt; 常用于：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;Loading → Content → Error 三态切换&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;导航页面切换&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Tab 内容切换&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;数字/计数器动态变化&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;六、手势驱动动画：Animatable 与协程&lt;/h2&gt;&lt;p&gt;对于需要手势精确控制的动画（如拖拽、滑动到删除），应使用底层的 &lt;code&gt;Animatable&lt;/code&gt; API，它提供了 &lt;code&gt;animateTo&lt;/code&gt;、&lt;code&gt;snapTo&lt;/code&gt;、&lt;code&gt;stop&lt;/code&gt; 等协程友好的控制方法。&lt;/p&gt;&lt;pre&gt;@Composable
fun&amp;nbsp;SwipeToDeleteItem(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onDelete:&amp;nbsp;()&amp;nbsp;-&amp;gt;&amp;nbsp;Unit,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;content:&amp;nbsp;@Composable&amp;nbsp;()&amp;nbsp;-&amp;gt;&amp;nbsp;Unit
)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;offsetX&amp;nbsp;=&amp;nbsp;remember&amp;nbsp;{&amp;nbsp;Animatable(0f)&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;coroutineScope&amp;nbsp;=&amp;nbsp;rememberCoroutineScope()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;density&amp;nbsp;=&amp;nbsp;LocalDensity.current
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;threshold&amp;nbsp;=&amp;nbsp;with(density)&amp;nbsp;{&amp;nbsp;120.dp.toPx()&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Box(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier&amp;nbsp;=&amp;nbsp;Modifier
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.fillMaxWidth()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.pointerInput(Unit)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;detectHorizontalDragGestures(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onDragEnd&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;coroutineScope.launch&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(offsetX.value&amp;nbsp;&amp;lt;&amp;nbsp;-threshold)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;超过阈值，执行删除动画
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;offsetX.animateTo(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;targetValue&amp;nbsp;=&amp;nbsp;-size.width.toFloat(),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;animationSpec&amp;nbsp;=&amp;nbsp;tween(300)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onDelete()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;else&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;回弹
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;offsetX.animateTo(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;targetValue&amp;nbsp;=&amp;nbsp;0f,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;animationSpec&amp;nbsp;=&amp;nbsp;spring(dampingRatio&amp;nbsp;=&amp;nbsp;Spring.DampingRatioMediumBouncy)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onHorizontalDrag&amp;nbsp;=&amp;nbsp;{&amp;nbsp;_,&amp;nbsp;dragAmount&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;coroutineScope.launch&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;newValue&amp;nbsp;=&amp;nbsp;(offsetX.value&amp;nbsp;+&amp;nbsp;dragAmount).coerceAtMost(0f)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;offsetX.snapTo(newValue)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;删除背景
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Box(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier&amp;nbsp;=&amp;nbsp;Modifier
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.fillMaxSize()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.background(MaterialTheme.colorScheme.errorContainer),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;contentAlignment&amp;nbsp;=&amp;nbsp;Alignment.CenterEnd
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Icon(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Icons.Default.Delete,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;contentDescription&amp;nbsp;=&amp;nbsp;&amp;quot;删除&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier&amp;nbsp;=&amp;nbsp;Modifier.padding(end&amp;nbsp;=&amp;nbsp;16.dp),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tint&amp;nbsp;=&amp;nbsp;MaterialTheme.colorScheme.onErrorContainer
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;内容层
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Box(modifier&amp;nbsp;=&amp;nbsp;Modifier.offset&amp;nbsp;{&amp;nbsp;IntOffset(offsetX.value.roundToInt(),&amp;nbsp;0)&amp;nbsp;})&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;content()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;h2&gt;七、性能优化与最佳实践&lt;/h2&gt;&lt;p&gt;Compose 动画性能优化的关键在于减少不必要的重组范围，以及尽量让动画跑在非 UI 线程。&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;使用 graphicsLayer 修饰符&lt;/strong&gt;：scale、alpha、rotation 等属性变化使用 &lt;code&gt;graphicsLayer&lt;/code&gt; 可以跳过重组，直接在 RenderThread 执行，性能最佳&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;避免在动画回调中分配对象&lt;/strong&gt;：animationSpec 的 lambda 会频繁调用，避免在里面创建新对象&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;合理使用 remember&lt;/strong&gt;：Animatable、AnimationState 等对象必须用 &lt;code&gt;remember&lt;/code&gt; 包裹，避免每次重组重新创建&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;shrinkToFit 优化列表动画&lt;/strong&gt;：在列表 item 的 AnimatedVisibility 中使用 &lt;code&gt;SizeTransform(clip = true)&lt;/code&gt; 避免超出边界的绘制&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;使用 Android Studio Compose Preview 动画调试&lt;/strong&gt;：在 Preview 中点击动画图标，可以可视化调试动画时间线&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;//&amp;nbsp;推荐：用&amp;nbsp;graphicsLayer&amp;nbsp;做&amp;nbsp;alpha/scale&amp;nbsp;动画
val&amp;nbsp;alpha&amp;nbsp;by&amp;nbsp;animateFloatAsState(if&amp;nbsp;(visible)&amp;nbsp;1f&amp;nbsp;else&amp;nbsp;0f,&amp;nbsp;label&amp;nbsp;=&amp;nbsp;&amp;quot;alpha&amp;quot;)
Box(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier&amp;nbsp;=&amp;nbsp;Modifier.graphicsLayer&amp;nbsp;{&amp;nbsp;this.alpha&amp;nbsp;=&amp;nbsp;alpha&amp;nbsp;}
)&amp;nbsp;{&amp;nbsp;/*&amp;nbsp;content&amp;nbsp;*/&amp;nbsp;}

//&amp;nbsp;不推荐：直接用&amp;nbsp;alpha&amp;nbsp;修饰符会触发重组
//&amp;nbsp;Box(modifier&amp;nbsp;=&amp;nbsp;Modifier.alpha(alpha))&amp;nbsp;{&amp;nbsp;/*&amp;nbsp;content&amp;nbsp;*/&amp;nbsp;}&lt;/pre&gt;&lt;p&gt;遵循这些最佳实践，能确保你的 Compose 动画在低端设备上同样流畅稳定，为用户带来一致的优质体验。&lt;/p&gt;</description><pubDate>Thu, 29 Oct 2026 08:07:08 +0800</pubDate></item><item><title>AI Agent 工程实践：从 ReAct 到多智能体协作的落地路径</title><link>https://blog.resmic.cn/post/394.html</link><description>&lt;p&gt;&lt;img src=&quot;https://blog.resmic.cn/zb_users/upload/2026/10/20261028080601179314596197869.jpg&quot; alt=&quot;封面&quot; style=&quot;width:100%;&quot;/&gt;&lt;/p&gt;&lt;h2&gt;一、为什么 AI Agent 落地这么难？&lt;/h2&gt;&lt;p&gt;自 ChatGPT 掀起 LLM 热潮以来，AI Agent 已成为工程界最炙手可热的方向。然而现实往往骨感——很多团队花了数周搭起来的 Agent，在 Demo 里表现亮眼，一到生产环境就开始翻车：无限循环、幻觉工具调用、上下文爆炸……这些问题并非偶然，而是 Agent 工程化中必须系统性面对的挑战。&lt;/p&gt;&lt;p&gt;本文不讲理论，只讲工程。我们将从主流 Agent 框架对比出发，深入多智能体架构设计，给出可直接落地的实践方案。&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;幻觉工具调用&lt;/strong&gt;：LLM 凭空构造不存在的参数或函数名&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;ReAct 死循环&lt;/strong&gt;：Thought-Action-Observation 无法收敛到终止条件&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;上下文窗口溢出&lt;/strong&gt;：长任务的历史消息累积超出模型限制&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;多 Agent 协调混乱&lt;/strong&gt;：子 Agent 输出格式不统一，Orchestrator 无法解析&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;二、主流 Agent 框架对比：ReAct、Plan-and-Execute 与 Reflexion&lt;/h2&gt;&lt;p&gt;在选型之前，先搞清楚三种主流范式各自的适用场景。&lt;/p&gt;&lt;h3&gt;2.1 ReAct（推理与行动交替）&lt;/h3&gt;&lt;p&gt;ReAct 是目前最广泛使用的 Agent 范式，核心思想是让模型在推理（Thought）和行动（Action）之间交替迭代，每次行动后观察结果（Observation），再决定下一步。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：单轮任务、工具数量少（小于10个）、任务步骤可预期。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;不适用&lt;/strong&gt;：需要长期规划、步骤数量不确定、需要回溯修正的复杂场景。&lt;/p&gt;&lt;h3&gt;2.2 Plan-and-Execute（先规划再执行）&lt;/h3&gt;&lt;p&gt;先让 Planner 生成完整的执行计划，再由 Executor 逐步执行，执行过程中可以根据结果动态调整计划。这种模式能够提前发现依赖冲突，避免执行到一半才发现方向错误。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：复杂多步骤任务、步骤间存在依赖关系、需要全局视角的项目。&lt;/p&gt;&lt;h3&gt;2.3 Reflexion（自反思迭代）&lt;/h3&gt;&lt;p&gt;在 ReAct 基础上增加自我评估和反思环节，执行失败后会分析原因并调整策略再次尝试。Reflexion 特别适合需要高准确率的场景，通过多次迭代逐步逼近正确答案。&lt;/p&gt;&lt;h2&gt;三、多智能体架构设计：Orchestrator-Worker 模式&lt;/h2&gt;&lt;p&gt;单个 Agent 能力有限，复杂任务需要多个专业化 Agent 协作。目前最成熟的架构是 Orchestrator-Worker 模式。&lt;/p&gt;&lt;p&gt;Orchestrator 负责：任务分解、子任务分发、结果聚合。Worker 负责：专注单一领域（搜索、代码生成、数据分析等）、返回结构化结果。&lt;/p&gt;&lt;p&gt;设计要点包括：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;接口标准化&lt;/strong&gt;：所有 Worker 遵循统一的输入输出 Schema&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;路由策略&lt;/strong&gt;：Orchestrator 根据任务类型智能选择 Worker&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;错误隔离&lt;/strong&gt;：单个 Worker 失败不影响整体任务流&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;并行执行&lt;/strong&gt;：无依赖的子任务可以并行调度，提升效率&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;四、工程化关键：可靠性与可观测性&lt;/h2&gt;&lt;p&gt;Agent 进入生产环境，可靠性和可观测性是两大核心要求。&lt;/p&gt;&lt;h3&gt;4.1 工具调用防御&lt;/h3&gt;&lt;p&gt;工具调用是 Agent 最容易出问题的环节，需要做好以下几点防护：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;参数校验&lt;/strong&gt;：使用 Pydantic 等工具对输入参数做强类型校验&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;超时控制&lt;/strong&gt;：每个工具调用设置合理的 timeout（建议 30 秒）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;错误处理&lt;/strong&gt;：捕获所有异常并返回结构化错误信息，而非直接抛出&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;重试机制&lt;/strong&gt;：对网络类工具实现幂等重试，避免副作用&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;4.2 上下文窗口管理&lt;/h3&gt;&lt;p&gt;长任务中消息历史会快速膨胀，超出模型上下文限制后会导致截断或报错。解决方案包括：保留系统消息和最近 N 轮对话、对历史消息做摘要压缩、将重要中间结果存入外部存储（Redis/向量库）。&lt;/p&gt;&lt;h3&gt;4.3 Tracing 与可观测性&lt;/h3&gt;&lt;p&gt;推荐使用 LangSmith 或 OpenTelemetry 对 Agent 的每一步进行追踪。关键指标包括：每次工具调用的延迟和成功率、Token 消耗趋势、任务完成率、异常类型分布。良好的可观测性是排查 Agent 问题的基础。&lt;/p&gt;&lt;h2&gt;五、RAG 增强 Agent：私有知识库接入&lt;/h2&gt;&lt;p&gt;纯 LLM 的 Agent 知识存在截止日期，结合 RAG（检索增强生成）可以让 Agent 实时访问最新的私有知识库。典型架构如下：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;文档处理&lt;/strong&gt;：将企业文档切块（Chunking）后向量化存入 Chroma、Milvus 等向量数据库&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;检索工具&lt;/strong&gt;：将向量相似度搜索封装成 Agent 工具，支持语义检索&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;混合检索&lt;/strong&gt;：结合稀疏检索（BM25）和稠密检索（语义），提升召回率&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;引用溯源&lt;/strong&gt;：在最终回答中附上来源文档，方便验证&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;六、生产环境部署检查清单&lt;/h2&gt;&lt;p&gt;在将 Agent 推向生产之前，逐项检查以下关键点：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;工具幂等性：相同参数多次调用结果一致，支持安全重试&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;最大迭代次数：ReAct 循环设置硬性上限（建议不超过 15 次）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;费用上限：单次任务的 Token 消耗设置预算上限&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;输出格式校验：最终输出符合下游系统预期的 Schema&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;人工审核钩子：高风险操作（发邮件、写数据库）前插入人工确认&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;降级策略：Agent 失败时能够优雅降级到规则引擎或人工处理&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;日志审计：所有 Agent 决策和工具调用留存完整日志&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;版本管理：Prompt 版本化，支持 A/B 测试新旧版本效果&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;安全沙箱：代码执行类工具运行在隔离环境，防止恶意注入&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;七、未来展望：Agentic Workflows 的演进方向&lt;/h2&gt;&lt;p&gt;AI Agent 工程化还在快速演进中，以下几个方向值得持续关注：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Agent Protocol 标准化&lt;/strong&gt;：MCP、A2A 协议正在推动 Agent 间通信标准化，未来 Agent 可以像微服务一样互相调用&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;长程记忆&lt;/strong&gt;：向量记忆加结构化记忆的混合方案，让 Agent 跨任务保持上下文&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;自主学习&lt;/strong&gt;：Agent 从历史轨迹中自动优化 Prompt 和工具调用策略&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;边缘部署&lt;/strong&gt;：小模型（7B 以下）驱动的轻量 Agent 在端侧运行，降低延迟和成本&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Agent 工程化是一场持久战。好的架构设计、严格的工程纪律、完善的可观测性，是 Agent 从实验室走向生产的必经之路。希望本文的实践经验能为你的 Agent 落地之旅提供参考。&lt;/p&gt;</description><pubDate>Wed, 28 Oct 2026 08:08:04 +0800</pubDate></item><item><title>Android Jetpack Compose 性能优化实战：7个核心技巧提升应用流畅度</title><link>https://blog.resmic.cn/post/393.html</link><description>&lt;p&gt;&lt;img src=&quot;https://blog.resmic.cn/zb_users/upload/2026/10/20261027080349179305942973568.jpg&quot; alt=&quot;封面&quot; style=&quot;width:100%;&quot;/&gt;&lt;/p&gt;&lt;h2&gt;一、Compose 重组机制：理解性能问题的根源&lt;/h2&gt;&lt;p&gt;Jetpack Compose 的核心工作原理是&lt;strong&gt;重组（Recomposition）&lt;/strong&gt;——当状态发生变化时，Compose 会自动重新执行相关 Composable 函数来更新 UI。这一机制赋予了 Compose 声明式编程的优雅性，但也成为性能问题的主要来源。&lt;/p&gt;&lt;p&gt;重组并不像传统 View 体系那样只更新&amp;quot;脏&amp;quot;节点，而是重新执行整个 Composable 函数。如果开发者对状态依赖关系处理不当，就会触发大量不必要的重组，导致 UI 卡顿甚至掉帧。&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;智能重组&lt;/strong&gt;：Compose 会尝试跳过参数未变化的 Composable，但前提是参数类型必须是&amp;quot;稳定的（Stable）&amp;quot;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;重组作用域&lt;/strong&gt;：只有读取了变化状态的最小 Composable 作用域才会被重组&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;结构相等性&lt;/strong&gt;：Compose 使用 equals() 判断参数是否变化，不稳定类型每次都会触发重组&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;//&amp;nbsp;❌&amp;nbsp;不推荐：整个&amp;nbsp;ParentComposable&amp;nbsp;会因&amp;nbsp;count&amp;nbsp;变化而重组
@Composable
fun&amp;nbsp;ParentComposable(viewModel:&amp;nbsp;MyViewModel)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;count&amp;nbsp;=&amp;nbsp;viewModel.count.collectAsState()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ChildComposable(count.value)&amp;nbsp;//&amp;nbsp;每次&amp;nbsp;count&amp;nbsp;变化，Child&amp;nbsp;都重组
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;HeavyComposable()&amp;nbsp;//&amp;nbsp;这个也会无辜被重组！
}

//&amp;nbsp;✅&amp;nbsp;推荐：将状态读取下沉到最小作用域
@Composable
fun&amp;nbsp;ParentComposable(viewModel:&amp;nbsp;MyViewModel)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CounterDisplay(countFlow&amp;nbsp;=&amp;nbsp;viewModel.count)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;HeavyComposable()&amp;nbsp;//&amp;nbsp;不受&amp;nbsp;count&amp;nbsp;影响
}

@Composable
fun&amp;nbsp;CounterDisplay(countFlow:&amp;nbsp;StateFlow&amp;lt;Int&amp;gt;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;count&amp;nbsp;=&amp;nbsp;countFlow.collectAsState()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Text(text&amp;nbsp;=&amp;nbsp;&amp;quot;Count:&amp;nbsp;${count.value}&amp;quot;)
}&lt;/pre&gt;&lt;h2&gt;二、remember 与 derivedStateOf 的正确使用姿势&lt;/h2&gt;&lt;p&gt;&lt;code&gt;remember&lt;/code&gt; 是 Compose 中最常用的缓存机制，用于在重组之间保留计算结果或对象引用。但错误使用 &lt;code&gt;remember&lt;/code&gt; 不仅达不到优化效果，还可能引入 Bug。&lt;/p&gt;&lt;p&gt;&lt;code&gt;derivedStateOf&lt;/code&gt; 则专门用于从一个或多个 State 派生出新的 State，它的核心价值在于&lt;strong&gt;减少不必要的重组触发&lt;/strong&gt;：只有派生值真正发生变化时，才会触发下游重组。&lt;/p&gt;&lt;pre&gt;//&amp;nbsp;❌&amp;nbsp;错误用法：每次重组都重新创建列表
@Composable
fun&amp;nbsp;UserList(users:&amp;nbsp;List&amp;lt;User&amp;gt;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;sortedUsers&amp;nbsp;=&amp;nbsp;users.sortedBy&amp;nbsp;{&amp;nbsp;it.name&amp;nbsp;}&amp;nbsp;//&amp;nbsp;每次重组都排序！
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LazyColumn&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(sortedUsers)&amp;nbsp;{&amp;nbsp;UserItem(it)&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

//&amp;nbsp;✅&amp;nbsp;正确：用&amp;nbsp;remember&amp;nbsp;缓存排序结果
@Composable
fun&amp;nbsp;UserList(users:&amp;nbsp;List&amp;lt;User&amp;gt;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;sortedUsers&amp;nbsp;=&amp;nbsp;remember(users)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;users.sortedBy&amp;nbsp;{&amp;nbsp;it.name&amp;nbsp;}&amp;nbsp;//&amp;nbsp;只在&amp;nbsp;users&amp;nbsp;变化时重新排序
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LazyColumn&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(sortedUsers)&amp;nbsp;{&amp;nbsp;UserItem(it)&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

//&amp;nbsp;✅&amp;nbsp;derivedStateOf&amp;nbsp;示例：滚动位置派生&amp;quot;显示回顶部按钮&amp;quot;状态
@Composable
fun&amp;nbsp;ScrollableContent()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;listState&amp;nbsp;=&amp;nbsp;rememberLazyListState()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;每次滚动都会改变&amp;nbsp;firstVisibleItemIndex，但按钮状态只在跨越阈值时才变
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;showScrollTop&amp;nbsp;by&amp;nbsp;remember&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;derivedStateOf&amp;nbsp;{&amp;nbsp;listState.firstVisibleItemIndex&amp;nbsp;&amp;gt;&amp;nbsp;5&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Box&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LazyColumn(state&amp;nbsp;=&amp;nbsp;listState)&amp;nbsp;{&amp;nbsp;/*&amp;nbsp;items&amp;nbsp;*/&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(showScrollTop)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FloatingActionButton(onClick&amp;nbsp;=&amp;nbsp;{&amp;nbsp;/*&amp;nbsp;scroll&amp;nbsp;to&amp;nbsp;top&amp;nbsp;*/&amp;nbsp;})&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Icon(Icons.Default.ArrowUpward,&amp;nbsp;contentDescription&amp;nbsp;=&amp;nbsp;null)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;h2&gt;三、LazyColumn / LazyRow 性能优化实战&lt;/h2&gt;&lt;p&gt;列表是 Android 应用中最常见的性能瓶颈。Compose 的 &lt;code&gt;LazyColumn&lt;/code&gt; 虽然比传统 RecyclerView 更易用，但如果使用不当，性能可能大打折扣。&lt;/p&gt;&lt;h3&gt;3.1 为列表项提供稳定的 key&lt;/h3&gt;&lt;p&gt;不提供 &lt;code&gt;key&lt;/code&gt; 时，Compose 默认按位置识别列表项，数据插入/删除会导致所有后续项重组。&lt;/p&gt;&lt;pre&gt;//&amp;nbsp;❌&amp;nbsp;没有&amp;nbsp;key：列表变化时全量重组
LazyColumn&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(messages)&amp;nbsp;{&amp;nbsp;message&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MessageItem(message)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

//&amp;nbsp;✅&amp;nbsp;提供稳定&amp;nbsp;key：只有变化的项才重组
LazyColumn&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(messages,&amp;nbsp;key&amp;nbsp;=&amp;nbsp;{&amp;nbsp;it.id&amp;nbsp;})&amp;nbsp;{&amp;nbsp;message&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MessageItem(message)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;h3&gt;3.2 避免在 item lambda 中进行复杂计算&lt;/h3&gt;&lt;pre&gt;//&amp;nbsp;❌&amp;nbsp;在&amp;nbsp;item&amp;nbsp;渲染时进行格式化（每次重组都执行）
LazyColumn&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(orders,&amp;nbsp;key&amp;nbsp;=&amp;nbsp;{&amp;nbsp;it.id&amp;nbsp;})&amp;nbsp;{&amp;nbsp;order&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;formattedDate&amp;nbsp;=&amp;nbsp;SimpleDateFormat(&amp;quot;yyyy-MM-dd&amp;quot;).format(order.date)&amp;nbsp;//&amp;nbsp;每次重组都创建对象
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OrderItem(order,&amp;nbsp;formattedDate)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

//&amp;nbsp;✅&amp;nbsp;预处理数据，或在&amp;nbsp;OrderItem&amp;nbsp;内部用&amp;nbsp;remember&amp;nbsp;缓存
@Composable
fun&amp;nbsp;OrderItem(order:&amp;nbsp;Order)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;formattedDate&amp;nbsp;=&amp;nbsp;remember(order.date)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SimpleDateFormat(&amp;quot;yyyy-MM-dd&amp;quot;,&amp;nbsp;Locale.getDefault()).format(order.date)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;...
}&lt;/pre&gt;&lt;h3&gt;3.3 contentType 优化不同类型列表项&lt;/h3&gt;&lt;pre&gt;LazyColumn&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items&amp;nbsp;=&amp;nbsp;feedItems,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key&amp;nbsp;=&amp;nbsp;{&amp;nbsp;it.id&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;contentType&amp;nbsp;=&amp;nbsp;{&amp;nbsp;item&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;when&amp;nbsp;(item)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is&amp;nbsp;FeedItem.Article&amp;nbsp;-&amp;gt;&amp;nbsp;&amp;quot;article&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is&amp;nbsp;FeedItem.Ad&amp;nbsp;-&amp;gt;&amp;nbsp;&amp;quot;ad&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is&amp;nbsp;FeedItem.Video&amp;nbsp;-&amp;gt;&amp;nbsp;&amp;quot;video&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{&amp;nbsp;item&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;when&amp;nbsp;(item)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is&amp;nbsp;FeedItem.Article&amp;nbsp;-&amp;gt;&amp;nbsp;ArticleCard(item)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is&amp;nbsp;FeedItem.Ad&amp;nbsp;-&amp;gt;&amp;nbsp;AdBanner(item)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is&amp;nbsp;FeedItem.Video&amp;nbsp;-&amp;gt;&amp;nbsp;VideoCard(item)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;h2&gt;四、Compose 稳定性标注：解决&amp;quot;不稳定类型&amp;quot;引发的重组&lt;/h2&gt;&lt;p&gt;Compose 编译器会自动分析类型的稳定性。对于不稳定的参数类型，即使值没有实际变化，Compose 也会保守地触发重组。常见的不稳定类型包括：普通数据类中含有 &lt;code&gt;List&lt;/code&gt;/&lt;code&gt;Map&lt;/code&gt; 字段、持有可变状态的类等。&lt;/p&gt;&lt;pre&gt;//&amp;nbsp;❌&amp;nbsp;不稳定：List&amp;nbsp;是不稳定类型，每次父组件重组都会触发
data&amp;nbsp;class&amp;nbsp;UserProfile(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;name:&amp;nbsp;String,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;tags:&amp;nbsp;List&amp;lt;String&amp;gt;&amp;nbsp;//&amp;nbsp;不稳定！
)

@Composable
fun&amp;nbsp;ProfileCard(profile:&amp;nbsp;UserProfile)&amp;nbsp;{&amp;nbsp;//&amp;nbsp;无法跳过重组
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;...
}

//&amp;nbsp;✅&amp;nbsp;方案1：使用&amp;nbsp;@Stable&amp;nbsp;或&amp;nbsp;@Immutable&amp;nbsp;标注
@Immutable
data&amp;nbsp;class&amp;nbsp;UserProfile(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;name:&amp;nbsp;String,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;tags:&amp;nbsp;List&amp;lt;String&amp;gt;
)

//&amp;nbsp;✅&amp;nbsp;方案2：使用&amp;nbsp;kotlinx.collections.immutable
implementation(&amp;quot;org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7&amp;quot;)

data&amp;nbsp;class&amp;nbsp;UserProfile(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;name:&amp;nbsp;String,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;tags:&amp;nbsp;ImmutableList&amp;lt;String&amp;gt;&amp;nbsp;//&amp;nbsp;稳定！
)

//&amp;nbsp;✅&amp;nbsp;方案3：配置&amp;nbsp;Compose&amp;nbsp;编译器稳定性配置文件（composeCompilerStabilityConfig）
//&amp;nbsp;在&amp;nbsp;stability_config.conf&amp;nbsp;中添加：
//&amp;nbsp;com.example.MyClass&lt;/pre&gt;&lt;p&gt;在 &lt;code&gt;build.gradle.kts&lt;/code&gt; 中启用稳定性配置：&lt;/p&gt;&lt;pre&gt;composeCompiler&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stabilityConfigurationFile&amp;nbsp;=&amp;nbsp;rootProject.layout.projectDirectory.file(&amp;quot;stability_config.conf&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;reportsDestination&amp;nbsp;=&amp;nbsp;layout.buildDirectory.dir(&amp;quot;compose_compiler&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;metricsDestination&amp;nbsp;=&amp;nbsp;layout.buildDirectory.dir(&amp;quot;compose_compiler&amp;quot;)
}&lt;/pre&gt;&lt;h2&gt;五、Baseline Profile：应用启动与首帧性能的飞跃&lt;/h2&gt;&lt;p&gt;Baseline Profile 是 Android 提供的一种性能优化机制，通过预先编译关键代码路径，大幅减少应用冷启动时间和首帧渲染延迟。对于 Compose 应用尤其重要，因为 Compose 框架本身就是一个需要 JIT 编译的大型库。&lt;/p&gt;&lt;pre&gt;//&amp;nbsp;1.&amp;nbsp;添加依赖
//&amp;nbsp;build.gradle.kts&amp;nbsp;(app)
dependencies&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;implementation(&amp;quot;androidx.profileinstaller:profileinstaller:1.3.1&amp;quot;)
}

//&amp;nbsp;2.&amp;nbsp;创建&amp;nbsp;Baseline&amp;nbsp;Profile&amp;nbsp;生成模块
//&amp;nbsp;macrobenchmark/build.gradle.kts
plugins&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;id(&amp;quot;com.android.test&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;id(&amp;quot;androidx.baselineprofile&amp;quot;)
}

android&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;targetProjectPath&amp;nbsp;=&amp;nbsp;&amp;quot;:app&amp;quot;
}

dependencies&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;implementation(&amp;quot;androidx.test.ext:junit:1.1.5&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;implementation(&amp;quot;androidx.test.espresso:espresso-core:3.5.1&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;implementation(&amp;quot;androidx.test.uiautomator:uiautomator:2.2.0&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;implementation(&amp;quot;androidx.benchmark:benchmark-macro-junit4:1.2.0&amp;quot;)
}

//&amp;nbsp;3.&amp;nbsp;编写&amp;nbsp;Profile&amp;nbsp;生成规则
@OptIn(ExperimentalBaselineProfilesApi::class)
class&amp;nbsp;BaselineProfileGenerator&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@get:Rule
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;rule&amp;nbsp;=&amp;nbsp;BaselineProfileRule()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@Test
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fun&amp;nbsp;generate()&amp;nbsp;=&amp;nbsp;rule.collect(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;packageName&amp;nbsp;=&amp;nbsp;&amp;quot;com.example.myapp&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pressHome()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;startActivityAndWait()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;覆盖关键用户路径
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;device.findObject(By.text(&amp;quot;Products&amp;quot;)).click()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;device.waitForIdle()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;生成 Baseline Profile 后，将 &lt;code&gt;baseline-prof.txt&lt;/code&gt; 放入 &lt;code&gt;src/main/&lt;/code&gt; 目录，发布时 Google Play 会自动进行云端 AOT 编译。实测数据显示，配置 Baseline Profile 后：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;冷启动时间平均减少 &lt;strong&gt;30%~40%&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;首帧渲染延迟降低约 &lt;strong&gt;20%&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;滚动流畅度（jank rate）降低约 &lt;strong&gt;15%&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;六、使用 Compose 性能工具诊断问题&lt;/h2&gt;&lt;p&gt;工欲善其事，必先利其器。Android Studio 提供了多种工具帮助开发者诊断 Compose 性能问题。&lt;/p&gt;&lt;h3&gt;6.1 Layout Inspector - Recomposition 高亮&lt;/h3&gt;&lt;p&gt;在 Android Studio 的 Layout Inspector 中，开启&amp;quot;Show Recomposition Counts&amp;quot;选项，可以实时看到每个 Composable 的重组次数，快速定位重组热点。&lt;/p&gt;&lt;h3&gt;6.2 Compose 编译器报告&lt;/h3&gt;&lt;pre&gt;//&amp;nbsp;build.gradle.kts
composeCompiler&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;reportsDestination&amp;nbsp;=&amp;nbsp;layout.buildDirectory.dir(&amp;quot;compose_compiler&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;metricsDestination&amp;nbsp;=&amp;nbsp;layout.buildDirectory.dir(&amp;quot;compose_compiler&amp;quot;)
}&lt;/pre&gt;&lt;p&gt;运行 &lt;code&gt;./gradlew assembleRelease&lt;/code&gt; 后，在 &lt;code&gt;build/compose_compiler/&lt;/code&gt; 目录下会生成详细报告，包含每个 Composable 的稳定性分析和可跳过性（skippable）判断。&lt;/p&gt;&lt;h3&gt;6.3 Systrace / Perfetto 分析帧耗时&lt;/h3&gt;&lt;pre&gt;//&amp;nbsp;在代码中添加自定义&amp;nbsp;trace&amp;nbsp;段
import&amp;nbsp;androidx.tracing.trace

@Composable
fun&amp;nbsp;HeavyList(items:&amp;nbsp;List&amp;lt;Item&amp;gt;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;trace(&amp;quot;HeavyList-composition&amp;quot;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LazyColumn&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(items,&amp;nbsp;key&amp;nbsp;=&amp;nbsp;{&amp;nbsp;it.id&amp;nbsp;})&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;trace(&amp;quot;ItemCard-${it.id}&amp;quot;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ItemCard(it)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;h2&gt;七、总结：Compose 性能优化清单&lt;/h2&gt;&lt;p&gt;经过以上六个维度的深入探讨，我们可以总结出一份 Compose 性能优化实践清单：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;✅ &lt;strong&gt;状态读取下沉&lt;/strong&gt;：将状态读取尽可能推迟到最小的 Composable 作用域&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;✅ &lt;strong&gt;合理使用 remember&lt;/strong&gt;：为昂贵计算添加 &lt;code&gt;remember(key)&lt;/code&gt;，避免重复执行&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;✅ &lt;strong&gt;derivedStateOf 派生状态&lt;/strong&gt;：高频变化的状态派生低频变化的状态时必用&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;✅ &lt;strong&gt;LazyList 添加 key&lt;/strong&gt;：列表项必须提供稳定唯一的 key&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;✅ &lt;strong&gt;稳定性标注&lt;/strong&gt;：对含不稳定字段的数据类使用 &lt;code&gt;@Immutable&lt;/code&gt; 或切换 immutable 集合&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;✅ &lt;strong&gt;配置 Baseline Profile&lt;/strong&gt;：上线前必做，效果立竿见影&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;✅ &lt;strong&gt;编译器报告监控&lt;/strong&gt;：CI 集成稳定性报告，防止性能退化&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;✅ &lt;strong&gt;避免在 Composable 中创建 Lambda&lt;/strong&gt;：用 &lt;code&gt;remember { {} }&lt;/code&gt; 缓存 Lambda 引用&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Compose 性能优化是一个系统性工程，需要开发者深入理解其重组机制和编译器行为。建议在项目早期就建立性能基准，并将编译器稳定性报告纳入 CI/CD 流程，防患于未然。&lt;/p&gt;</description><pubDate>Tue, 27 Oct 2026 08:04:12 +0800</pubDate></item><item><title>PHP 8.3 新特性实战：只读类、类型常量与 json_validate 深度解析</title><link>https://blog.resmic.cn/post/392.html</link><description>&lt;p&gt;&lt;img src=&quot;https://blog.resmic.cn/zb_users/upload/2026/10/20261023080556179271395653984.jpg&quot; alt=&quot;封面&quot; style=&quot;width:100%;&quot;&gt;&lt;/p&gt;

&lt;h2&gt;一、PHP 8.3 新特性概览&lt;/h2&gt;
&lt;p&gt;PHP 8.3 于 2023 年 11 月正式发布，延续了 PHP 8.x 系列的快速演进势头。相比 8.2，本次更新更加聚焦于类型安全、代码可读性和运行时性能。以下是本次更新中最值得关注的几项特性：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;只读类（Readonly Classes）&lt;/strong&gt;：一次声明，全局不可变&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;类常量类型声明&lt;/strong&gt;：支持为常量指定类型约束&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;json_validate() 函数&lt;/strong&gt;：无需解码即可校验 JSON 合法性&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;新增 #[\Override] 属性&lt;/strong&gt;：防止子类方法命名错误&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;深克隆与 readonly 属性&lt;/strong&gt;：通过 clone 重置只读属性&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;二、只读类（Readonly Classes）深度解析&lt;/h2&gt;
&lt;p&gt;PHP 8.2 引入了只读属性（&lt;code&gt;readonly&lt;/code&gt; property），PHP 8.3 进一步完善了只读类的能力，允许开发者在 &lt;code&gt;clone&lt;/code&gt; 表达式中修改只读属性，实现&quot;写时复制&quot;模式。&lt;/p&gt;
&lt;p&gt;下面是一个典型的值对象（Value Object）示例：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php

readonly class Money {
    public function __construct(
        public int $amount,
        public string $currency
    ) {}

    // PHP 8.3：clone 时可修改 readonly 属性
    public function withAmount(int $newAmount): static {
        return clone($this, amount: $newAmount);
    }

    public function add(Money $other): static {
        if ($this-&gt;currency !== $other-&gt;currency) {
            throw new \InvalidArgumentException('Currency mismatch');
        }
        return $this-&gt;withAmount($this-&gt;amount + $other-&gt;amount);
    }
}

$price = new Money(1000, 'CNY');
$tax   = new Money(80,   'CNY');
$total = $price-&gt;add($tax);

echo $total-&gt;amount;   // 1080
echo $total-&gt;currency; // CNY
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;只读类天然是线程安全的，非常适合用于 DTO、配置对象和领域值对象等场景，彻底告别&quot;防御性克隆&quot;的样板代码。&lt;/p&gt;

&lt;h2&gt;三、类常量类型声明&lt;/h2&gt;
&lt;p&gt;在 PHP 8.3 之前，类常量没有类型约束，运行时赋值错误只能靠人工 review 发现。PHP 8.3 允许为常量指定类型：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php

interface HasVersion {
    const string VERSION;
}

class App implements HasVersion {
    const string VERSION = '1.0.0';
    const int    MAX_RETRY = 3;
    const array  SUPPORTED_LOCALES = ['zh_CN', 'en_US', 'ja_JP'];
}

// 以下代码在 PHP 8.3 中会报错（类型不匹配）
class BadApp implements HasVersion {
    const string VERSION = 123; // Fatal error: Cannot use int as string constant
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;类型声明支持所有标量类型（&lt;code&gt;int&lt;/code&gt;、&lt;code&gt;float&lt;/code&gt;、&lt;code&gt;string&lt;/code&gt;、&lt;code&gt;bool&lt;/code&gt;）、&lt;code&gt;array&lt;/code&gt;、&lt;code&gt;null&lt;/code&gt; 以及枚举类型，大幅提升了接口契约的可靠性。&lt;/p&gt;

&lt;h2&gt;四、json_validate() 与 #[\Override] 属性&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;json_validate()&lt;/strong&gt; 是一个简单却实用的新函数。在此之前，验证 JSON 字符串合法性需要完整执行 &lt;code&gt;json_decode()&lt;/code&gt; 并检查 &lt;code&gt;json_last_error()&lt;/code&gt;，浪费了反序列化的开销。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php

$raw = '{&quot;name&quot;:&quot;Alice&quot;,&quot;age&quot;:30}';

// 旧方式：解码再判断
json_decode($raw);
$valid_old = (json_last_error() === JSON_ERROR_NONE);

// PHP 8.3 新方式：仅校验不解码
$valid_new = json_validate($raw);

// 性能对比（大 JSON 场景）
$bigJson = json_encode(range(1, 10000));
$start = microtime(true);
for ($i = 0; $i &lt; 1000; $i++) json_validate($bigJson);
echo 'json_validate: ' . round((microtime(true) - $start) * 1000, 2) . 'ms';
// 约为 json_decode 方式的 1/3 耗时
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;#[\Override]&lt;/strong&gt; 属性用于标记子类方法意图覆盖父类方法，如果父类中不存在该方法，PHP 将抛出编译错误，有效防止因拼写错误导致的隐藏 Bug：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php

class Base {
    public function process(): void { /* ... */ }
}

class Child extends Base {
    #[\Override]
    public function process(): void { /* 正确覆盖 */ }

    #[\Override]
    public function procsss(): void { /* Fatal: procsss() 在父类中不存在 */ }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;五、升级建议与最佳实践&lt;/h2&gt;
&lt;p&gt;在将现有项目升级到 PHP 8.3 之前，建议按以下步骤操作：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;运行 php-deprecation-detector&lt;/strong&gt;：扫描代码中的废弃特性调用&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;更新 Composer 依赖&lt;/strong&gt;：确保所有第三方包声明了对 PHP 8.3 的兼容&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;开启 strict_types&lt;/strong&gt;：&lt;code&gt;declare(strict_types=1);&lt;/code&gt; 与新类型特性配合效果最佳&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;逐步迁移 DTO 为 readonly class&lt;/strong&gt;：从新增代码开始，不必一次重构全部&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;CI 中加入 PHP Stan / Psalm&lt;/strong&gt;：静态分析工具对 8.3 新特性有完整支持&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;PHP 8.3 是一个稳健的生产就绪版本，新特性在不引入破坏性变更的前提下显著提升了代码质量上限。无论是新项目选型还是旧项目升级，都值得优先考虑。&lt;/p&gt;
</description><pubDate>Fri, 23 Oct 2026 08:06:13 +0800</pubDate></item><item><title>Android Jetpack Compose 性能优化实战：7大技巧打造丝滑UI</title><link>https://blog.resmic.cn/post/391.html</link><description>&lt;p&gt;&lt;img src=&quot;https://blog.resmic.cn/zb_users/upload/2026/10/20261022080323179262740396631.jpg&quot; alt=&quot;封面&quot; style=&quot;width:100%;&quot;/&gt;&lt;/p&gt;&lt;h2&gt;一、理解 Compose 重组机制：性能优化的基础&lt;/h2&gt;&lt;p&gt;Jetpack Compose 的核心工作原理是&lt;strong&gt;重组（Recomposition）&lt;/strong&gt;。每当状态发生变化时，Compose 会重新执行依赖该状态的可组合函数。理解重组的触发时机和范围，是性能优化的第一步。&lt;/p&gt;&lt;p&gt;Compose 采用智能重组策略：只有直接读取了变化状态的可组合函数才会重组，其子树也会选择性地跳过。但如果你的代码编写不当，依然会引发大范围不必要的重组。&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;稳定类型（Stable types）&lt;/strong&gt;：Int、String、Boolean 等基础类型天然稳定，Compose 可以跳过重组&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;不稳定类型&lt;/strong&gt;：普通 data class、List、Map 默认被视为不稳定，每次都会触发重组&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;@Stable / @Immutable 注解&lt;/strong&gt;：对自定义类标注，明确告诉 Compose 该类型是稳定的&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;//&amp;nbsp;❌&amp;nbsp;不稳定&amp;nbsp;-&amp;nbsp;每次都会重组
data&amp;nbsp;class&amp;nbsp;UserState(val&amp;nbsp;name:&amp;nbsp;String,&amp;nbsp;val&amp;nbsp;age:&amp;nbsp;Int)

//&amp;nbsp;✅&amp;nbsp;稳定&amp;nbsp;-&amp;nbsp;标注后可跳过重组
@Immutable
data&amp;nbsp;class&amp;nbsp;UserState(val&amp;nbsp;name:&amp;nbsp;String,&amp;nbsp;val&amp;nbsp;age:&amp;nbsp;Int)

@Composable
fun&amp;nbsp;UserCard(state:&amp;nbsp;UserState)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;当&amp;nbsp;state&amp;nbsp;未变化时，此函数将被跳过
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Text(text&amp;nbsp;=&amp;nbsp;state.name)
}&lt;/pre&gt;&lt;p&gt;建议在项目中开启 &lt;strong&gt;Compose Compiler Report&lt;/strong&gt;，自动分析哪些类和函数是不稳定的，然后有针对性地优化。&lt;/p&gt;&lt;h2&gt;二、remember 与 derivedStateOf 的正确使用&lt;/h2&gt;&lt;p&gt;&lt;code&gt;remember&lt;/code&gt; 是 Compose 中缓存计算结果的核心 API，但错误使用反而会引入 Bug 或性能问题。&lt;/p&gt;&lt;pre&gt;//&amp;nbsp;❌&amp;nbsp;错误：每次重组都重新计算
@Composable
fun&amp;nbsp;BadExample(items:&amp;nbsp;List&amp;lt;String&amp;gt;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;sortedItems&amp;nbsp;=&amp;nbsp;items.sortedBy&amp;nbsp;{&amp;nbsp;it&amp;nbsp;}&amp;nbsp;//&amp;nbsp;每次重组都排序！
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LazyColumn&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(sortedItems)&amp;nbsp;{&amp;nbsp;item&amp;nbsp;-&amp;gt;&amp;nbsp;Text(item)&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

//&amp;nbsp;✅&amp;nbsp;正确：remember&amp;nbsp;缓存计算结果
@Composable
fun&amp;nbsp;GoodExample(items:&amp;nbsp;List&amp;lt;String&amp;gt;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;sortedItems&amp;nbsp;=&amp;nbsp;remember(items)&amp;nbsp;{&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items.sortedBy&amp;nbsp;{&amp;nbsp;it&amp;nbsp;}&amp;nbsp;&amp;nbsp;//&amp;nbsp;只在&amp;nbsp;items&amp;nbsp;变化时重新排序
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LazyColumn&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(sortedItems)&amp;nbsp;{&amp;nbsp;item&amp;nbsp;-&amp;gt;&amp;nbsp;Text(item)&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;&lt;code&gt;derivedStateOf&lt;/code&gt; 适用于从多个状态派生新状态的场景，它会自动追踪依赖并按需更新：&lt;/p&gt;&lt;pre&gt;@Composable
fun&amp;nbsp;SearchScreen(searchQuery:&amp;nbsp;String,&amp;nbsp;allItems:&amp;nbsp;List&amp;lt;String&amp;gt;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;✅&amp;nbsp;derivedStateOf：只在搜索结果真正变化时才触发重组
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;filteredItems&amp;nbsp;by&amp;nbsp;remember&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;derivedStateOf&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(searchQuery.isEmpty())&amp;nbsp;allItems
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;allItems.filter&amp;nbsp;{&amp;nbsp;it.contains(searchQuery,&amp;nbsp;ignoreCase&amp;nbsp;=&amp;nbsp;true)&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LazyColumn&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(filteredItems)&amp;nbsp;{&amp;nbsp;item&amp;nbsp;-&amp;gt;&amp;nbsp;Text(item)&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;关键原则：当一个状态是从其他状态计算而来，且希望减少不必要的重组时，优先选用 &lt;code&gt;derivedStateOf&lt;/code&gt;。&lt;/p&gt;&lt;h2&gt;三、LazyColumn / LazyRow 高性能实践&lt;/h2&gt;&lt;p&gt;列表是 Android 应用中最常见的性能瓶颈。Compose 的 &lt;code&gt;LazyColumn&lt;/code&gt; 等同于 RecyclerView，但使用不当同样会卡顿。&lt;/p&gt;&lt;h3&gt;3.1 为 items 提供稳定的 key&lt;/h3&gt;&lt;pre&gt;LazyColumn&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;❌&amp;nbsp;不提供&amp;nbsp;key：列表增删时全部重组
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(messages)&amp;nbsp;{&amp;nbsp;message&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MessageItem(message)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;✅&amp;nbsp;提供稳定&amp;nbsp;key：只有变化的&amp;nbsp;item&amp;nbsp;才重组
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items&amp;nbsp;=&amp;nbsp;messages,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key&amp;nbsp;=&amp;nbsp;{&amp;nbsp;message&amp;nbsp;-&amp;gt;&amp;nbsp;message.id&amp;nbsp;}&amp;nbsp;&amp;nbsp;//&amp;nbsp;唯一且稳定的&amp;nbsp;key
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{&amp;nbsp;message&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MessageItem(message)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;h3&gt;3.2 使用 contentType 区分不同类型的 item&lt;/h3&gt;&lt;pre&gt;LazyColumn&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items&amp;nbsp;=&amp;nbsp;feedItems,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key&amp;nbsp;=&amp;nbsp;{&amp;nbsp;it.id&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;contentType&amp;nbsp;=&amp;nbsp;{&amp;nbsp;item&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;when&amp;nbsp;(item)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is&amp;nbsp;FeedItem.Post&amp;nbsp;-&amp;gt;&amp;nbsp;&amp;quot;post&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is&amp;nbsp;FeedItem.Ad&amp;nbsp;-&amp;gt;&amp;nbsp;&amp;quot;ad&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is&amp;nbsp;FeedItem.Story&amp;nbsp;-&amp;gt;&amp;nbsp;&amp;quot;story&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{&amp;nbsp;item&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;when&amp;nbsp;(item)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is&amp;nbsp;FeedItem.Post&amp;nbsp;-&amp;gt;&amp;nbsp;PostCard(item)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is&amp;nbsp;FeedItem.Ad&amp;nbsp;-&amp;gt;&amp;nbsp;AdBanner(item)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is&amp;nbsp;FeedItem.Story&amp;nbsp;-&amp;gt;&amp;nbsp;StoryRow(item)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;提供 &lt;code&gt;contentType&lt;/code&gt; 后，Compose 可以在同类型的 item 间复用组合，进一步提升滚动性能。&lt;/p&gt;&lt;h2&gt;四、Baseline Profile：启动与冷启动性能飞跃&lt;/h2&gt;&lt;p&gt;Baseline Profile 是 Android 14+ 推荐的性能优化手段，它通过预编译热点代码路径，显著降低应用启动时间和 UI 卡顿。&lt;/p&gt;&lt;h3&gt;4.1 创建 Baseline Profile&lt;/h3&gt;&lt;p&gt;在项目中添加 &lt;code&gt;baselineprofile&lt;/code&gt; 模块：&lt;/p&gt;&lt;pre&gt;//&amp;nbsp;baselineprofile/build.gradle.kts
plugins&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alias(libs.plugins.baselineprofile)
}

android&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;targetProjectPath&amp;nbsp;=&amp;nbsp;&amp;quot;:app&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;testOptions.managedDevices.localDevices&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;create(&amp;quot;pixel6api34&amp;quot;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;device&amp;nbsp;=&amp;nbsp;&amp;quot;Pixel&amp;nbsp;6&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;apiLevel&amp;nbsp;=&amp;nbsp;34
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;systemImageSource&amp;nbsp;=&amp;nbsp;&amp;quot;google&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

dependencies&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;implementation(libs.androidx.benchmark.macro.junit4)
}&lt;/pre&gt;&lt;pre&gt;//&amp;nbsp;编写&amp;nbsp;Profile&amp;nbsp;Generator
@ExperimentalBaselineProfilesApi
class&amp;nbsp;BaselineProfileGenerator&amp;nbsp;{

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@get:Rule
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;rule&amp;nbsp;=&amp;nbsp;BaselineProfileRule()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@Test
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fun&amp;nbsp;generateBaselineProfile()&amp;nbsp;=&amp;nbsp;rule.collect(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;packageName&amp;nbsp;=&amp;nbsp;&amp;quot;com.example.myapp&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;模拟用户核心路径
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pressHome()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;startActivityAndWait()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;滚动主列表
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;device.findObject(By.res(&amp;quot;feed_list&amp;quot;)).also&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;it.setGestureMargin(device.displayWidth&amp;nbsp;/&amp;nbsp;5)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;it.fling(Direction.DOWN)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;device.waitForIdle()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;h3&gt;4.2 集成 Baseline Profile&lt;/h3&gt;&lt;pre&gt;//&amp;nbsp;app/build.gradle.kts
dependencies&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;implementation(libs.androidx.profileinstaller)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;baselineProfile&amp;quot;(project(&amp;quot;:baselineprofile&amp;quot;))
}&lt;/pre&gt;&lt;p&gt;集成后，应用冷启动速度通常可提升 &lt;strong&gt;30-40%&lt;/strong&gt;，滑动帧率也会明显改善。&lt;/p&gt;&lt;h2&gt;五、避免常见性能陷阱&lt;/h2&gt;&lt;h3&gt;5.1 Lambda 捕获导致的重组&lt;/h3&gt;&lt;pre&gt;//&amp;nbsp;❌&amp;nbsp;每次重组都创建新的&amp;nbsp;lambda&amp;nbsp;对象，导致子&amp;nbsp;Composable&amp;nbsp;重组
@Composable
fun&amp;nbsp;Parent(viewModel:&amp;nbsp;MyViewModel)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;count&amp;nbsp;by&amp;nbsp;viewModel.count.collectAsState()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Child(onClick&amp;nbsp;=&amp;nbsp;{&amp;nbsp;viewModel.increment()&amp;nbsp;})&amp;nbsp;&amp;nbsp;//&amp;nbsp;新&amp;nbsp;lambda
}

//&amp;nbsp;✅&amp;nbsp;用&amp;nbsp;remember&amp;nbsp;缓存&amp;nbsp;lambda
@Composable
fun&amp;nbsp;Parent(viewModel:&amp;nbsp;MyViewModel)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;count&amp;nbsp;by&amp;nbsp;viewModel.count.collectAsState()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;onClick&amp;nbsp;=&amp;nbsp;remember&amp;nbsp;{&amp;nbsp;{&amp;nbsp;viewModel.increment()&amp;nbsp;}&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Child(onClick&amp;nbsp;=&amp;nbsp;onClick)
}&lt;/pre&gt;&lt;h3&gt;5.2 避免在重组期间读写 State&lt;/h3&gt;&lt;pre&gt;//&amp;nbsp;❌&amp;nbsp;在重组阶段写入&amp;nbsp;State，引发无限重组
@Composable
fun&amp;nbsp;BadCounter()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;count&amp;nbsp;by&amp;nbsp;remember&amp;nbsp;{&amp;nbsp;mutableStateOf(0)&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;count++&amp;nbsp;&amp;nbsp;//&amp;nbsp;❌&amp;nbsp;重组期间写入，触发新的重组，无限循环！
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Text(&amp;quot;Count:&amp;nbsp;$count&amp;quot;)
}

//&amp;nbsp;✅&amp;nbsp;在事件回调中修改&amp;nbsp;State
@Composable
fun&amp;nbsp;GoodCounter()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;count&amp;nbsp;by&amp;nbsp;remember&amp;nbsp;{&amp;nbsp;mutableStateOf(0)&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Button(onClick&amp;nbsp;=&amp;nbsp;{&amp;nbsp;count++&amp;nbsp;})&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Text(&amp;quot;Count:&amp;nbsp;$count&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;h3&gt;5.3 使用 Layout Inspector 定位重组热点&lt;/h3&gt;&lt;p&gt;Android Studio 的 &lt;strong&gt;Layout Inspector&lt;/strong&gt; 在 Compose 模式下可以直观显示每个可组合函数的重组次数和跳过次数。重组次数异常高的节点，就是需要重点优化的地方。&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;打开 &lt;strong&gt;View &amp;gt; Tool Windows &amp;gt; Layout Inspector&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;连接设备运行 App，选择进程&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;在 &lt;strong&gt;Recomposition Counts&lt;/strong&gt; 列查看各节点数据&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;重组次数持续累加、跳过次数为 0 的节点需重点优化&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;六、实战案例：优化复杂列表页面&lt;/h2&gt;&lt;p&gt;以一个包含图片、标题、标签的复杂信息流列表为例，展示完整的优化过程：&lt;/p&gt;&lt;pre&gt;@Immutable
data&amp;nbsp;class&amp;nbsp;Article(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;id:&amp;nbsp;Long,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;title:&amp;nbsp;String,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;coverUrl:&amp;nbsp;String,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;tags:&amp;nbsp;List&amp;lt;String&amp;gt;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;publishTime:&amp;nbsp;Long
)

@Composable
fun&amp;nbsp;ArticleFeed(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;articles:&amp;nbsp;List&amp;lt;Article&amp;gt;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onArticleClick:&amp;nbsp;(Long)&amp;nbsp;-&amp;gt;&amp;nbsp;Unit
)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;derivedStateOf&amp;nbsp;派生排序后的列表
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;sortedArticles&amp;nbsp;by&amp;nbsp;remember&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;derivedStateOf&amp;nbsp;{&amp;nbsp;articles.sortedByDescending&amp;nbsp;{&amp;nbsp;it.publishTime&amp;nbsp;}&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LazyColumn(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;verticalArrangement&amp;nbsp;=&amp;nbsp;Arrangement.spacedBy(8.dp),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;contentPadding&amp;nbsp;=&amp;nbsp;PaddingValues(16.dp)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items&amp;nbsp;=&amp;nbsp;sortedArticles,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key&amp;nbsp;=&amp;nbsp;{&amp;nbsp;it.id&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;contentType&amp;nbsp;=&amp;nbsp;{&amp;nbsp;&amp;quot;article&amp;quot;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{&amp;nbsp;article&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ArticleCard(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;article&amp;nbsp;=&amp;nbsp;article,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onClick&amp;nbsp;=&amp;nbsp;remember(article.id)&amp;nbsp;{&amp;nbsp;{&amp;nbsp;onArticleClick(article.id)&amp;nbsp;}&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

@Composable
fun&amp;nbsp;ArticleCard(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;article:&amp;nbsp;Article,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onClick:&amp;nbsp;()&amp;nbsp;-&amp;gt;&amp;nbsp;Unit,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier:&amp;nbsp;Modifier&amp;nbsp;=&amp;nbsp;Modifier
)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Card(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onClick&amp;nbsp;=&amp;nbsp;onClick,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier&amp;nbsp;=&amp;nbsp;modifier.fillMaxWidth()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Column(modifier&amp;nbsp;=&amp;nbsp;Modifier.padding(12.dp))&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;AsyncImage(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;model&amp;nbsp;=&amp;nbsp;article.coverUrl,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;contentDescription&amp;nbsp;=&amp;nbsp;null,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier&amp;nbsp;=&amp;nbsp;Modifier
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.fillMaxWidth()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.height(160.dp)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.clip(RoundedCornerShape(8.dp)),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;contentScale&amp;nbsp;=&amp;nbsp;ContentScale.Crop
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Spacer(modifier&amp;nbsp;=&amp;nbsp;Modifier.height(8.dp))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Text(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;text&amp;nbsp;=&amp;nbsp;article.title,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;style&amp;nbsp;=&amp;nbsp;MaterialTheme.typography.titleMedium,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;maxLines&amp;nbsp;=&amp;nbsp;2,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;overflow&amp;nbsp;=&amp;nbsp;TextOverflow.Ellipsis
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Spacer(modifier&amp;nbsp;=&amp;nbsp;Modifier.height(4.dp))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FlowRow(horizontalArrangement&amp;nbsp;=&amp;nbsp;Arrangement.spacedBy(4.dp))&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;article.tags.forEach&amp;nbsp;{&amp;nbsp;tag&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SuggestionChip(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onClick&amp;nbsp;=&amp;nbsp;{},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;label&amp;nbsp;=&amp;nbsp;{&amp;nbsp;Text(tag,&amp;nbsp;style&amp;nbsp;=&amp;nbsp;MaterialTheme.typography.labelSmall)&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;经过以上优化，该列表页面的滚动帧率从平均 45fps 提升到稳定 60fps，首帧渲染时间减少约 35%。&lt;/p&gt;&lt;h2&gt;七、性能优化工具链总结&lt;/h2&gt;&lt;p&gt;工欲善其事，必先利其器。以下是 Compose 性能优化必备工具：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Compose Compiler Metrics&lt;/strong&gt;：分析可组合函数的稳定性，输出详细报告&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Android Studio Layout Inspector&lt;/strong&gt;：实时查看重组次数和跳过情况&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Macrobenchmark&lt;/strong&gt;：测量真实设备上的启动时间、滚动帧率&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Systrace / Perfetto&lt;/strong&gt;：深入分析 UI 线程和渲染线程的耗时&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;StrictMode&lt;/strong&gt;：在开发阶段检测主线程 IO 等违规操作&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;//&amp;nbsp;在&amp;nbsp;build.gradle.kts&amp;nbsp;中开启&amp;nbsp;Compiler&amp;nbsp;Metrics
tasks.withType&amp;lt;KotlinCompile&amp;gt;().configureEach&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;compilerOptions&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;freeCompilerArgs.addAll(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;-P&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=${project.buildDir.absolutePath}/compose_metrics&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;-P&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=${project.buildDir.absolutePath}/compose_metrics&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;性能优化是一个持续迭代的过程。建议在项目初期就建立性能基准测试，将 Macrobenchmark 集成到 CI/CD 流水线，确保每次迭代都不引入性能退化。&lt;/p&gt;&lt;p&gt;掌握本文介绍的核心技术——稳定性注解、remember/derivedStateOf 正确使用、LazyColumn 最佳实践、Baseline Profile 预编译以及常见陷阱规避——你的 Compose 应用将在各种设备上都能保持出色的性能表现。&lt;/p&gt;</description><pubDate>Thu, 22 Oct 2026 08:04:29 +0800</pubDate></item><item><title>AI Agent 工作流实战：用 LangGraph 构建生产级多智能体系统</title><link>https://blog.resmic.cn/post/390.html</link><description>&lt;p&gt;&lt;img src=&quot;https://blog.resmic.cn/zb_users/upload/2026/10/20261021080519179254111983960.jpg&quot; alt=&quot;封面&quot; style=&quot;width:100%;&quot;/&gt;&lt;/p&gt;&lt;h2&gt;为什么选择 LangGraph？&lt;/h2&gt;&lt;p&gt;随着大语言模型（LLM）能力的持续提升，单轮对话已难以满足复杂业务需求。AI Agent 工作流正在成为新的开发范式——它允许模型在多步骤任务中保持状态、调用工具、与其他 Agent 协作。而 LangGraph 正是 LangChain 生态中专为此设计的编排框架。&lt;/p&gt;&lt;p&gt;与简单的链式调用相比，LangGraph 提供了有状态的图执行引擎（通过 StateGraph 管理跨步骤的上下文）、条件边与循环（支持基于模型输出动态决定下一步骤）、持久化检查点（支持中断恢复与人工干预）以及多 Agent 协作能力（原生支持 Supervisor 模式与 Swarm 模式）。相比 CrewAI、AutoGen 等框架，LangGraph 的最大优势在于透明性与可控性，你能精确知道每个节点的输入输出，适合生产级应用。&lt;/p&gt;&lt;h2&gt;核心概念：状态图与节点&lt;/h2&gt;&lt;p&gt;LangGraph 的核心抽象是 StateGraph，整个工作流被建模为一张有向图：节点（Node）执行具体逻辑，边（Edge）决定流转路径，状态（State）在节点间传递。&lt;/p&gt;&lt;p&gt;一个典型的 LangGraph 应用由以下几部分构成：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;State（状态）&lt;/strong&gt;：使用 TypedDict 定义，记录整个工作流中需要传递的数据结构&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Node（节点）&lt;/strong&gt;：普通 Python 函数，接收并返回状态，每个节点负责一项具体任务&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Edge（边）&lt;/strong&gt;：连接节点的路径，可以是固定的，也可以是基于条件动态决定的&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Compile（编译）&lt;/strong&gt;：调用 workflow.compile() 生成可执行的应用实例&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;通过将推理节点（think）和执行节点（action）循环连接，可以构建出经典的 ReAct 循环——模型先推理当前情况，再执行工具，然后观察结果并继续推理。&lt;/p&gt;&lt;h2&gt;多智能体架构设计&lt;/h2&gt;&lt;p&gt;真实业务场景往往需要多个专职 Agent 协作完成任务。LangGraph 支持两种主流多 Agent 架构：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Supervisor 模式&lt;/strong&gt;：一个主控 Agent 负责任务分发与结果汇总，子 Agent 专注特定能力。例如，一个 researcher Agent 负责联网搜索，一个 coder Agent 负责编写代码，Supervisor 负责根据任务性质分配工作。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Swarm 模式（Handoff）&lt;/strong&gt;：Agent 之间平等交接控制权，适合流水线型任务。上游 Agent 完成自己的工作后，将控制权移交给下游 Agent，实现无缝协作。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;使用 langgraph-supervisor 库可以快速构建 Supervisor 模式的多 Agent 系统，通过 create_supervisor() 函数声明主控逻辑，通过 create_react_agent() 为每个子 Agent 配置专属工具和指令。&lt;/p&gt;&lt;h2&gt;生产关键：持久化与人工干预&lt;/h2&gt;&lt;p&gt;生产级 Agent 系统必须具备两个能力：状态持久化（防止 token 超限或服务崩溃时丢失进度）和人工干预（在关键决策点插入人工审核）。LangGraph 通过 Checkpointer 机制实现这两点。&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;PostgresSaver&lt;/strong&gt;：使用 PostgreSQL 作为持久化后端，支持多线程并发和高可用部署&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;SqliteSaver&lt;/strong&gt;：轻量级本地持久化，适合开发调试阶段&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;MemorySaver&lt;/strong&gt;：内存持久化，适合无状态场景的快速原型&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;通过在 compile() 时设置 interrupt_before 参数，可以在高风险节点前自动暂停，等待人工确认后再继续执行。每次会话使用唯一的 thread_id 标识，支持随时中断和恢复，非常适合需要人工审核的业务流程。&lt;/p&gt;&lt;h2&gt;工具调用最佳实践&lt;/h2&gt;&lt;p&gt;Agent 的能力上限取决于工具的质量。以下是生产环境中工具设计的核心原则：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;原子性&lt;/strong&gt;：每个工具只做一件事，避免副作用耦合。不要把搜索和存储写在同一个工具里。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;幂等性&lt;/strong&gt;：工具应能安全重试，避免重复执行产生副作用。查询类工具天然幂等，写入类工具需额外设计。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;超时控制&lt;/strong&gt;：所有外部调用必须设置 timeout，防止 Agent 卡死在等待状态。建议通过 httpx.Client(timeout=10.0) 统一控制。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;结构化输出&lt;/strong&gt;：返回 JSON 格式而非纯文本，便于模型解析和下一步使用。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;错误友好&lt;/strong&gt;：捕获所有异常并返回结构化的错误信息，让 Agent 能够理解失败原因并决定是否重试。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;LangChain 的 @tool 装饰器配合 Pydantic 的 BaseModel 可以优雅地定义工具的参数 schema，让模型能够准确理解参数含义和类型约束，减少错误调用。&lt;/p&gt;&lt;h2&gt;错误恢复与重试策略&lt;/h2&gt;&lt;p&gt;生产 Agent 系统必须有完善的错误处理机制。LangGraph 提供了节点级别的 RetryPolicy 配置，支持设置最大重试次数、等待时间、指数退避系数以及需要重试的异常类型。&lt;/p&gt;&lt;p&gt;除了代码层面的重试，还应在架构层面考虑：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;降级策略&lt;/strong&gt;：主模型失败时切换到备用模型（例如 GPT-4o 失败后切换到 GPT-4o-mini）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;限流保护&lt;/strong&gt;：使用令牌桶算法控制工具调用频率，避免触发外部 API 的速率限制&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;告警监控&lt;/strong&gt;：接入 LangSmith 或自建可观测系统，追踪 Agent 每步执行的 token 消耗、延迟和成功率&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;死循环检测&lt;/strong&gt;：设置最大循环次数，防止 Agent 在某个步骤无限重试&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;性能优化：并发执行&lt;/h2&gt;&lt;p&gt;当 Agent 需要并行调用多个工具时，串行等待会极大影响响应速度。LangGraph 支持通过 Send API 实现节点级并发：协调节点将任务列表拆分为多个 Send 对象，图引擎会并行调度所有工作节点，最后汇聚结果。&lt;/p&gt;&lt;p&gt;实测显示，对于需要调用 5 个外部 API 的场景，并行执行可将总耗时从 15 秒缩短至 4 秒，性能提升超过 3 倍。在实际应用中，网络搜索、数据库查询、文件读取等独立操作都是并发优化的理想候选。&lt;/p&gt;&lt;h2&gt;部署与监控建议&lt;/h2&gt;&lt;p&gt;将 LangGraph 应用推向生产，需要关注以下几个维度：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;容器化部署&lt;/strong&gt;：使用 Docker + Kubernetes，为每个 Agent 服务配置独立的资源限制，避免单个 Agent 占用过多 CPU 或内存&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;可观测性&lt;/strong&gt;：接入 LangSmith Tracing，或将 trace 导出到 OpenTelemetry 兼容后端（如 Jaeger、Grafana Tempo）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;成本控制&lt;/strong&gt;：使用 token 计数中间件监控每次调用的 token 消耗，设置预算告警和硬限制&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;版本管理&lt;/strong&gt;：对 Agent 图结构进行版本控制，支持 A/B 测试和灰度发布，生产变更需经过充分测试&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;对于需要快速上线的团队，LangGraph Cloud 提供了一键部署能力，内置任务队列、持久化存储和 Studio 可视化调试界面，是生产落地的最低阻力路径。从原型到生产的跨越，核心在于可靠性设计：持久化状态、优雅降级、完整可观测。LangGraph 提供了正确的抽象层，剩下的，就是你对业务逻辑的深刻理解。&lt;/p&gt;</description><pubDate>Wed, 21 Oct 2026 08:12:07 +0800</pubDate></item><item><title>Jetpack Compose 性能优化实战：从重组机制到生产级调优指南</title><link>https://blog.resmic.cn/post/389.html</link><description>&lt;p&gt;&lt;img src=&quot;https://blog.resmic.cn/zb_users/upload/2026/10/20261020080446179245468662505.jpg&quot; alt=&quot;封面&quot; style=&quot;width:100%;&quot;/&gt;&lt;/p&gt;&lt;h2&gt;一、为什么 Compose 应用会卡？从重组机制说起&lt;/h2&gt;&lt;p&gt;Jetpack Compose 基于响应式编程模型，当状态（State）发生变化时，框架会自动触发依赖该状态的 Composable 函数重新执行，这个过程称为&lt;strong&gt;重组（Recomposition）&lt;/strong&gt;。理想情况下，重组是精确且高效的，但在实际开发中，许多常见写法会导致不必要的大规模重组，进而引发 UI 卡顿、列表滑动不流畅等体验问题。&lt;/p&gt;&lt;p&gt;理解性能优化，必须先理解 Compose 的三个核心阶段：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;组合（Composition）&lt;/strong&gt;：执行 Composable 函数，构建 UI 树描述&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;布局（Layout）&lt;/strong&gt;：测量和放置每个节点&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;绘制（Drawing）&lt;/strong&gt;：将节点渲染到 Canvas 上&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;性能问题通常发生在「组合」阶段——过多不必要的 Composable 函数被重新执行。Compose 官方工具 Layout Inspector 和 Recomposition Highlighter 可以帮助我们直观地发现重组热点。&lt;/p&gt;&lt;pre&gt;//&amp;nbsp;在&amp;nbsp;debug&amp;nbsp;构建中开启重组计数器
class&amp;nbsp;MainActivity&amp;nbsp;:&amp;nbsp;ComponentActivity()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;override&amp;nbsp;fun&amp;nbsp;onCreate(savedInstanceState:&amp;nbsp;Bundle?)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;super.onCreate(savedInstanceState)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;setContent&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;ComposeInvestigator&amp;nbsp;或&amp;nbsp;Layout&amp;nbsp;Inspector&amp;nbsp;观察重组
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MyApp()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;h2&gt;二、稳定性（Stability）：让 Compose 跳过不必要的重组&lt;/h2&gt;&lt;p&gt;Compose 编译器会对每个 Composable 的参数进行稳定性分析。如果所有参数都被判定为「稳定（Stable）」，且参数值未发生变化，Compose 就可以安全地&lt;strong&gt;跳过（Skip）&lt;/strong&gt;该 Composable 的重组——这是性能优化的核心机制。&lt;/p&gt;&lt;p&gt;哪些类型天然稳定？&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;基本类型：&lt;code&gt;Int&lt;/code&gt;、&lt;code&gt;String&lt;/code&gt;、&lt;code&gt;Boolean&lt;/code&gt;、&lt;code&gt;Float&lt;/code&gt; 等&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;函数类型（lambda）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;标注了 &lt;code&gt;@Stable&lt;/code&gt; 或 &lt;code&gt;@Immutable&lt;/code&gt; 的类&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;哪些类型不稳定（导致无法跳过重组）？&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;普通 &lt;code&gt;data class&lt;/code&gt; 包含 &lt;code&gt;List&lt;/code&gt;、&lt;code&gt;Map&lt;/code&gt; 等集合类型&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;来自非 Compose 模块的类（编译器无法分析）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;包含 &lt;code&gt;var&lt;/code&gt; 属性的类&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;//&amp;nbsp;❌&amp;nbsp;不稳定：List&amp;nbsp;不是&amp;nbsp;Stable&amp;nbsp;类型
data&amp;nbsp;class&amp;nbsp;UiState(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;items:&amp;nbsp;List&amp;lt;Item&amp;gt;,&amp;nbsp;&amp;nbsp;//&amp;nbsp;导致整个类不稳定
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;isLoading:&amp;nbsp;Boolean
)

//&amp;nbsp;✅&amp;nbsp;方案1：使用&amp;nbsp;@Immutable&amp;nbsp;标注（承诺内容不可变）
@Immutable
data&amp;nbsp;class&amp;nbsp;UiState(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;items:&amp;nbsp;List&amp;lt;Item&amp;gt;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;isLoading:&amp;nbsp;Boolean
)

//&amp;nbsp;✅&amp;nbsp;方案2：使用&amp;nbsp;kotlinx.collections.immutable
import&amp;nbsp;kotlinx.collections.immutable.ImmutableList
import&amp;nbsp;kotlinx.collections.immutable.persistentListOf

data&amp;nbsp;class&amp;nbsp;UiState(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;items:&amp;nbsp;ImmutableList&amp;lt;Item&amp;gt;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;isLoading:&amp;nbsp;Boolean
)&lt;/pre&gt;&lt;p&gt;推荐在项目中引入 &lt;code&gt;kotlinx.collections.immutable&lt;/code&gt; 库，它提供真正不可变的集合类型，Compose 编译器可以直接识别其稳定性。&lt;/p&gt;&lt;h2&gt;三、remember 与 rememberUpdatedState 的正确使用姿势&lt;/h2&gt;&lt;p&gt;&lt;code&gt;remember&lt;/code&gt; 是 Compose 中缓存计算结果的核心 API，正确使用可以避免每次重组时重复进行昂贵的计算或对象创建。&lt;/p&gt;&lt;h3&gt;3.1 remember 的基础用法&lt;/h3&gt;&lt;pre&gt;@Composable
fun&amp;nbsp;ExpensiveScreen(data:&amp;nbsp;List&amp;lt;Item&amp;gt;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;❌&amp;nbsp;每次重组都会重新排序，即使&amp;nbsp;data&amp;nbsp;没变
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;sortedItems&amp;nbsp;=&amp;nbsp;data.sortedBy&amp;nbsp;{&amp;nbsp;it.name&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;✅&amp;nbsp;只有&amp;nbsp;data&amp;nbsp;变化时才重新计算
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;sortedItems&amp;nbsp;=&amp;nbsp;remember(data)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data.sortedBy&amp;nbsp;{&amp;nbsp;it.name&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LazyColumn&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(sortedItems)&amp;nbsp;{&amp;nbsp;item&amp;nbsp;-&amp;gt;&amp;nbsp;ItemRow(item)&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;h3&gt;3.2 rememberUpdatedState：处理长生命周期 effect 中的回调&lt;/h3&gt;&lt;pre&gt;@Composable
fun&amp;nbsp;Timer(onTimeout:&amp;nbsp;()&amp;nbsp;-&amp;gt;&amp;nbsp;Unit)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;✅&amp;nbsp;确保&amp;nbsp;LaunchedEffect&amp;nbsp;中始终引用最新的&amp;nbsp;onTimeout
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;currentOnTimeout&amp;nbsp;by&amp;nbsp;rememberUpdatedState(onTimeout)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LaunchedEffect(Unit)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;delay(5000L)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;currentOnTimeout()&amp;nbsp;&amp;nbsp;//&amp;nbsp;不会捕获旧的&amp;nbsp;onTimeout&amp;nbsp;引用
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;h3&gt;3.3 rememberSaveable：跨越配置变更的记忆&lt;/h3&gt;&lt;pre&gt;@Composable
fun&amp;nbsp;SearchBar()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;旋转屏幕后仍能保持搜索内容
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;query&amp;nbsp;by&amp;nbsp;rememberSaveable&amp;nbsp;{&amp;nbsp;mutableStateOf(&amp;quot;&amp;quot;)&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TextField(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;value&amp;nbsp;=&amp;nbsp;query,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onValueChange&amp;nbsp;=&amp;nbsp;{&amp;nbsp;query&amp;nbsp;=&amp;nbsp;it&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;label&amp;nbsp;=&amp;nbsp;{&amp;nbsp;Text(&amp;quot;搜索&amp;quot;)&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
}&lt;/pre&gt;&lt;h2&gt;四、derivedStateOf：精确控制重组触发时机&lt;/h2&gt;&lt;p&gt;&lt;code&gt;derivedStateOf&lt;/code&gt; 用于将一个或多个 State 转换为新的 State，&lt;strong&gt;只有当派生结果真正变化时，才触发读取该派生状态的 Composable 重组&lt;/strong&gt;。这对于高频状态变化（如滚动位置）非常有效。&lt;/p&gt;&lt;pre&gt;@Composable
fun&amp;nbsp;ChatList()&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;listState&amp;nbsp;=&amp;nbsp;rememberLazyListState()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;❌&amp;nbsp;错误：每次滚动都触发重组（因为&amp;nbsp;firstVisibleItemIndex&amp;nbsp;每帧都变）
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;showScrollButton&amp;nbsp;=&amp;nbsp;listState.firstVisibleItemIndex&amp;nbsp;&amp;gt;&amp;nbsp;0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;✅&amp;nbsp;正确：只有&amp;quot;是否显示按钮&amp;quot;的结果变化时才重组
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;showScrollButton&amp;nbsp;by&amp;nbsp;remember&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;derivedStateOf&amp;nbsp;{&amp;nbsp;listState.firstVisibleItemIndex&amp;nbsp;&amp;gt;&amp;nbsp;0&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Box&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LazyColumn(state&amp;nbsp;=&amp;nbsp;listState)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(1000)&amp;nbsp;{&amp;nbsp;index&amp;nbsp;-&amp;gt;&amp;nbsp;ChatItem(index)&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(showScrollButton)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FloatingActionButton(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onClick&amp;nbsp;=&amp;nbsp;{&amp;nbsp;/*&amp;nbsp;滚回顶部&amp;nbsp;*/&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier&amp;nbsp;=&amp;nbsp;Modifier.align(Alignment.BottomEnd)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Icon(Icons.Default.ArrowUpward,&amp;nbsp;&amp;quot;回到顶部&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;使用场景总结：&lt;/strong&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;列表滚动位置 → 控制「回到顶部」按钮显示&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;表单输入内容 → 控制「提交」按钮的启用/禁用&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;复杂过滤/搜索逻辑 → 避免每次击键都全量重算&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;五、LazyList 性能优化：contentType 与 key 的重要性&lt;/h2&gt;&lt;p&gt;&lt;code&gt;LazyColumn&lt;/code&gt; / &lt;code&gt;LazyRow&lt;/code&gt; 是 Compose 中处理长列表的核心组件，但不当使用同样会造成性能问题。&lt;/p&gt;&lt;h3&gt;5.1 设置 key：避免错误的重组和动画&lt;/h3&gt;&lt;pre&gt;LazyColumn&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items&amp;nbsp;=&amp;nbsp;contacts,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key&amp;nbsp;=&amp;nbsp;{&amp;nbsp;contact&amp;nbsp;-&amp;gt;&amp;nbsp;contact.id&amp;nbsp;}&amp;nbsp;&amp;nbsp;//&amp;nbsp;✅&amp;nbsp;稳定唯一标识
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{&amp;nbsp;contact&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ContactRow(contact)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;不设置 &lt;code&gt;key&lt;/code&gt; 时，列表插入/删除/排序会导致所有可见项重组，设置后 Compose 可以精确追踪每个 item 的身份，实现最小化更新。&lt;/p&gt;&lt;h3&gt;5.2 设置 contentType：复用不同类型的 item&lt;/h3&gt;&lt;pre&gt;LazyColumn&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items&amp;nbsp;=&amp;nbsp;feedItems,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key&amp;nbsp;=&amp;nbsp;{&amp;nbsp;it.id&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;contentType&amp;nbsp;=&amp;nbsp;{&amp;nbsp;item&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;when&amp;nbsp;(item)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is&amp;nbsp;FeedItem.Post&amp;nbsp;-&amp;gt;&amp;nbsp;&amp;quot;post&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;✅&amp;nbsp;相同类型共享组合节点
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is&amp;nbsp;FeedItem.Ad&amp;nbsp;-&amp;gt;&amp;nbsp;&amp;quot;ad&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is&amp;nbsp;FeedItem.Story&amp;nbsp;-&amp;gt;&amp;nbsp;&amp;quot;story&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{&amp;nbsp;item&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;when&amp;nbsp;(item)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is&amp;nbsp;FeedItem.Post&amp;nbsp;-&amp;gt;&amp;nbsp;PostCard(item)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is&amp;nbsp;FeedItem.Ad&amp;nbsp;-&amp;gt;&amp;nbsp;AdBanner(item)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;is&amp;nbsp;FeedItem.Story&amp;nbsp;-&amp;gt;&amp;nbsp;StoryRow(item)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;h3&gt;5.3 避免在 item lambda 中创建不稳定对象&lt;/h3&gt;&lt;pre&gt;//&amp;nbsp;❌&amp;nbsp;每次重组都创建新的&amp;nbsp;lambda，导致&amp;nbsp;item&amp;nbsp;无法跳过重组
LazyColumn&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(list)&amp;nbsp;{&amp;nbsp;item&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ItemRow(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;item&amp;nbsp;=&amp;nbsp;item,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onClick&amp;nbsp;=&amp;nbsp;{&amp;nbsp;viewModel.onItemClick(item.id)&amp;nbsp;}&amp;nbsp;&amp;nbsp;//&amp;nbsp;新&amp;nbsp;lambda！
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

//&amp;nbsp;✅&amp;nbsp;将事件回调提升到&amp;nbsp;ViewModel，使用稳定引用
LazyColumn&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(list,&amp;nbsp;key&amp;nbsp;=&amp;nbsp;{&amp;nbsp;it.id&amp;nbsp;})&amp;nbsp;{&amp;nbsp;item&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ItemRow(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;item&amp;nbsp;=&amp;nbsp;item,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onClick&amp;nbsp;=&amp;nbsp;viewModel::onItemClick&amp;nbsp;&amp;nbsp;//&amp;nbsp;稳定引用
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;h2&gt;六、Modifier 链优化与 graphicsLayer 硬件加速&lt;/h2&gt;&lt;p&gt;Modifier 的使用顺序和方式对布局和渲染性能有直接影响。&lt;/p&gt;&lt;h3&gt;6.1 Modifier.drawWithCache：缓存绘制操作&lt;/h3&gt;&lt;pre&gt;//&amp;nbsp;✅&amp;nbsp;渐变背景只在尺寸变化时重新创建
Box(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier&amp;nbsp;=&amp;nbsp;Modifier
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.fillMaxSize()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.drawWithCache&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;gradient&amp;nbsp;=&amp;nbsp;Brush.verticalGradient(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;colors&amp;nbsp;=&amp;nbsp;listOf(Color.Blue,&amp;nbsp;Color.Cyan),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;startY&amp;nbsp;=&amp;nbsp;0f,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;endY&amp;nbsp;=&amp;nbsp;size.height
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onDrawBehind&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;drawRect(gradient)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
)&lt;/pre&gt;&lt;h3&gt;6.2 graphicsLayer：GPU 加速动画&lt;/h3&gt;&lt;pre&gt;@Composable
fun&amp;nbsp;AnimatedCard(visible:&amp;nbsp;Boolean)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;alpha&amp;nbsp;by&amp;nbsp;animateFloatAsState(if&amp;nbsp;(visible)&amp;nbsp;1f&amp;nbsp;else&amp;nbsp;0f)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;scale&amp;nbsp;by&amp;nbsp;animateFloatAsState(if&amp;nbsp;(visible)&amp;nbsp;1f&amp;nbsp;else&amp;nbsp;0.8f)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Card(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier&amp;nbsp;=&amp;nbsp;Modifier
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.graphicsLayer&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;✅&amp;nbsp;在&amp;nbsp;GPU&amp;nbsp;层执行，不触发重组和重布局
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.alpha&amp;nbsp;=&amp;nbsp;alpha
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;scaleX&amp;nbsp;=&amp;nbsp;scale
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;scaleY&amp;nbsp;=&amp;nbsp;scale
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CardContent()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;使用 &lt;code&gt;graphicsLayer&lt;/code&gt; 执行透明度、缩放、旋转等变换时，Compose 会将该节点提升到独立的渲染层，变换只发生在 GPU 侧，完全绕过组合和布局阶段，动画性能极佳。&lt;/p&gt;&lt;h2&gt;七、实战：用 Baseline Profiles 提升冷启动速度&lt;/h2&gt;&lt;p&gt;Compose 大量使用反射和动态代码，首次运行时 JIT 编译开销大，导致冷启动卡顿。&lt;strong&gt;Baseline Profiles&lt;/strong&gt; 可以预先将关键代码路径编译为机器码，显著改善启动体验。&lt;/p&gt;&lt;pre&gt;//&amp;nbsp;build.gradle.kts
plugins&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;id(&amp;quot;com.android.application&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;id(&amp;quot;androidx.baselineprofile&amp;quot;)
}

dependencies&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;implementation(&amp;quot;androidx.profileinstaller:profileinstaller:1.3.1&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;baselineProfile(project(&amp;quot;:baselineprofile&amp;quot;))
}

//&amp;nbsp;baselineprofile/src/main/kotlin/GenerateBaselineProfile.kt
@ExperimentalBaselineProfilesApi
class&amp;nbsp;GenerateBaselineProfile&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@get:Rule
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;rule&amp;nbsp;=&amp;nbsp;BaselineProfileRule()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@Test
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fun&amp;nbsp;generate()&amp;nbsp;=&amp;nbsp;rule.collect(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;packageName&amp;nbsp;=&amp;nbsp;&amp;quot;com.example.myapp&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;遍历关键用户旅程
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pressHome()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;startActivityAndWait()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;滚动主列表
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;device.findObject(By.res(&amp;quot;main_list&amp;quot;)).also&amp;nbsp;{&amp;nbsp;list&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;list.setGestureMargin(device.displayWidth&amp;nbsp;/&amp;nbsp;5)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;list.fling(Direction.DOWN)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;生成 Baseline Profile 后，将 &lt;code&gt;baseline-prof.txt&lt;/code&gt; 提交到代码库，R8 在构建 release 包时会自动读取并预编译，冷启动时间通常可减少 20%~40%。&lt;/p&gt;&lt;h2&gt;八、性能监控：线上发现问题比线下更重要&lt;/h2&gt;&lt;p&gt;本地优化固然重要，但真实用户设备千差万别，建立完善的线上性能监控体系才是长久之道。&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Android Vitals&lt;/strong&gt;：Google Play 控制台提供的 ANR 率、崩溃率、启动速度等核心指标&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Firebase Performance Monitoring&lt;/strong&gt;：自定义 Trace 追踪关键业务路径耗时&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Macrobenchmark&lt;/strong&gt;：在 CI/CD 中自动化测量启动时间和滚动帧率，防止性能回退&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;//&amp;nbsp;使用&amp;nbsp;Macrobenchmark&amp;nbsp;测量滚动性能
@LargeTest
@RunWith(AndroidJUnit4::class)
class&amp;nbsp;ScrollBenchmark&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@get:Rule
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;rule&amp;nbsp;=&amp;nbsp;MacrobenchmarkRule()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@Test
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fun&amp;nbsp;scrollFeed()&amp;nbsp;=&amp;nbsp;rule.measureRepeated(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;packageName&amp;nbsp;=&amp;nbsp;&amp;quot;com.example.myapp&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;metrics&amp;nbsp;=&amp;nbsp;listOf(FrameTimingMetric()),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;iterations&amp;nbsp;=&amp;nbsp;5,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;setupBlock&amp;nbsp;=&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pressHome()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;startActivityAndWait()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;feed&amp;nbsp;=&amp;nbsp;device.findObject(By.res(&amp;quot;feed_list&amp;quot;))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;feed.setGestureMargin(device.displayWidth&amp;nbsp;/&amp;nbsp;5)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;repeat(3)&amp;nbsp;{&amp;nbsp;feed.fling(Direction.DOWN)&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;将 Macrobenchmark 集成到 GitHub Actions / 蓝盾 CI，每次 PR 合并后自动跑基准测试，当帧率或启动时间超过阈值时自动发送告警，将性能治理前移到开发阶段。&lt;/p&gt;&lt;p&gt;性能优化是一场持续的战役，没有银弹。掌握本文介绍的重组稳定性控制、remember 正确用法、derivedStateOf、LazyList 最佳实践、graphicsLayer 加速以及 Baseline Profiles 等技术，结合线上监控持续迭代，你的 Compose 应用一定能在各种设备上流畅运行。&lt;/p&gt;</description><pubDate>Tue, 20 Oct 2026 08:08:31 +0800</pubDate></item><item><title>AI Agent 生产落地全攻略：主流框架选型与工程实践</title><link>https://blog.resmic.cn/post/388.html</link><description>&lt;p&gt;&lt;img src=&quot;https://blog.resmic.cn/zb_users/upload/2026/10/20261019080757179236847758159.jpg&quot; alt=&quot;封面&quot; style=&quot;width:100%;&quot;/&gt;&lt;/p&gt;&lt;h2&gt;一、AI Agent 的崛起：从 Demo 到生产落地&lt;/h2&gt;&lt;p&gt;2025 年，AI Agent 已经不再是实验室里的玩具。从 GitHub Copilot Workspace 到 Devin，从企业内部的代码审查机器人到自动化客服系统，基于 LLM 的自主智能体正在各行各业悄然改变工程师的工作方式。&lt;/p&gt;&lt;p&gt;但许多团队在尝试将 Agent 落地时都遇到了同一个问题：框架太多，不知如何选择；架构不清，系统越做越脆；评估困难，上线后效果难以量化。本文将系统梳理当前主流 Agent 框架与范式，帮助开发者做出更明智的技术决策。&lt;/p&gt;&lt;p&gt;AI Agent 的核心能力可以归纳为三点：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;规划（Planning）&lt;/strong&gt;：将复杂目标分解为可执行的子任务序列&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;记忆（Memory）&lt;/strong&gt;：在长对话或跨会话中保持上下文一致性&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;工具使用（Tool Use）&lt;/strong&gt;：调用外部 API、数据库、代码执行器等扩展能力&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;二、主流 Agent 范式对比&lt;/h2&gt;&lt;p&gt;目前生产环境中最常见的 Agent 范式主要有以下几种，各有其适用场景和局限性。&lt;/p&gt;&lt;h3&gt;2.1 ReAct 范式&lt;/h3&gt;&lt;p&gt;ReAct（Reasoning + Acting）是目前最广泛使用的单智能体范式。LLM 在每一步先进行推理（Thought），再决定执行什么行动（Action），观察结果后继续推理，形成 Thought → Action → Observation 的循环。&lt;/p&gt;&lt;pre&gt;from&amp;nbsp;langchain.agents&amp;nbsp;import&amp;nbsp;create_react_agent
from&amp;nbsp;langchain_openai&amp;nbsp;import&amp;nbsp;ChatOpenAI
from&amp;nbsp;langchain.tools&amp;nbsp;import&amp;nbsp;tool

@tool
def&amp;nbsp;search_web(query:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;str:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;Search&amp;nbsp;the&amp;nbsp;web&amp;nbsp;for&amp;nbsp;information.&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;调用搜索&amp;nbsp;API
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;search_api(query)

@tool&amp;nbsp;&amp;nbsp;
def&amp;nbsp;run_python(code:&amp;nbsp;str)&amp;nbsp;-&amp;gt;&amp;nbsp;str:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;Execute&amp;nbsp;Python&amp;nbsp;code&amp;nbsp;in&amp;nbsp;a&amp;nbsp;sandbox.&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;sandbox.run(code)

llm&amp;nbsp;=&amp;nbsp;ChatOpenAI(model=&amp;quot;gpt-4o&amp;quot;,&amp;nbsp;temperature=0)
agent&amp;nbsp;=&amp;nbsp;create_react_agent(llm,&amp;nbsp;tools=[search_web,&amp;nbsp;run_python],&amp;nbsp;prompt=react_prompt)&lt;/pre&gt;&lt;p&gt;ReAct 的优势在于简单透明，每一步推理可以被观察和调试。适合工具数量不超过 10 个、任务链路较短（5 步以内）的场景。&lt;/p&gt;&lt;h3&gt;2.2 Plan-and-Execute 范式&lt;/h3&gt;&lt;p&gt;对于需要长期规划的任务，ReAct 的逐步决策容易偏离目标。Plan-and-Execute 先由 Planner LLM 生成完整计划，再由 Executor 逐步执行，更适合复杂的多步骤任务。&lt;/p&gt;&lt;pre&gt;from&amp;nbsp;langgraph.prebuilt&amp;nbsp;import&amp;nbsp;create_react_agent
from&amp;nbsp;langgraph.graph&amp;nbsp;import&amp;nbsp;StateGraph

#&amp;nbsp;规划节点：生成任务计划
def&amp;nbsp;planner(state):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;plan&amp;nbsp;=&amp;nbsp;llm.invoke(f&amp;quot;将以下目标分解为详细步骤：{state[&amp;#39;goal&amp;#39;]}&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;plan&amp;quot;:&amp;nbsp;plan,&amp;nbsp;&amp;quot;steps&amp;quot;:&amp;nbsp;parse_steps(plan)}

#&amp;nbsp;执行节点：逐步执行
def&amp;nbsp;executor(state):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;current_step&amp;nbsp;=&amp;nbsp;state[&amp;quot;steps&amp;quot;][state[&amp;quot;current_idx&amp;quot;]]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result&amp;nbsp;=&amp;nbsp;agent.invoke(current_step)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{&amp;quot;results&amp;quot;:&amp;nbsp;state[&amp;quot;results&amp;quot;]&amp;nbsp;+&amp;nbsp;[result]}

graph&amp;nbsp;=&amp;nbsp;StateGraph()
graph.add_node(&amp;quot;planner&amp;quot;,&amp;nbsp;planner)
graph.add_node(&amp;quot;executor&amp;quot;,&amp;nbsp;executor)&lt;/pre&gt;&lt;h3&gt;2.3 Multi-Agent 范式&lt;/h3&gt;&lt;p&gt;当任务需要多个专业角色协作时，Multi-Agent 架构能够显著提升质量和效率。典型的模式包括：Supervisor + Worker、Peer-to-Peer 协作、以及流水线式的 Pipeline。&lt;/p&gt;&lt;h2&gt;三、2025 年主流框架横向评测&lt;/h2&gt;&lt;p&gt;下面从开发体验、生产稳定性、调试能力、社区活跃度四个维度对主流框架进行对比：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;LangGraph&lt;/strong&gt;：图结构状态机，可视化流程清晰，适合复杂多节点工作流，LangSmith 追踪能力强，推荐生产优先选择&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;AutoGen&lt;/strong&gt;：微软出品，Multi-Agent 对话框架，代码执行能力优秀，适合代码生成类任务，但配置较复杂&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;CrewAI&lt;/strong&gt;：角色扮演式多智能体，上手极快，适合快速原型，生产稳定性相对较弱&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;LlamaIndex Workflows&lt;/strong&gt;：以 RAG 为核心扩展，知识密集型任务表现出色，工具生态丰富&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Semantic Kernel&lt;/strong&gt;：微软企业级方案，.NET/Python 双语言，与 Azure OpenAI 深度集成&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;选型建议：如果你的团队熟悉 Python 且任务流程复杂，优先考虑 LangGraph；如果主要是代码生成/执行任务，AutoGen 是更好的选择；快速验证 POC 用 CrewAI 效率最高。&lt;/p&gt;&lt;h2&gt;四、生产部署的关键挑战与解决方案&lt;/h2&gt;&lt;p&gt;将 AI Agent 从 Demo 推向生产，需要应对几个核心挑战：&lt;/p&gt;&lt;h3&gt;4.1 可靠性：工具调用失败与重试策略&lt;/h3&gt;&lt;p&gt;Agent 在生产环境中会遇到网络超时、API 限频、工具返回异常等问题。合理的重试策略和降级方案是必须的。&lt;/p&gt;&lt;pre&gt;import&amp;nbsp;tenacity

@tenacity.retry(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stop=tenacity.stop_after_attempt(3),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;wait=tenacity.wait_exponential(multiplier=1,&amp;nbsp;min=2,&amp;nbsp;max=10),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;retry=tenacity.retry_if_exception_type(Exception)
)
def&amp;nbsp;resilient_tool_call(tool_name:&amp;nbsp;str,&amp;nbsp;params:&amp;nbsp;dict):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;带重试的工具调用封装&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result&amp;nbsp;=&amp;nbsp;tool_registry[tool_name](**params)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;result
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;RateLimitError:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;降级：返回缓存结果或空响应
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;get_cached_result(tool_name,&amp;nbsp;params)&lt;/pre&gt;&lt;h3&gt;4.2 成本控制：Token 用量优化&lt;/h3&gt;&lt;p&gt;Agent 的 Token 消耗远高于普通对话，主要来源包括：系统提示词（每次请求都携带）、历史消息积累、工具返回内容过长。优化方向：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;使用滑动窗口裁剪历史消息，保留最近 N 轮 + 摘要&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;工具返回内容超过 2000 Token 时自动截断并附加摘要&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;用小模型（如 gpt-4o-mini）处理简单判断，大模型只处理核心推理&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;对高频相似查询启用语义缓存（Semantic Cache）&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;4.3 可观测性：追踪与调试&lt;/h3&gt;&lt;p&gt;Agent 的决策链路复杂，传统日志难以满足调试需求。推荐接入 LangSmith 或 Arize Phoenix 进行全链路追踪，记录每次 LLM 调用的输入输出、工具调用序列、耗时和费用。&lt;/p&gt;&lt;pre&gt;from&amp;nbsp;langsmith&amp;nbsp;import&amp;nbsp;Client
import&amp;nbsp;os

os.environ[&amp;quot;LANGCHAIN_TRACING_V2&amp;quot;]&amp;nbsp;=&amp;nbsp;&amp;quot;true&amp;quot;
os.environ[&amp;quot;LANGCHAIN_PROJECT&amp;quot;]&amp;nbsp;=&amp;nbsp;&amp;quot;prod-agent-v2&amp;quot;

#&amp;nbsp;所有&amp;nbsp;LangChain/LangGraph&amp;nbsp;调用自动上报到&amp;nbsp;LangSmith
#&amp;nbsp;可在&amp;nbsp;UI&amp;nbsp;中查看完整的推理链路&lt;/pre&gt;&lt;h2&gt;五、实战案例：构建代码审查 Agent&lt;/h2&gt;&lt;p&gt;以一个实际落地的代码审查 Agent 为例，展示完整的架构设计思路。该 Agent 能够自动分析 GitHub PR，识别潜在 Bug、安全漏洞和性能问题，并生成结构化审查报告。&lt;/p&gt;&lt;pre&gt;from&amp;nbsp;langgraph.graph&amp;nbsp;import&amp;nbsp;StateGraph,&amp;nbsp;END
from&amp;nbsp;typing&amp;nbsp;import&amp;nbsp;TypedDict,&amp;nbsp;List

class&amp;nbsp;ReviewState(TypedDict):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pr_url:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;diff:&amp;nbsp;str
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;security_issues:&amp;nbsp;List[str]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;perf_issues:&amp;nbsp;List[str]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;final_report:&amp;nbsp;str

def&amp;nbsp;fetch_pr_diff(state:&amp;nbsp;ReviewState)&amp;nbsp;-&amp;gt;&amp;nbsp;ReviewState:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;获取&amp;nbsp;PR&amp;nbsp;的代码变更&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;diff&amp;nbsp;=&amp;nbsp;github_client.get_pr_diff(state[&amp;quot;pr_url&amp;quot;])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{**state,&amp;nbsp;&amp;quot;diff&amp;quot;:&amp;nbsp;diff}

def&amp;nbsp;security_review(state:&amp;nbsp;ReviewState)&amp;nbsp;-&amp;gt;&amp;nbsp;ReviewState:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;安全漏洞检测&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;prompt&amp;nbsp;=&amp;nbsp;f&amp;quot;&amp;quot;&amp;quot;分析以下代码变更，找出潜在的安全问题：
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{state[&amp;#39;diff&amp;#39;]}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;重点关注：SQL注入、XSS、敏感信息硬编码、权限校验缺失&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;issues&amp;nbsp;=&amp;nbsp;security_llm.invoke(prompt)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{**state,&amp;nbsp;&amp;quot;security_issues&amp;quot;:&amp;nbsp;parse_issues(issues)}

def&amp;nbsp;performance_review(state:&amp;nbsp;ReviewState)&amp;nbsp;-&amp;gt;&amp;nbsp;ReviewState:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;性能问题检测&amp;quot;&amp;quot;&amp;quot;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;prompt&amp;nbsp;=&amp;nbsp;f&amp;quot;分析代码变更中的性能问题，包括&amp;nbsp;N+1&amp;nbsp;查询、未使用的变量、低效算法：\n{state[&amp;#39;diff&amp;#39;]}&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;issues&amp;nbsp;=&amp;nbsp;perf_llm.invoke(prompt)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{**state,&amp;nbsp;&amp;quot;perf_issues&amp;quot;:&amp;nbsp;parse_issues(issues)}

def&amp;nbsp;generate_report(state:&amp;nbsp;ReviewState)&amp;nbsp;-&amp;gt;&amp;nbsp;ReviewState:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;生成最终审查报告&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;report&amp;nbsp;=&amp;nbsp;report_llm.invoke({
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;security&amp;quot;:&amp;nbsp;state[&amp;quot;security_issues&amp;quot;],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;performance&amp;quot;:&amp;nbsp;state[&amp;quot;perf_issues&amp;quot;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;})
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;{**state,&amp;nbsp;&amp;quot;final_report&amp;quot;:&amp;nbsp;report}

#&amp;nbsp;构建并行审查图
workflow&amp;nbsp;=&amp;nbsp;StateGraph(ReviewState)
workflow.add_node(&amp;quot;fetch&amp;quot;,&amp;nbsp;fetch_pr_diff)
workflow.add_node(&amp;quot;security&amp;quot;,&amp;nbsp;security_review)
workflow.add_node(&amp;quot;performance&amp;quot;,&amp;nbsp;performance_review)
workflow.add_node(&amp;quot;report&amp;quot;,&amp;nbsp;generate_report)

#&amp;nbsp;安全和性能审查并行执行
workflow.add_edge(&amp;quot;fetch&amp;quot;,&amp;nbsp;&amp;quot;security&amp;quot;)
workflow.add_edge(&amp;quot;fetch&amp;quot;,&amp;nbsp;&amp;quot;performance&amp;quot;)
workflow.add_edge([&amp;quot;security&amp;quot;,&amp;nbsp;&amp;quot;performance&amp;quot;],&amp;nbsp;&amp;quot;report&amp;quot;)
workflow.add_edge(&amp;quot;report&amp;quot;,&amp;nbsp;END)

app&amp;nbsp;=&amp;nbsp;workflow.compile()&lt;/pre&gt;&lt;p&gt;该架构的关键设计决策：安全审查和性能审查并行执行，减少等待时间；各节点职责单一，便于独立测试和优化；通过 TypedDict 定义状态结构，避免数据传递错误。&lt;/p&gt;&lt;h2&gt;六、Agent 评估体系：如何量化效果&lt;/h2&gt;&lt;p&gt;Agent 的评估比普通模型更复杂，因为中间步骤的质量同样重要。推荐建立以下评估维度：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;任务完成率&lt;/strong&gt;：最终结果是否符合预期，这是最核心的指标&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;工具调用准确率&lt;/strong&gt;：选择正确工具的比例，以及参数填写的准确性&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;步骤效率&lt;/strong&gt;：完成任务平均需要多少步，越少越好（过多步骤意味着推理偏差）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;幻觉率&lt;/strong&gt;：Agent 是否会编造工具调用结果或虚构事实&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;成本效率&lt;/strong&gt;：每次任务完成的平均 Token 消耗和 API 费用&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;建议为每个 Agent 建立专属的黄金测试集（Gold Dataset），包含 50-100 个典型任务及其期望输出，在每次模型或提示词升级时运行回归测试，防止性能退化。&lt;/p&gt;&lt;h2&gt;七、未来趋势：2026 年 Agent 技术展望&lt;/h2&gt;&lt;p&gt;站在 2025 年底展望未来，AI Agent 领域还有几个方向值得重点关注：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;长上下文 Agent&lt;/strong&gt;：随着 Gemini 2.0 等模型将上下文窗口扩展到百万 Token，Agent 的记忆管理策略将发生根本性变化&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;多模态 Agent&lt;/strong&gt;：能够处理图像、视频、音频的 Agent 将开拓更广泛的应用场景&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Agent 协议标准化&lt;/strong&gt;：A2A（Agent-to-Agent）通信协议和 MCP（Model Context Protocol）的普及将推动 Agent 生态系统的互联互通&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;端侧 Agent&lt;/strong&gt;：借助 Apple Intelligence、Google Gemini Nano 等端侧模型，轻量 Agent 将在移动设备上获得更广泛部署&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;AI Agent 的核心价值在于「让 AI 替人完成有意义的工作」。技术框架只是工具，真正重要的是找准业务场景、设计可靠的系统架构、建立完善的评估体系。希望本文能为你的 Agent 落地之路提供一些实用的参考。&lt;/p&gt;</description><pubDate>Mon, 19 Oct 2026 08:08:28 +0800</pubDate></item><item><title>Laravel 11 实战指南：架构升级、Eloquent 优化与生产部署</title><link>https://blog.resmic.cn/post/387.html</link><description>&lt;p&gt;&lt;img src=&quot;https://blog.resmic.cn/zb_users/upload/2026/10/20261018080259179228177972219.jpg&quot; alt=&quot;封面&quot; style=&quot;width:100%;&quot;&gt;&lt;/p&gt;

&lt;h2&gt;为什么选择 Laravel 作为 PHP 开发首选框架&lt;/h2&gt;
&lt;p&gt;在众多 PHP 框架中，Laravel 凭借其优雅的语法、强大的生态系统和活跃的社区，成为全球最受欢迎的 PHP 框架之一。无论是快速构建 API、开发全栈 Web 应用，还是搭建微服务架构，Laravel 都提供了开箱即用的解决方案。&lt;/p&gt;
&lt;p&gt;根据 JetBrains 2024 年开发者调查，Laravel 在 PHP 框架使用率榜单中持续占据首位，超过 60% 的 PHP 开发者在日常项目中使用 Laravel。这一数字背后，是 Laravel 在开发效率、安全性、可维护性三个维度的持续领先。&lt;/p&gt;

&lt;h2&gt;Laravel 11 核心架构升级亮点&lt;/h2&gt;
&lt;p&gt;Laravel 11 于 2024 年 3 月正式发布，带来了一系列重要的架构优化，让项目结构更加简洁清晰。&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;精简默认项目结构&lt;/strong&gt;：移除了大量之前默认存在但多数项目不需要的文件，新项目目录更加干净，核心文件减少约 40%&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;统一配置入口&lt;/strong&gt;：新的 bootstrap/app.php 统一了中间件、服务提供者和路由的注册方式，告别分散在多个文件的配置&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;健康检查路由&lt;/strong&gt;：内置 /up 路由，为容器化部署和云平台健康检查提供标准化端点&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;每分钟速率限制&lt;/strong&gt;：队列处理器新增每分钟速率限制支持，更精细地控制任务执行频率&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Reverb WebSocket 服务器&lt;/strong&gt;：官方推出的 Laravel Reverb，为实时功能提供高性能 WebSocket 解决方案，无需依赖第三方服务&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些改进并非简单的功能堆砌，而是 Laravel 团队深度思考开发者痛点后的精心设计。精简的项目结构降低了新团队成员的认知负担，让代码审查更加高效。&lt;/p&gt;

&lt;h2&gt;Eloquent ORM 最佳实践：避免 N+1 查询陷阱&lt;/h2&gt;
&lt;p&gt;Eloquent ORM 是 Laravel 最强大的特性之一，但也是性能问题的高发区。N+1 查询问题是大多数 Laravel 应用性能瓶颈的根源。理解并掌握预加载（Eager Loading）机制，是每位 Laravel 开发者的必修课。&lt;/p&gt;
&lt;p&gt;常见的 N+1 问题场景：查询用户列表时，对每个用户再执行一次查询获取关联的订单数据。如果有 100 个用户，就会产生 101 次数据库查询。解决方案是使用 with() 方法进行预加载，将 101 次查询压缩为 2 次。&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;预加载关联&lt;/strong&gt;：使用 with(['orders', 'profile']) 一次性加载所有需要的关联数据&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;条件预加载&lt;/strong&gt;：with(['orders' =&gt; function($query){ $query-&gt;where('status', 'paid'); }]) 过滤关联数据&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;懒预加载&lt;/strong&gt;：对已加载的集合使用 loadMissing() 补充缺失的关联&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;计数预加载&lt;/strong&gt;：withCount('orders') 获取关联数量而不加载全部数据，大幅减少内存占用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;推荐在开发环境启用 Telescope 或 Debugbar 工具，实时监控每个请求的查询次数和耗时。将查询次数控制在个位数是高性能 Laravel 应用的基本要求。&lt;/p&gt;

&lt;h2&gt;Laravel 队列系统：异步处理的正确姿势&lt;/h2&gt;
&lt;p&gt;队列系统是构建高响应性 Web 应用的核心工具。将耗时操作（发送邮件、生成报表、调用第三方 API）从请求生命周期中剥离，能将 API 响应时间从秒级降低到毫秒级。&lt;/p&gt;
&lt;p&gt;Laravel 队列支持多种驱动：数据库队列适合中小型应用，零额外依赖；Redis 队列性能更高，适合高并发场景；Amazon SQS 等云队列服务适合企业级部署。选择合适的驱动需要综合考虑团队的运维能力和业务规模。&lt;/p&gt;
&lt;p&gt;队列设计的关键原则包括：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;幂等性&lt;/strong&gt;：任务必须支持重复执行，网络故障或重试不应导致数据重复&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;合理的重试策略&lt;/strong&gt;：设置最大重试次数和退避时间，避免一直重试消耗资源&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;任务拆分&lt;/strong&gt;：将复杂任务拆分为多个小任务，利用 Job Chaining 或 Job Batching 编排执行顺序&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;监控告警&lt;/strong&gt;：使用 Laravel Horizon 监控队列吞吐量和失败率，配置告警及时发现问题&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;生产环境部署：容器化与性能优化&lt;/h2&gt;
&lt;p&gt;将 Laravel 应用部署到生产环境，性能优化是绕不开的话题。正确的配置可以让应用性能提升 3 到 5 倍。&lt;/p&gt;
&lt;p&gt;以下是生产环境必做的优化项：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;配置缓存&lt;/strong&gt;：执行 config:cache 将所有配置文件合并为单个缓存文件，消除每次请求读取配置的开销&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;路由缓存&lt;/strong&gt;：执行 route:cache 预编译路由表，大型应用路由解析速度提升显著&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;视图缓存&lt;/strong&gt;：执行 view:cache 预编译所有 Blade 模板，避免运行时编译开销&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;自动加载优化&lt;/strong&gt;：Composer 的 optimize-autoloader 选项生成优化的类映射文件&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;OPcache 配置&lt;/strong&gt;：PHP OPcache 是最廉价的性能提升手段，正确配置后 PHP 代码执行速度提升 2 至 3 倍&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;容器化部署方面，推荐使用多阶段构建优化镜像体积，将 PHP-FPM 和 Nginx 分别部署在不同容器中，通过 Kubernetes 或 Docker Swarm 实现弹性伸缩。结合 Laravel Octane（基于 Swoole 或 RoadRunner），可以进一步将吞吐量提升 5 到 10 倍。&lt;/p&gt;
&lt;p&gt;Laravel 生态的成熟度和社区活力，使其成为构建可靠 PHP 应用的最佳选择。无论是初创团队的快速原型开发，还是大型企业的复杂业务系统，Laravel 都提供了足够的工具和最佳实践。掌握本文介绍的核心技能，将帮助你构建更高效、更易维护的 PHP 应用。&lt;/p&gt;</description><pubDate>Sun, 18 Oct 2026 08:06:07 +0800</pubDate></item><item><title>PHP 8.3 新特性实战：类型化常量、json_validate 与 Randomizer 完全解析</title><link>https://blog.resmic.cn/post/386.html</link><description>&lt;p&gt;&lt;img src=&quot;https://blog.resmic.cn/zb_users/upload/2026/10/20261017080234179219535490932.jpg&quot; alt=&quot;封面&quot; style=&quot;width:100%;&quot;/&gt;&lt;/p&gt;&lt;h2&gt;一、PHP 8.3 新特性概览&lt;/h2&gt;&lt;p&gt;PHP 8.3 于 2023 年 11 月正式发布，作为 PHP 8.x 系列的最新版本，它在性能、类型系统和内置函数方面带来了多项重要改进。对于正在使用 PHP 8.0/8.1/8.2 的开发者来说，升级到 8.3 是一次值得的投资。&lt;/p&gt;&lt;p&gt;本文将聚焦于以下几个核心新特性，并结合实际业务场景给出代码示例：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;类型化类常量（Typed Class Constants）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;只读属性在类中的增强（Readonly Amendments）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;json_validate()&lt;/code&gt; 函数&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;Randomizer&lt;/code&gt; 类新方法&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;动态类常量获取语法&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;二、类型化类常量&lt;/h2&gt;&lt;p&gt;在 PHP 8.3 之前，类常量没有类型声明，这在大型项目中容易引起歧义。8.3 正式引入了类型化常量，让代码更健壮、IDE 支持更完善。&lt;/p&gt;&lt;pre&gt;&amp;lt;?php

interface&amp;nbsp;HasVersion&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;string&amp;nbsp;VERSION&amp;nbsp;=&amp;nbsp;&amp;#39;1.0.0&amp;#39;;
}

class&amp;nbsp;Config&amp;nbsp;implements&amp;nbsp;HasVersion&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;string&amp;nbsp;VERSION&amp;nbsp;=&amp;nbsp;&amp;#39;2.5.1&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;int&amp;nbsp;MAX_RETRY&amp;nbsp;=&amp;nbsp;3;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;float&amp;nbsp;TIMEOUT&amp;nbsp;=&amp;nbsp;30.5;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;bool&amp;nbsp;DEBUG&amp;nbsp;=&amp;nbsp;false;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;array&amp;nbsp;DEFAULT_HEADERS&amp;nbsp;=&amp;nbsp;[&amp;#39;Content-Type&amp;#39;&amp;nbsp;=&amp;gt;&amp;nbsp;&amp;#39;application/json&amp;#39;];
}

echo&amp;nbsp;Config::VERSION;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;2.5.1
echo&amp;nbsp;Config::MAX_RETRY;&amp;nbsp;//&amp;nbsp;3&lt;/pre&gt;&lt;p&gt;类型化常量会在赋值时进行类型检查，如果类型不匹配会抛出 &lt;code&gt;TypeError&lt;/code&gt;。支持所有标量类型：&lt;code&gt;string&lt;/code&gt;、&lt;code&gt;int&lt;/code&gt;、&lt;code&gt;float&lt;/code&gt;、&lt;code&gt;bool&lt;/code&gt;、&lt;code&gt;array&lt;/code&gt;，以及 &lt;code&gt;null&lt;/code&gt;、&lt;code&gt;self&lt;/code&gt;、接口和枚举类型。&lt;/p&gt;&lt;p&gt;在继承关系中，子类的常量类型必须与父类兼容，否则会抛出编译错误，这有助于在大型项目中维护接口契约的一致性。&lt;/p&gt;&lt;h2&gt;三、json_validate() 函数&lt;/h2&gt;&lt;p&gt;以前验证 JSON 字符串是否合法，开发者通常需要这样写：&lt;/p&gt;&lt;pre&gt;&amp;lt;?php

//&amp;nbsp;PHP&amp;nbsp;8.3&amp;nbsp;之前的方式
function&amp;nbsp;isValidJson(string&amp;nbsp;$str):&amp;nbsp;bool&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;json_decode($str);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;json_last_error()&amp;nbsp;===&amp;nbsp;JSON_ERROR_NONE;
}

//&amp;nbsp;问题：json_decode&amp;nbsp;会完整解析并分配内存，对大型&amp;nbsp;JSON&amp;nbsp;有性能损耗
$result&amp;nbsp;=&amp;nbsp;isValidJson(&amp;#39;{&amp;quot;name&amp;quot;:&amp;quot;Alice&amp;quot;,&amp;quot;age&amp;quot;:30}&amp;#39;);&lt;/pre&gt;&lt;p&gt;PHP 8.3 引入了 &lt;code&gt;json_validate()&lt;/code&gt;，它只做验证而不解析，对于只需要检查格式合法性的场景，性能大幅提升：&lt;/p&gt;&lt;pre&gt;&amp;lt;?php

//&amp;nbsp;PHP&amp;nbsp;8.3&amp;nbsp;新方式
$valid&amp;nbsp;=&amp;nbsp;json_validate(&amp;#39;{&amp;quot;name&amp;quot;:&amp;quot;Alice&amp;quot;,&amp;quot;age&amp;quot;:30}&amp;#39;);&amp;nbsp;//&amp;nbsp;true
$invalid&amp;nbsp;=&amp;nbsp;json_validate(&amp;#39;{name:&amp;nbsp;Alice}&amp;#39;);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;false

//&amp;nbsp;支持深度限制和&amp;nbsp;flags
$deep&amp;nbsp;=&amp;nbsp;json_validate($jsonString,&amp;nbsp;depth:&amp;nbsp;512);

//&amp;nbsp;实际应用：API&amp;nbsp;参数校验
function&amp;nbsp;validateApiPayload(string&amp;nbsp;$body):&amp;nbsp;void&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(!json_validate($body))&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;\InvalidArgumentException(&amp;#39;请求体不是合法的&amp;nbsp;JSON&amp;nbsp;格式&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;实测在处理大型 JSON 字符串（如 100KB+）时，&lt;code&gt;json_validate()&lt;/code&gt; 比 &lt;code&gt;json_decode()&lt;/code&gt; + &lt;code&gt;json_last_error()&lt;/code&gt; 的方式快约 40%，内存占用更低。&lt;/p&gt;&lt;h2&gt;四、Randomizer 类新方法&lt;/h2&gt;&lt;p&gt;PHP 8.2 引入了 &lt;code&gt;Random\Randomizer&lt;/code&gt; 类，8.3 为其增加了几个实用方法：&lt;/p&gt;&lt;pre&gt;&amp;lt;?php

use&amp;nbsp;Random\Randomizer;

$rand&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Randomizer();

//&amp;nbsp;getBytesFromString：从指定字符集中随机取&amp;nbsp;N&amp;nbsp;个字节
//&amp;nbsp;非常适合生成验证码、随机&amp;nbsp;Token
$captcha&amp;nbsp;=&amp;nbsp;$rand-&amp;gt;getBytesFromString(&amp;#39;ABCDEFGHJKLMNPQRSTUVWXYZ23456789&amp;#39;,&amp;nbsp;6);
echo&amp;nbsp;$captcha;&amp;nbsp;//&amp;nbsp;例：K7RX2M

//&amp;nbsp;生成安全的&amp;nbsp;API&amp;nbsp;Key
$apiKey&amp;nbsp;=&amp;nbsp;$rand-&amp;gt;getBytesFromString(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;abcdefghijklmnopqrstuvwxyz0123456789&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;32
);

//&amp;nbsp;getFloat：生成指定范围内的浮点数（PHP&amp;nbsp;8.3&amp;nbsp;新增）
$price&amp;nbsp;=&amp;nbsp;$rand-&amp;gt;getFloat(10.0,&amp;nbsp;99.99);
echo&amp;nbsp;round($price,&amp;nbsp;2);&amp;nbsp;//&amp;nbsp;例：47.23

//&amp;nbsp;nextFloat：生成&amp;nbsp;[0.0,&amp;nbsp;1.0)&amp;nbsp;之间的浮点数
$probability&amp;nbsp;=&amp;nbsp;$rand-&amp;gt;nextFloat();
echo&amp;nbsp;$probability;&amp;nbsp;//&amp;nbsp;例：0.73842...&lt;/pre&gt;&lt;p&gt;&lt;code&gt;getBytesFromString&lt;/code&gt; 的出现解决了之前用 &lt;code&gt;str_split&lt;/code&gt; + &lt;code&gt;array_rand&lt;/code&gt; 生成随机字符串时存在的分布不均问题，使用密码学安全的随机源，适合安全敏感场景。&lt;/p&gt;&lt;h2&gt;五、动态类常量获取与迁移建议&lt;/h2&gt;&lt;p&gt;PHP 8.3 允许通过变量动态获取类常量，语法更简洁：&lt;/p&gt;&lt;pre&gt;&amp;lt;?php

class&amp;nbsp;Status&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;string&amp;nbsp;ACTIVE&amp;nbsp;=&amp;nbsp;&amp;#39;active&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;string&amp;nbsp;INACTIVE&amp;nbsp;=&amp;nbsp;&amp;#39;inactive&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;string&amp;nbsp;PENDING&amp;nbsp;=&amp;nbsp;&amp;#39;pending&amp;#39;;
}

//&amp;nbsp;动态获取常量（PHP&amp;nbsp;8.3）
$key&amp;nbsp;=&amp;nbsp;&amp;#39;ACTIVE&amp;#39;;
echo&amp;nbsp;Status::{$key};&amp;nbsp;//&amp;nbsp;active（等同于&amp;nbsp;Status::ACTIVE）

//&amp;nbsp;结合枚举使用
enum&amp;nbsp;Color:&amp;nbsp;string&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;Red&amp;nbsp;=&amp;nbsp;&amp;#39;#FF0000&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;Green&amp;nbsp;=&amp;nbsp;&amp;#39;#00FF00&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;Blue&amp;nbsp;=&amp;nbsp;&amp;#39;#0000FF&amp;#39;;
}

$colorName&amp;nbsp;=&amp;nbsp;&amp;#39;Red&amp;#39;;
echo&amp;nbsp;Color::{$colorName}-&amp;gt;value;&amp;nbsp;//&amp;nbsp;#FF0000&lt;/pre&gt;&lt;p&gt;在考虑升级到 PHP 8.3 时，需注意以下几点：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;检查项目中是否有覆盖父类常量但类型不一致的情况&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;确认 Composer 依赖包是否已支持 PHP 8.3（运行 &lt;code&gt;composer check-platform-reqs&lt;/code&gt;）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;使用 &lt;code&gt;rector/rector&lt;/code&gt; 工具自动化迁移部分代码&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;在 CI 流程中增加 PHP 8.3 的测试矩阵&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;关注官方废弃通知（Deprecations），为将来的 PHP 9.0 做准备&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;总体来说，PHP 8.3 是一次稳健的升级，新特性实用性强，向后兼容性好，推荐在做好测试的前提下积极迁移。&lt;/p&gt;</description><pubDate>Sat, 17 Oct 2026 08:02:55 +0800</pubDate></item></channel></rss>