XamlC is currently enabled for most Xamarin.Forms projects in `Debug`
and `Release` configurations. It enables faster startup/runtime
performance, XAML-syntax checking at build time--both quiet useful!
However, there is a build-time cost to using XamlC: each assembly is
loaded via Mono.Cecil, IL generated, and saved back to disk as an
additional step after Rosyln has compiled the assembly.
The proposal would be to add a new experimental MSBuild property, that
can be enabled for `Debug` mode such as:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<!-- ... -->
<XFXamlCValidateOnly>True</XFXamlCValidateOnly>
</PropertyGroup>
This would do the following:
* `OptimizeIL` is skipped.
* Assemblies are analyzed, but no changes written to disk.
* No symbols are loaded via Mono.Cecil, we don't need them if we
aren't writing back to disk!
This will improve build performance, and we don't lose the build-time
error checking for XAML.
Down the road, we could consider moving the MSBuild property to be the
default for `Debug` builds or change the Xamarin templates. I think it
would be wise to require developers to opt-in to try this out.
~~ Results ~~
I tested this change by building the ControlGallery after changing one
line of XAML:
msbuild Xamarin.Forms.ControlGallery.Android\Xamarin.Forms.ControlGallery.Android.csproj /clp:performancesummary /p:XFXamlCValidateOnly=True
Before:
1979 ms XamlCTask 1 calls
After:
923 ms XamlCTask 1 calls
I *only* tested `Debug` builds.
Right, so it's faster. But let's keep the entire developer loop in
mind, how much slower is startup?
Before:
09-05 14:37:32.274 1169 1192 I ActivityManager: Displayed AndroidControlGallery.AndroidControlGallery/md546303760447087909496d02dc7b17ae8.Activity1: +3s890ms
09-05 14:38:30.178 1169 1192 I ActivityManager: Displayed AndroidControlGallery.AndroidControlGallery/md546303760447087909496d02dc7b17ae8.Activity1: +3s848ms
09-05 14:38:40.300 1169 1192 I ActivityManager: Displayed AndroidControlGallery.AndroidControlGallery/md546303760447087909496d02dc7b17ae8.Activity1: +3s848ms
After:
09-05 14:40:38.512 1169 1192 I ActivityManager: Displayed AndroidControlGallery.AndroidControlGallery/md546303760447087909496d02dc7b17ae8.Activity1: +3s894ms
09-05 14:40:55.497 1169 1192 I ActivityManager: Displayed AndroidControlGallery.AndroidControlGallery/md546303760447087909496d02dc7b17ae8.Activity1: +3s856ms
09-05 14:41:03.754 1169 1192 I ActivityManager: Displayed AndroidControlGallery.AndroidControlGallery/md546303760447087909496d02dc7b17ae8.Activity1: +3s897ms
After three runs, it seems this app suffers 25-50ms slowdown to
startup, and gains 1 second of build time improvement. A good net-win!
Other apps that have significantly more XAML will have different
results. I suspect the build time improvement will be even better, but
the hit to startup could be worse. With this setting opt-in, we can
experiment and find out.