Unity包体积优化实践

news2024/11/25 20:40:29

目录

  • 简述
  • 优化前
  • 优化中
    • assets目录
      • 资源ab包动态下发
      • 资源大小优化
      • dll大小优化
      • 场景模型动态下载和加载
      • 优化assets目录后大小
    • lib目录
      • 优化目标架构
      • 裁剪代码
      • 优化代码和引用
    • 其他优化项
      • Shader优化
      • Release模式
      • 编译选项
  • 优化后

简述

在移动端App混合Unity开发的项目中,Unity的包体增量一直是一个被严格把控的关卡,包体积增量太大估计老板都直接不给上Unity了,因此Unity移动端的包体积优化尤为重要。由于混合开发中Unity部分的优化和Unity独立App的优化手段差不多,这里就以Android独立App项目为例,实践一波包体积优化。

优化前

我未做任何优化在Unity里直接打一个Apk出来,可以借用工具例如Android Studio查看Apk的大小和具体构成,供我们分析,可以看到,这个Apk大小为107.9MB,我们看看它的组成
在这里插入图片描述

可以看到,assets目录是占最大的,其次是lib目录,而dex相关文件只占很小部分。我们先看看这三个部分代表的什么:

  • assets目录:我们先看看assets目录包含什么东西
    在这里插入图片描述
    其中TestData和AssetsBundles目录都是我工程里放在StreamingAssets目录下的子目录,里面包含了资源,看来是被原封不动地放到了这里。而这个bin目录是什么呢?点进去看
    在这里插入图片描述
    可以看到包含了一大堆dll文件,原封不动地放到了这里,除此之外还包含了一些Resources和其他引用到的资源,图中没显示全,assest目录就大概包含了以上这些内容

  • lib目录:我们再看看lib目录下,可以看到右armeabi-v7a的文件夹,但是没有arm64的文件夹

    可以看到,里面包含了各种用到的so库

  • classes.dex文件:这个主要是java的代码,占比很小,可以忽略不计

优化中

assets目录

我们首先从assets目录的大小开始优化,从上面的分析得知,我们StreamingAssets目录下的资源和Resources目录的资源和其他引用的资源都放在了这个目录下,因此我们先对这个资源进行优化

资源ab包动态下发

我们把相关的资源改为动态加载的方式,全部打成ab包,放到cdn上动态下发,在运行时再去加载,我们用Android Studio自带的Apk大小比较工具看看效果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lzqpxeK3-1688546364593)(/tencent/api/attachments/s3/url?attachmentid=3027548)]

可以看到Apk只剩60.4MB了,减小了47.6M,几乎所有的集中在assets目录,还有极小部分减小在META-INF目录。其实大部分项目进行包体积优化的最大优化部分都是资源优化,所以几乎所有的移动端项目都会使用ab包动态下发的方式进行资源的包体积优化。

资源大小优化

如果还有部分资源是需要直接嵌入在Apk里的,也可以进行资源的压缩,资源大小主要是模型和贴图,模型可以通过减面和更换低模进行优化,贴图也可以通过各种手段进行优化,最简单的方式是在Unity里进行各个贴图分辨率控制和贴图压缩,还有贴图的合并图集等。虽然我们大部分资源都使用了ab包动态下发的方式,但是ab包里的资源也可以先优化之后再打ab包,减小ab包的大小和增强运行时性能。在当前这个测试项目中,资源都通过ab包下载,因此这部分没有减小包体积,但对于那些不使用ab包动态下载的项目中就会变得非常有用

dll大小优化

目前生成了一大堆的dll,在assets占用了大量包体,我们继续去优化一下。这里其实是因为旧的mono编译方式会把C#代码编译为中间语言,使用默认的中等优化级别,生成的二进制代码相对较大,同时还包含一些跨平台的兼容性代码,导致生成的dll较大。这里我们采用最新的IL2CPP编译方式替代mono编译,IL2CPP编译器会进行更高级别的优化,将C#生成更紧凑的、高效的本机机器码,因此不需要额外的跨平台适配逻辑,可以减小包体积大小,以下是我们换成IL2CPP的大小(对比优化前):
在这里插入图片描述

