Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Still seeing runtime compilation when using StackExchange.Precompilation.Build #38

Open
mike-riedel opened this issue Mar 7, 2018 · 7 comments

Comments

@mike-riedel
Copy link

I believe I've followed the necessary steps to use precompiled .cshtml views but when I run my web app and click on various pages, I still see significant delays and see VBCSCompiler.exe appearing in Task Manager, leading me to believe that the precompiled views are not being used.

Do I have the wrong expectations about what this package does or am I doing something wrong?

I followed these steps, per the instructions on github:

  1. Added the StackExchange.Precompilation.Build and StackExchange.Precompilation nugets to web project which uses Razor and .cshtml files
  2. Added true to .csproj
  3. Cleared existing ViewEngines and added new instance of PrecompiledViewEngine followed by RoslynRazorViewEngine

In the build output I've verified StackExchange.Precompiler.exe is being run, and while debugging I've verified PrecompiledViewEngine is finding what seem to be precompiled views in the project's assembly. And yet, I still see long delays and VBCSCompiler being run whenever new cshtml views are accessed.

@m0sa
Copy link
Contributor

m0sa commented Mar 8, 2018

You can get more details on what is happening by hooking into the following events:

StackExchange.Precompilation.RoslynRazorViewEngine.CompilingPath += OnRuntimeCompilation;
System.Web.WebPages.Razor.RazorBuildProvider.CompilingPath += OnRuntimeCompilation;

... and have the handler log it somewhere:

private static void OnRuntimeCompilation(object sender, System.Web.WebPages.Razor.CompilingPathEventArgs e)
{
    // TODO log details somewhere
}

There are also other thing asp.net tries to build at runtime, like global.asax, helpers, etc.

There is a workaround for global.asax in the test project via the PreApplicationStartMethodAttribute and the correct handler.

If you're sure you're not using anything else, you can also add a PrecompiledApp.config to you web application project with the following content:

<?xml version="1.0"?>
<precompiledApp version="42" updatable="true"/>

It tells the BuildManager not to attempt building any special-purpose folders such as App_Code, App_GlobalResources, and App_WebReferences, and special files such as Global.asax.

@mike-riedel
Copy link
Author

Thanks for the helpful information and suggestions.

I added trace output for those events, applied the global.asax workaround and create the PrecompiledApp.config file. The traces show a runtime compilation event whenever a "new" .cshtml page is requested. In other words, if the same page is requested multiple times, the event only occurs for the first request. The sender of the events is always System.Web.WebPages.Razor.RazorBuildProvider.

@m0sa
Copy link
Contributor

m0sa commented Mar 9, 2018

You can get a list of all precompiled views the precompiled view engine knows about via the PrecompiledViewEngine.ViewPaths property. If they aren't there, you didn't initialize it correctly. If they are, plase elaborate, as something might be broken in the path resolution / normalization.

@mike-riedel
Copy link
Author

I have two web projects in the same solution, one for sign-in and the other for whatever. The sign-in app never fires a runtime compilation event when its pages are requested. But the admin app wants to runtime-compile every page other than "~/index.cshtml". While debugging, PrecompiledViewEngine.ViewPaths contains reasonable paths which look like they should correlate with a particular Request.Url and in one case it seems to work and in the other it does not.

For example, ViewPaths contains "~/app/services/services.cshtml" and a request comes in with RawUrl = "/rightfaxsdk/admin/app/services/services.cshtml" and AppRelativeCurrentExecutionFilePath = "~/app/services/services.cshtml", which is an exact match for the entry in ViewPaths. But the CompilingPath event is fired, which to me means the page is being compiled.

I've spent hours looking for relevant differences between the two apps, including detailed file diffs, but haven't found anything that seems important. The sign-in app has a lot less pages (10 instead of 89) but I can't imagine that would matter.

@mike-riedel
Copy link
Author

We use HttpContext.RewritePath for most incoming requests (primarily to remove cache-busting fingerprints). Could the resulting changes to the Request cause the caching not to locate the correct precompiled file?

@m0sa
Copy link
Contributor

m0sa commented Mar 11, 2018

Maybe, if you use partial view names (e.g. View("Foo"), or just View() inside the Foo method). Have you tried specifying the full view path instead (e.g. View("~/Views/Bar/Foo.cshtml"))?

@michael-huxtable
Copy link

Adding to this, I found that using the package with VS2015, I consistently get this error message:

3>CSC : warning : Couldn't load reference 'System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' from 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\Facades\System.Runtime.dll' - 'Could not load file or assembly 'System.Runtime, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. An operation is not legal in the current state. (Exception from HRESULT: 0x80131509)'
3>CSC : error : An unhandled exception occured
3>CSC : error : System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.

Using VS2017, we do not see these build errors. Following the guide to copy the DLLs into the tools directory results in a different error when using VS2015:

3>CSC : warning : Couldn't load reference 'System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' from 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\Facades\System.Runtime.dll' - 'Could not load file or assembly 'System.Runtime, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. An operation is not legal in the current state. (Exception from HRESULT: 0x80131509)'
3>C:\Program Files (x86)\MSBuild\14.0\bin\Microsoft.CSharp.Core.targets(67,5): error MSB6006: "StackExchange.Precompiler.exe" exited with code -1073741819.

For now I have migrated to VS2017, Is this likely to be due to the MSBuild version used? Or related to dependency resolution?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants