前言
本文接上文 编写极简抖音的难点|青训营笔记 - 掘金 (juejin.cn),继续阐述我们在编写极简抖音期间进行优化的点。
对一个项目进行优化的时候,首先我们需要去检测项目中有什么需要优化的点。这时我们便需要使用到性能分析工具来对APP的各项性能进行检测,在本文中使用到的性能分析工具是 Dokit 。
下面我将罗列出几项我在项目中发现的可优化点,以及其优化方案。
初次启动白屏
由于APP启动的时候需要先启动 Application
进行初始化,在这个期间,会带来一个短暂的白屏展示,而这个白屏会给用户带来一个卡顿的感觉。
我们需要把白屏变成图案,这样子用户启动的时候就不会是看到一片空白。我使用到的方案是新建一个 SplashActivity
,让其来充当一个启动页。
我们要解决以下几点问题:
- 如何让未展示到
SplashActivity
的界面的时候,其背景就已经是我们需要设置的图案了 SplashActivity
如何有效降低内存占用
首先,第一个问题,我们需要设置对应的主题,因为 Activity
在未加载绑定的布局资源的时候,会先加载主题文件,所以我们修改主题文件就可以把对应的白屏变为我们想要的启动页了
下面展示我的相关代码
<!--res/drawable/splash_bg.xml--> <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <item> <shape android:shape="rectangle"> <solid android:color="@color/white" /> </shape> </item> <item android:gravity="center" android:drawable="@drawable/potato" /> </layer-list> 复制代码
<!--AndroidManifest.xml--> <activity android:name=".module.mine.activity.SplashActivity" android:exported="true" android:theme="@style/SplashTheme" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> 复制代码
//SplashActivity.java public class SplashActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash); ActivityUtil.startActivity(HomeActivity.class, true); } } 复制代码
像上方这样子设置后,我们在启动的时候,就可以直接看到我们的启动页了
ViewPage2预加载带来的多次请求
当我们使用到 ViewPage2
去做一些 fragment
的加载的时候,我们有需求让滑动到对应的位置的时候才进行页面的加载,并且滑动回去的时候不再进行加载。
但是 ViewPage
本身就预设定了会进行预加载,我们无法对其预加载做一个禁止。所以要完成我们的业务,我们可以对 Fragment
做一个懒加载,就是在加载的时候,预先加载布局,但是不加载数据。
// 关闭预加载 getBinding().viewPager2.setOffscreenPageLimit(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT); // 可以不设置 因为默认是 -1 默认不进行预加载 // 这个必须设置 不然仍然会启用预加载 ((RecyclerView)getBinding().viewPager2.getChildAt(0)).getLayoutManager().setItemPrefetchEnabled(false); // 设置缓存数量,对应 RecyclerView 中的 mCachedViews,即屏幕外的视图数量,此处设置为2 ((RecyclerView)getBinding().viewPager2.getChildAt(0)).setItemViewCacheSize(2); 复制代码
使用上述的代码,就可以让 ViewPage
页面进行懒加载,并且会对之前加载的页面进行一定数量的缓存
布局层过多,导致页面绘制压力大
在此,我们容易看到,APP 的UI层级普遍过高,这是由于使用线性布局等,会带来层级过多的问题,这会导致App显示的时候需要渲染的次数也多,这也直接导致了 APP 的性能问题。譬如在启动一个 Activity
,或者页面有动画的时候,会看到帧率明显降低,并且会导致 APP 出现明显的卡顿。
我的解决方案是,选用约束布局,当我们的页面比较复杂的时候,选用约束布局会使得我们的布局层数可以明显的减低。关于约束布局的学习,我们可以查看这篇文章 最全面的ConstraintLayout教程 (qq.com)
WebView的启动耗时以及内存占用
当我们使用 WebView 的时候,我们一般会给其单开一个进程,这样子 WebView
也就不会影响到我们的主进程。由于 WebView
容易发生内存泄露,所以它会有相对大的崩溃可能性,所以我们为其单开一个进程,提高 App 可使用的内存并且不影响主进程的使用。
但是这也产生一个问题,那就是新开一个进程的时候,会去重新执行一次 Application
,会导致第一次开启新的进程时候会有较久的白屏
解决方案:
- 优化
Applicaiton
中对各种类型资源的加载,对相关的进程只做必要额加载 - 多进程的开启不放到需要跳转时候才开启,对进程进行一个预加载