可以看到在assets目录下有大幅度的减小,但是lib却大幅度增长,最终反而增长了12.6MB,达到了72.9M,明显不符合预期,这是为什么呢?其实是因为我们IL2CPP打包的时候,选择打了ARMv7和ARM64两个cpu架构的包,但在现在的手机市场中,一般情况我们选一种就可以了,我们只选择ARM64,再进行一次打包:
在这里插入图片描述

可以看到,大小从72.9MB降到了45.1MB。我们看看和mono方式的对比:
在这里插入图片描述

assets目录大幅度减小,lib目录增长,总包体积减小了-15.2MB(需要注意的是,APK大小是压缩后的数据,而里面目录的大小是没压缩前的数据)

场景模型动态下载和加载

前面我们做了一些基本的ab包加载,但当时做的只是和一些本来就需要动态下载的资源相关的事情,没把场景里放置的场景资源也放进去,现在我们采用所有场景资源都ab包动态下载和加载的方式,再次验证大小:

可以看到,assets目录再次减小,总包体积从45.1MB降到了36.3MB,这里没有细查项目中的所有资源,如果全部找出来处理掉,这里还能再小,但是由于剩下的这些资源在压缩到apk里后大小占比太小,这里就不做处理了

优化assets目录后大小

我们再看看以上这些步骤优化后,在压缩的apk包里,各部分的大小:
在这里插入图片描述

可以看到,assets目录已经只剩下5.9MB了。而lib目录依然占比较大。

lib目录

优化目标架构

其实前面已经对这里进行过优化了,我们去掉了ARMv7,只保留ARM64,就已经是优化了一半大小。

裁剪代码

在Unity的Player Settings中,选择"Player Settings",然后在"Other Settings"下的"Optimization"部分,勾选"Strip Engine Code"。这将删除未使用的引擎代码,减小.so文件的大小。请注意,这可能会导致某些功能的不可用性,因此在使用此选项之前,请确保测试应用程序的功能完整性。在我的测试项目中,开到了最大的裁剪幅度,然后出现了一些问题,解决后,apk大小再次降低:
在这里插入图片描述
这次减小到29MB了,lib目录甚至assets目录都在减小。

优化代码和引用

有时候我们代码里会引用很多第三方dll,我们需要了解这些dll我们是否必须引用,引用过多的dll肯定是会增加大小的,想查看引用的dll,我们在Unity Editor编译好Apk后,点击Unity Editor Console控制台的右上角三个点,然后选择Open Editor Log,找到类似以下的内容:
在这里插入图片描述

这样就可以查看我们引用的所有dll了,然后根据实际情况去处理,这里测试项目就不处理,因为这部分会花费不少时间,还需要注意会不会引入新的问题,如果引用不多,优化力度也不是很大。除此之外,我们还要优化我们自己编写的代码,尽量不要写无效代码。

其他优化项

Shader优化

我们刚刚已经打开了Editor Log,其实下面还有显示各部分占比大小,虽然不是很全面,但是我们也可以从中得知一些信息:
在这里插入图片描述

可以看到,我们的资源部分基本上没有任何占用了,但能看到Shaders还有一些占用,我们继续处理,这些shader实际上都是在工程里设置了always include shaders才引入的,有时候设置了但是又忘了去掉,又用不到,也会占用内存。我们根据实际情况做一下删减,我这里做一下删减,未压缩前的assets目录减少了2MB左右,但是压缩后几乎可以忽略不计,这里就补贴出图片了,项目里Shader很复杂的需要注意这里的优化就行了

Release模式

我们前面其实一直用的debug模式,我们开启一下release模式,然后选择Use R8再次再次编译,看看效果:
在这里插入图片描述

可以看到,优化的力度是非常大的,但是会增加编译时间,并且无法进行调试,所以平时开发时还是用debug模式,发布时记得改Release模式。

编译选项

我们在打包的时候,可以选择一些压缩配置,例如在Build窗口,我们可以改为以下两个配置:
在这里插入图片描述

我们再次进行打包验证,最终会变成以下大小:

优化后

我们最后总结一下以上各个步骤的优化情况:

初始大小部分资源ab包动态下发IL2CPP(只保留ARM64)全部资源打ab包裁剪代码Release模式编译压缩选项
107.9MB60.4MB45.1MB36.3MB29MB19.1MB17.4MB

到这里,我们基本上从107.9MB优化到了17.4MB,减小了80%多的包体大小。如果追求极限,还有进一步的优化空间,但也和这个差不了多少了,工作量却会大幅度增加,一般按照上面这些配置,已经能满足现在大部分工程的需要。并且如果是和移动端混合开发,还会配合使用移动端的一些优化方案,会进一步减小大小。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/722771.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VSCode配置C/C++环境(极简版)

预期结果: 首先安装扩展: 然后按照下面readme.txt中即可 链接:https://pan.baidu.com/s/16OV5Kr82i0gWCc4bvKs42g 提取码:zxcv

【模式识别目标检测】——模式识别技术车牌检测应用

目录 引入 一、模式识别主要方法 1、统计模式识别 2、基于隐马尔可夫模型识别 3、模糊模式识别 4、人工神经网络模式识别 总结 二、模式识别应用 1、车牌定位 2、车牌识别 参考文献: 引入 人在观察事物或现象时,常寻找它与其他事物或现象不同…

江苏某农商行稳健发展,软件安全推动金融服务新气象

​江苏某农商银行是全国最早成立的农商行之一。面对复杂严峻的内外部形势,该农商行在坚守服务“三农”与小微市场的同时,紧跟改革脚步,不断探索业务创新与数字化转型,实现经营稳健发展。 打造多维度数字化体系 驱动农商行创新发展…

QT之一种notifiation使用

简介 使用Qt5实现的消息提醒功能。 本文借助消息通知开源框架实现消息通知功能,软件包在上面。 使用说明 在pro工程中包含qtnotify2.pri 使用举例 include($$PWD/../src/qtnotify2.pri)// 包含头文件 #include "notifymanager.h"// 可建立全局实例 N…

深入理解MySQL数据库存储引擎及数据授权

深入理解MySQL数据库存储引擎及数据授权 一、MySQL数据库存储引擎的概述1.InnoDB引擎2.MyISAM引擎3.Memory引擎 二、MySQL数据授权问题1.用户管理2.数据库级授权3.表级授权4.列级授权5.收回权限 引言: MySQL是一款广泛应用的关系型数据库管理系统,为了满…

Linux常用命令——exportfs命令

在线Linux命令查询工具 exportfs 管理NFS共享文件系统列表 补充说明 exportfs 命令用来管理当前NFS共享的文件系统列表。 参数: -a 打开或取消所有目录共享。 -o options,...指定一列共享选项,与 exports(5) 中讲到的类似。 -i 忽略 /etc/exports 文…

IMX6ULL 移植篇-uboot网络命令NFS下载的文件的验证

一. 简介 本文承接以下文章: IMX6ULL 移植篇-uboot 网络命令NFS_凌肖战的博客-CSDN博客 之前学习了,如何通过NFS服务,向开发板下载 zImage文件(内核镜像文件)。 本文主要学习对 下载到开发板的 zImage文件内容进行验…

基于深度学习的高精度刀具检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要:基于深度学习的高精度刀具检测识别系统可用于日常生活中或野外来检测与定位刀具目标,利用深度学习算法可实现图片、视频、摄像头等方式的刀具目标检测识别,另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检测模型…

《MySQL》数据类型

文章目录 一,数值类型int类型bit类型小数类型float 和 decimal 二,字符串类型char和varchar日期和时间类型enum和set 一,数值类型 MySQL数据库里面的数据类型 int类型 int类型是一个大类 类型大小tinyint1字节 (-27 ~ 27-1&a…

[NISACTF 2022]babyserialize(pop链构造与脚本编写详细教学)

目录 一、理清pop链并进行标注 二、如何编写相关脚本 三、过滤与绕过 1、waf的绕过 2、preg_match的绕过 做这道题作为pop链的构造很典型,也很有意思,因为还存在一些其他东西。 打开链接,这种很多类的PHP代码多半是需要构造pop链 一、理…

Excel如何排序?掌握3种排序方法!

我是个刚开始学习Excel的新手,对很多Excel的知识都不太熟悉。今天使用Excel进行表格排序时我又遇到了一些问题。请问Excel如何排序呢?希望给我一些建议。 在Excel中,排序是一种常见且有用的数据处理操作,它可以帮助您按照特定的规…

Java编译器IDE-Java学习帮手(移动端)

应用商店搜索"java" 编码测试 import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List;public class SplitTime {private static List<Date> dateSplit(Date start…

【回溯算法part02】| 216.组合总和III、17.电话号码的字母组合

目录 &#x1f388;LeetCode216.组合总和||| ✨剪枝优化 &#x1f388;LeetCode17.电话号码的字母组合 &#x1f388;LeetCode216.组合总和||| 链接&#xff1a;216.组合总和||| 找出所有相加之和为 n 的 k 个数的组合&#xff0c;且满足下列条件&#xff1a; 只使用数…

SONY索尼MP4视频变RSV文件修复方法

索尼MP4变RSV的原因分析 索尼新型号相机或者摄像机&#xff0c;如SONY A7S3&#xff0c;A7M4&#xff0c;FX3, FX6, FX9等&#xff0c;如果录像过程中有发生如下异常情况&#xff0c;如断电&#xff0c;死机&#xff0c;电量不足&#xff0c;机器摔倒&#xff0c;非常规操作&a…

confluence_table数据爬取

需求场景&#xff1a; 获取指定confluence文档中的表格数据&#xff0c;同时将页面中的附件下载在指定的文件夹中。 实现步骤&#xff1a; 开启confluence的远程api端口 选择使用的接口。 可以参考 官方接口文档 。 当前示例用到的接口为&#xff1a; Get content /rest/a…

现在开始学linux驱动内核好吗?

一开始是觉得&#xff0c;内核诶&#xff0c;高大上。然后看了几个月驱动后&#xff0c;是认认真真的钻了几个月源码&#xff0c;写了很多学习笔记的那种。 先说好处吧&#xff0c;对基础能力的提升很明显。比如内核数据结构&#xff0c;指针&#xff0c;以及如何用c需要去完成…

Windows系统上安装Node.js图文步骤流程

Windows系统上安装Node.js图文步骤流程&#xff0c;本文以安装Node.js v4.4.3 LTS(长期支持版本)版本为例&#xff1a; 目录 Node.js下载 Windows 上安装 Node.js 1、Windows 安装包(.msi) 2、Windows 二进制文件 (.exe)安装 版本测试 Node.js下载 Node.js 安装包及源码…

Linux扩容和删除运行内存(swapfile 交换文件)

1 新增swapfile 交换文件 Linux中Swap&#xff08;即&#xff1a;交换分区&#xff09;&#xff0c;类似于Windows的虚拟内存&#xff0c;就是当内存不足的时候&#xff0c;把一部分硬盘空间虚拟成内存使用,从而解决内存容量不足的情况。Android是基于Linux的操作系统&#xf…

Cyclo(L-Pro-L-Trp-),38136-70-8,L型氨基酸环二肽,及其参数说明

&#xff08;文章资料汇总来源于&#xff1a;陕西新研博美生物科技有限公司小编MISSwu&#xff09; 为大家介绍&#xff08;CAS&#xff1a;38136-70-8&#xff09;,试剂仅用于科学研究&#xff0c;不可用于人类&#xff0c;非药用&#xff0c;非食用。 分子式&#xff1a;C16…

vscode的代码工作区实现机制

工作区是编辑器的重要部分&#xff0c;它承载着编辑器和本地文件的连接&#xff0c;对文件增、删、改、查。下面我会介绍vscode工作区的创建。同样我们知道vscode软件打开的时候没有默认工作区&#xff0c;这里我对它进行了改造&#xff0c;软件启动时指向默认工作区。 工作区目…