<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>性能优化 on 山行小记</title>
    <link>https://ruijingan.pages.dev/tags/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/</link>
    <description>Recent content in 性能优化 on 山行小记</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <copyright>@2025</copyright>
    <lastBuildDate>Tue, 06 Nov 2018 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://ruijingan.pages.dev/tags/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>RecyclerView 卡顿排查的几个套路</title>
      <link>https://ruijingan.pages.dev/posts/2018/recyclerview-perf/</link>
      <pubDate>Tue, 06 Nov 2018 00:00:00 +0000</pubDate>
      <guid>https://ruijingan.pages.dev/posts/2018/recyclerview-perf/</guid>
      <description>&lt;p&gt;最近接手了一个商品列表页，产品反馈&amp;quot;滑动的时候有一点点卡，但说不清楚哪里卡&amp;quot;。这种模糊的需求最难办，记录一下我的排查过程，下次遇到可以直接翻这篇。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第一步永远是先量化，不要靠手感。&lt;/strong&gt; 打开开发者选项里的 GPU 渲染模式，或者直接接 Systrace 看帧耗时。我们的情况是滚动时偶发 30ms+ 的帧，但不是每一帧都卡。这种偶发型卡顿，&lt;code&gt;onCreateViewHolder&lt;/code&gt; 的嫌疑最大。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;然后按嫌疑大小逐个排除：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;onBindViewHolder&lt;/code&gt; 里有没有做 IO？我们的问题就出在这——图片文案里的表情包配置是从 SharedPreferences 同步读的，第一次滚动到该位置时阻塞了主线程。改成启动时预加载到内存就好了。&lt;/li&gt;
&lt;li&gt;item 布局层级是否太深。用 Layout Inspector 看了下，我们最深的一层嵌套了 7 层，把多余的 LinearLayout 换成 ConstraintLayout 之后测量耗时明显下降。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;setHasFixedSize(true)&lt;/code&gt; 加了吗？数据变化不改变 item 高度的话，加上能省一次全量布局。&lt;/li&gt;
&lt;li&gt;DiffUtil 用了没？我们还在用 &lt;code&gt;notifyDataSetChanged()&lt;/code&gt;，全量刷新导致大量无意义重绘，换成 DiffUtil 后滑动顺滑了一个档次。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;最后一个不算套路的心得：&lt;strong&gt;别过早优化&lt;/strong&gt;。上面这些做完之后帧耗时稳定在 16ms 以内了，我本来还想上 RecyclerView 的 prefetch 调参，试了下收益几乎为零，就回滚了。性能优化到&amp;quot;感知不到卡&amp;quot;就该停手，剩下的时间是业务的时间。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
