再探.NET8 NativeAOT
这回,我们终于进入实战阶段了!
这回,我们终于进入实战阶段了!
乘着昨天良好的开局,这一回,我们开始进入实战项目的阶段。 翻了半天,终于找到一个代码量不大也不小的工具类应用:VuePacker。它的主要功能是前端开发工具,主要功能有:
看看NativeAOT能否一句将其拿下。
先改TargetFramework,然后加上PublishAot,最后dotnet publish发布打包……一通熟手的操作下来,竟然无比顺利,成功编译生得到了exe。果然不出意外地出了意外,双击运行的时候,报 错 了!
Reflection-based serialization has been disabled for this application. Either use the source generator APIs or explicitly configure the 'JsonSerializerOptions.TypeInfoResolver' property.
报错信息的指向很明确,是个Json反序列化的报错。项目代码确实用到了System.Text.Json,沿着这条线索,终于找到解决方法。
AOT的编译是会根据代码实际情况对依赖的库进行裁剪,以保证生成文件足够苗条。但有些库可能用到某些动态写法,因此编译器裁剪后打包却不能正常工作。这时候,我们需要引入rd.xml来声明第三方库的编译打包方式,告诉编译器不要对它做裁剪,而是全量编译进去。等于做出一定牺牲,让文件变得臃肿一些,以保证应用能够正常运行,以空间换胜利。
<Directives>
<Application>
<Assembly Name="System.Text.Json" Dynamic="Required All">
</Assembly>
</Application>
</Directives>
<ItemGroup>
<RdXmlFile Include="rd.xml" />
</ItemGroup>
重新发布后,报错消除,我的应用可以正常执行了!但是exe文件的大小,从原来的5.6M涨到了8.4M,竟直胖了50%!
rd.xml的方案确实有效果,不过副作用也挺大,是最求极值的在下不能忍受。那么,下面就继续做些优化吧。优化思路:
appsetting.json的配置文件而已,几千行代码仅仅调用过一次。其实可以试试yml 或者 ini,这些配置解析的算法都比json轻的多。不过,这样也有坏处,就是对用户不大友好。以往版本都是用json做配置的,换一种配置方式用户教育成本,虽不大但还是有的。让用户无感升级才是最最理想的。按照方案C操作后,得到4.5M的exe文件。
看来量少用或者不用第三方库,对优化exe文件大小会有立竿见影的效果。好吧,掌握了规律,那就再动动刀子,把仅剩一个的第三方库:NUglify换掉试试。
我发现Javascript打包混淆的代码,自己去造轮子显然不现实,只能找别人的轮子拼接过来。事实上这套代码并不好找,我在GitHub翻了好久,才找到一个停更多年的开源项目:https://github.com/Taritsyn/JSMin.NET将就着用把,反正也只是个试验罢了。
最后,一番折腾下来,我能做到极限大小的exe文件是3.2M。