I've been learning about the various ways of content optimization for websites for months now, however I'm still confused about what's the right way of doing so e.g. which 'optimization workflow' results in what effects.
ASP.NET MVC provides its own optimization framework through the 'Microsoft.Web.Infrastructure' package. With that, I can define bundles and minification strategies directly in code on request or when the application starts. However, since my style files are written in less, I need to compile them beforehand, which might slow down the overall application start process, so I feel it might be better to compile those during the build process of the application. But then again, most stylesheet compilers allow to bundle and minimize directly, so why not doing anything there?
LESS files should be compiled when the application compiles
CSS files should be bundled to reduce the amount of needed client requests
CSS files should be minimized to reduce traffic and overall page content size
So, what's the suggested way of accomplishing this?
Compile LESS files on build (with e.g. dotless)
Deploy application to server
Bundle and minify on request using optimization bundles?
When does this bundling and minification happen in the ASP.NET lifecycle? On the first start of the web application? On every request?
Bundling and minification happens on application start.
By default the bundle is created on the first request and then cached on the server. The cached version is then used for all other requests.
The bundling and minification occur at the start of the web application. That is where we specify the process.
Some of the tools allow you to do it explicitly, in such cases we load the .min.js files directly.
When we create a min.js using any tool, the source and minified files are different. These are mapped through a map file.
As we update the source files during development, there are chances that the min.js files are not updated when the source .js files are changed. This issue is more prominent when the files are source controlled. In such a scenario during deployments, it is common to find that the changes in the source machine aren't reflecting in the deployment.
The best thing for bundling and minification would be to adopt the Optimization framework provided by ASP .NET, this does the job dynamically unlike other external tools.
When compilation debug = true it skips the process and loads the original files without bundling, when it is false, the framework bundles all the specified JS and CSS files and deploys it to the server.
I hope this answers your question.
Related
I've written an electron application which is packed via electron-packager and shipped to users. Now of course I'd like to put at least some very basic Protection on my sources, ideally merging all my JS files into one big file, and uglify this file.
Of course this would break all require Statements in the HTML and JS files (even if I only minify / uglify without merging, the JS files get renamed).
Is there any convenient way to merge those files upon building the app, without rewriting my working environment?
You can wrap your project with webpack. I'm not sure which framework has been used at your renderer UI framework.
But you can use this plugin https://webpack.js.org/plugins/uglifyjs-webpack-plugin/.
This will help to make uglify your source code.
After webpack build then you just need to change the entry point for main and renderer.
What are the differences between System.Web.Optimization.Bundle and the bundling operation in WebEssentials Visual Studio plugin?
I mean not only the final result which should be pretty much the same, but also the internals, esp. the differences (if any) in both Debug and Release mode.
And, finally, what do I gain and what do I loose choosing one or another?
As we know System.Web.Optimization.Bundle is mainly used for bundling the js or css files to reduce page size or loading issues but web Essentials is a collection of (mostly) web-related enhancements to Visual Studio.
It includes lots of new IntelliSense completions (especially for CSS), new BrowserLink features, automatic JSHint for Javascript files, new warnings for HTML and CSS, and many other features. Any web-related functionality you want to add should probably go here.
In details if you want to check then below links might be useful.
For Bundling and manification
https://learn.microsoft.com/en-us/aspnet/mvc/overview/performance/bundling-and-minification
For Web Essential
https://blogs.msdn.microsoft.com/mvpawardprogram/2013/11/05/making-web-development-wonderful-again-with-web-essentials/
I use both approaches time to time. The result is almost the same (size of output files, compile time etc).
System.Web.Optimization. You maintain functionality through *.cs and *.cshtml files.
Web Essentials. You maintain functionality through context menu and config accumulated in .json(xml) files.
But you can not use System.Web.Optimization approach if you develop static html page (no server side at all)
I am using ASP.NET MVC3, .NET4, Razor, C#, EF4.1, MS SQL2008(dev), SQL Azure(test,live).
I am deploying my web application to "Standard" Azure Websites. My process is:
1) Publish to local IIS folder, no precompilation options selected:
Project C# code is compiled as Project dll and put into "bin" folder.
Views stay as source *.cshtml files
2) FTP changed files to deployment server using Beyond Compare,so
Project DLL gets copied
Source *.cs files (Controllers, helpers, Models) get copied.
Changed source *.cshtml Views getting copied
With the initial call to the deployment server, the response is slow, due to JIT compilation. I suspect this is due to:
a) Views being compiled. Major factor as opposed to project dll??
b) Project DLL already precompiled so no issue here ??? Is this correct.
I try to keep the application pool in memory via pingback services either external monitor sites(Uptime Robot) or MS's "always on" service which is the same. But one can still get app pool refreshes and thus slow downs. It seems to me that everything should be precompiled for deployment so that if dropped from memory then rerunning will be quick.
My question(s)
1) Is my understanding correct about what is precompiled and what is not?
2) What should I do now to maximise precompilation and minimise these app pool refresh penalties, and thus keep performance at it peak ie no start of day warm ups etc. My initial impression is to precompile the Views. I did try editing the Project XML file, and this setting specifically:
<MvcBuildViews>true</MvcBuildViews>
However when I try to publish using the above setting I get an error:
obj\release\aspnetcompilemerge\source\web.config(45): error ASPCONFIG: It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS.
EDIT
Having done a little more research it seems that I need to focus on precompiling the Views for wich 2 main tools exist:
a) RazorSingleFile
b) RazorGenerator
Apparently
<MvcBuildViews>true</MvcBuildViews>
just compiles rather than precompiles. Not sure of the difference. So it is recommended to use one of the tools above.
EDIT2
My main MVC project dll is 890k-ish in size. Is this large? Would the size cause more drop out from memory?
There is a serious rabbit hole when building views. There is some known bug that this particular error happens. The only known if is to use the <BaseIntermediateOutputPath>. This path needs to exist, and not be within the project path (I think). I usually use:
<MvcBuildViews>true</MvcBuildViews>
<BaseIntermediateOutputPath>..\..\tempMVC</BaseIntermediateOutputPath>
The Aspnet Compiler Build Task in Visual Studio 2010 ASP.Net MVC 2 Projects
I am 95% sure that: You can't pre-compile MVC views (cshtml, etc) for deployment (with any default version of Visual Studio, there may be add-ons). There are two separate issues here.
First, <MvcBuildViews> is only a buildtime strongly-typed checker when set to true. Meaning that if you build a view against a specific #model that the compiler will check the view during a build to make sure aren't using the model incorrectly (like trying to use a property on the model that doesn't exist).
Secondly, the notion of pre-compiling a view into an assembly is a process that exists for Webforms because there is a code in-front and code behind that can be combined. Views aren't tied to logic in this way so the compiler hasn't been designed to take MVC Views into account.
OK, my solution was to publish the application.
Then I selected:
Precompile during Publishing
I then clicked on "configure" and then unchecked:
Allow precompiled site to be updateable
I then selected:
Do not merge, create a seperate assembly for each page or control.
This enabled the precompilation of the views, and put them in the bin folder, in the form of:
_orders.cshtml.4deb95a2.compiled
I understand this to be p-code and so will still need a binary compilation on first load on the deployment server. The project dll is worse since it is bigger.
By the way I did encounter quite a few assembly references issues that were caused by old excluded code files. I thought if they were excluded that was good enough, but no..... In the end I just deleted them all and the precompilation completed successfully.
Doing this forced me to fixed quite a few hidden razor errors which would have come out at runtime as opposed to compile time.
I'm a little confused as to how MVC handles CSS and Javascript, and I have a few questions.
Whenever I create a default MVC (5) application, I see that there are already a number of CSS and Javascript libraries added, with both normal and minified versions.
When I look at the BundleConfig class, I see that the regular files are bundled together, but the minified versions are not.
When are the minified versions actually used? When I debug the site, or even deploy it to a server, I never see these being used. Is this something I have to change myself, or is there a setting for this?
Also, do I need to keep the regular and minified versions of these files in sync, or is this something MVC can do automatically?
Thanks
Bundling
Bundling is a new feature in ASP.NET 4.5 that makes it easy to combine
or bundle multiple files into a single file. You can create CSS,
JavaScript and other bundles. Fewer files means fewer HTTP requests
and that can improve first page load performance.
Minification
Minification performs a variety of different code optimizations to
scripts or css, such as removing unnecessary white space and comments
and shortening variable names to one character.
Your Question ?
When I look at the BundleConfig class, I see that the regular files
are bundled together, but the minified versions are not.
Answer :
You don't need to include minified versions into bundle.B'cos bundling itself does this (minification) at the time when your app's status is release.By default Debug mode will use non minified version.
Your Question ?
When are the minified versions actually used? When I debug the site,
or even deploy it to a server, I never see these being used. Is this
something I have to change myself, or is there a setting for this?
Answer :
Minified version will use at the time app is on production (or release mode).
You don't need to do anything here.It does automatically when you change the App's status as release.
Your Question ?
Also, do I need to keep the regular and minified versions of these
files in sync, or is this something MVC can do automatically?
Answer :
You don't need to do anything here.It does automatically by the framework.
Important Note :
You don't need to add minified files into bundles.B'cos bundled files will be automatically minified when app status is on release mode.Please read below thread for more info.
Bundle vs Minification,Which one is the best
By default, if your app is built with Debug option, bundling and minification takes unminified versions. If site is built in Release mode, minified versions of files are taken, where available.
On top of that you can enforce minification yourself by having
BundleTable.EnableOptimizations = true;
in your BundleConfig class. This enables minification for all the bundles for you. To have this minification only in releases I usually do compiler condition:
#if !DEBUG
BundleTable.EnableOptimizations = true;
#endif
And it is very recommended to read the documentation already linked in comments
Ok, please bear with my noob question here.
I'm doing the simple task of making an update to my mvc application, compiling it and then moving in onto the production server.
I just wan't to know the best way to upload the compiled files. I have a single application pool, use ftp to upload the new application files and the site points to a single directory.
If I update just one view then which
files do I upload after compiling?
Is there a way to keep the site running
while I upload new code/views?
Where can I go to find out this
information?
Generally, you can update views without needing to re-cycle your web application. You would just want to replace the old version of the file with the new version, which can be done with a simple X-Copy command.
If there are code changes, then you will need to upate the web project DLL, which requires the app to recycle. This may or may not be a huge disruption, but it does mean that users may have their session interrupted, and lose some state.
Now, the question of how you could go about doing this is a little more complex. You can write a deployment process into your build scripts, which may be the easiest approach. The trick here, though, is that if you want to only include files that have changed, this can be a little trickier using vanilla NAnt or MSBuild tasks. You may also want to look at the WebDeploy tool from the IIS team. I've not used it much myself, but it is designed specifically to deploy web projects.
You may also want to hit google for some commercial deployment tools if none of the options so far seem to work for you.