I use yuicompressor-maven-plugin to compress and aggregate all java scripts / css in our project. I refer the final java script/ css in all the required JSPs. This works fine in production. However, this creates a problem in development because everytime I make change to individual js / css, I am forced to rebuild for the changes to reflect. Whats the best way to organize this so that in development I will be able to make changes to individual files and see them reflecting immediately, while in production I can take advantage of the aggregation ?
Probably depends on your setup. We use Jawr for compression and can enable/disable it for any given environment. Enabled on prod, the pages link to one huge JS and one huge CSS file, compressed. Disabled on local and dev, the pages return links to each of the individual JS and CSS files, uncompressed.
Related
Is there any way to exclude unused javascript and css code and load only the required code for a particular web page?
Lets take an example, In web development, for any web page, there are so many javascripts and css files get included. though the page requires only 20% of the code. Is there some tool which finds dependencies and create a bundle for required code (say 20%) only.
Platform:
Web server: Apache, nginx
Scripting language: php
For controlling excess JS files take a look at RequireJS as for CSS I'm afraid you will probably need to rely on discipline.
Take a look at $import.js utility that allows dynamically control JS and CSS files as well. Less files also supports but requires additional compiling logic.
My question could be perceived opinion based, but I am more needing for advantages and incovenients of both way to minimize JS script in a django app.
Is it better to minimize JS scripts at rendering time with python library such SlimIt or Django-pipeline to minimize all app's scripts and save them in files?
What strategy django experts are using? Is there some cases where one or other strategy is more adapted?
Other question: Can JS scripts with template tags be minimized correctly?
In my experience it doesn't matter all that much. This is down to the fact that both methods behave in a very similar way, as minification at runtime caches the results. Either in the file system in your static directory or in a cache such as memcached.
One downside to doing this at runtime though is that the first request will be slower, as the file or cache hasn't been populated yet. And the downside to generating everything manually is exactly that, you have to generate everything manually when you make changes.
My workflow involves having all static files generated at runtime during development and having them all minified and saved during production. Django pipeline does a lot of this out of the box.
I am working on a strategy for storing and deploying JavaScript files on Azure (ASP.NET web role)
My requirements are:
To use minified versions in production
Use original versions (i.e. not minified) local versions in development environment (to simplify debugging)
Simple build/deployment process (VS2010)
Simple update process (my files will change from time-to-time)
There is a great discussion here Visual Studio 2010: Publish minified javascript files instead of the original ones however this does not take into account the benefits Azure can offer or working with multiple instances.
I am considering deploying my minified JavaScript files to blob storage and use these in the production version. These will be stored with a large max-age Cache Control for client side caching and filenames will store the version (so I can easily update). I welcome feedback on this strategy.
Thus, in development the rendered HTML would refer to a local script file, i.e.:
<script src="Scripts/myjavascript-0.0.1.js" type="text/javascript"></script>
But in Production the result should use the following to refer to a minified version.
<script src="http://myblob.blob.core.windows.net/Scripts/myjavascript-0.0.1.js" type="text/javascript"></script>
My main question though is how to best to achieve automatic switching of the paths in development and production. Or would a custom handler be the normal route (and if so how would that work – I don’t want each instance to reload from the blob on each request).
Regarding #1 & 2:
I discuss a strategy for this here. The basic idea is to user a helper function to emit the script tag. The function can construct a link to the debug files when in debug mode, and the minified files otherwise (which also makes it easy to test locally with the minified files). The same function can handle adding a version to the path for cache invalidation, etc.
Regarding #3:
Add the minification as an after-build step. I added this to my csproj (which is just an msbuild file), which use yui-compressor:
<Target Name="AfterBuild" Condition="'$(Configuration)' != 'Debug'">
<!-- remove previous minified files -->
<Exec Command="del $(ProjectDir)Styles\*-min.css" />
<Exec Command="del $(ProjectDir)Scripts\*-min.js" />
<!-- Minify javascript and css, unless we're in Debug -->
<Exec Command="java -jar $(ProjectDir)..\yuicompressor\build\yuicompressor-2.4.6.jar -o .css$:-min.css --charset utf-8 $(ProjectDir)Styles\*.css" />
<Exec Command="java -jar $(ProjectDir)..\yuicompressor\build\yuicompressor-2.4.6.jar -o .js$:-min.js --charset utf-8 $(ProjectDir)Scripts\*.js" />
</Target>
This will create minified *-min.js and *-min.css files in ~\Scripts and ~\Styles, respectively.
Warning B/c of a bug in version 2.4.6 of the yui compressor, the above won't work if there is only one .css or .js file in the directory.
Your basic plan sounds good. It will even enable you to make use of the CDN with very little effort (you just need to replace the path to your storage account with the path to the CDN).
I don't think I'd try to over think this too much. As suggested elsewhere a control is a good way to go. Simply have this control look up a web.config setting to get the root directory for your scripts and prepend it to the path of the script (your local version this setting would be empty). In order to make sure that you don't have to mess around changing the config for every deploy, I'd use config transformations so it just happens automatically.
For switching the URL of the script links dynamically when running from Azure, you should put all the script blocks inside a usercontrol and use that usercontrol in all the pages. You should not put the script links directly on the aspx/master pages, instead put then on ascx and use the ascx. This helps keeping common script links in a single file and when you need to make a sitewide change, you just change the ascx.
Another approach is to use my httphandler that changes the URL of the scripts from relative to absolute in order to facilitate download of scripts from different domain than the site is running from. You can of course use it to prepend the absolute URL of your Azure site.
http://omaralzabir.com/loading_static_content_in_asp_net_pages_from_different_domain_for_faster_parallel_download/
You may want to check out the Windows Azure CDN helpers project. It should do pretty much everything you are asking for. You can set in the config if you want your minified files to automatically be deployed to blob storage or stay on the web roles.
http://cdnhelpers.codeplex.com/
http://ntotten.com/2011/06/windows-azure-cdn-helpers/
http://nuget.org/List/Packages/CdnHelpers.Razor
http://nuget.org/List/Packages/CdnHelpers.ASPX
I'm currently developing an application that will be run on local network in B2B environment. So I can almost forget about micro(mini?) optimizations in terms of saving bandwidth because Hardware Is Cheap, Programmers Are Expensive.
We have a well structured Object oriented js code in the project and obviously lots of js classes. If all the classes will be stored in separated files then it will be quite easy to navigate through this code and hence maintain it.
But this will bring my browser to generate a couple dozens of HTTP requests to get all the js files/classes I need on the page. Even in local environment it is not super fast on first load(with empty cache), and later when you modify it and cache has to be invalidated.
Possible solutions:
violate rule "one class per file"
use YUI compressor all the time(in development & production) for generating one big js file.
But if we choose YUI compressor for this(no minify action in dev environment, and minify for production) - then we need to reload/recompile this big js file on every modification in any js file.
What would you recommend for solving this problem?
Keep all the .js files separate. Keep your "one class per file" rule.
Then, use a server-side technology to aggregate the script into one request.
Options:
Use an ASPX or PHP or whatevver server-side scripting thing you have, to aggregate all the JS into one request. The request for a .js is no longer a static file, but with caching on the server it should be relatively cheap to serve.
Use Server Side Includes in a consolidated .js file.
<!--#include virtual="/class1.js"-->
<!--#include virtual="/class2.js"-->
Your approach of having separate files for each class is good - practices that make development easier are always good.
Here's some tips for making the loading faster:
Compress your code. As you say, you could use YUICompressor, or the newly released Google Closure Compiler.
When concatenating multiple files into one, think of what you need and when: If you only need files A, B and C when the app starts, but not Z and X, put only A, B and C into a single file. Load another file with Z and X concurrently after A/B/C.
You can use Firefox plugins YSlow and Page Speed to test for load performance bottlenecks
As you mention, you would need to rerun the compressor each time you make a change. I don't think this is a big problem - on a decent machine, it should run pretty fast even with a lot of files. Alternatively, you could use a daily build process using some tool, which could build the latest revision from your source control (you do use scm, right?), and run unit tests and deploy if everything goes OK.
I would recommend using Ant or some other automation tool to create a build script. This will make it as simple as running one command to build your compressed script, reducing the repetitive work you would otherwise need to do. You could even have Ant deploy your code to the server.
You may have the best of both worlds - a development environment with one class per js file without the need to compile/deploy for every iteration AND one (or several) concatenated larger js files (minified if desired) in production.
Depending on your build environment this may be setup in a number of different ways, but using Ant may be the easiest way. Using Ant you can run tasks for both concatenation and minification (running YUICompressor through the Java task). This will produce the concatenated and minified large js file.
However, to maintain productivity you want to avoid doing this for every code iteration. Changing the tags from one to several (for every class file) is out of the question.
So, you load your big js file as expected:
<script src="application.js"></script>
When deploying to production this file is the concatenated/minified version of all your js files.
However, during development this file is a bootstrap/loader file that simply loads all your individual js-files (illustrative example using jQuery).
$.getScript('/class1.js');
$.getScript('/class2.js');
$.getScript('/class3.js');
$.getScript('/class4.js');
$.getScript('/classn.js');
....
If you are using YUI 3 look into the module behavior and how to specify dependencies.
Using different Ant targets the generation and copying of these files to the correct location may easily be managed.
And now you may simply reload your browser whenever you need to test a change in a file, but get the performance benefit during production. All without sacrificing productivity or maintainability.
On a recent project I have been working on in C#/ASP.NET I have some fairly complicated JavaScript files and some nifty Style Sheets. As these script resources grow in size it is advisable to minify the resources and keep your web pages as light as possible, of course. I know many developers who hand-feed their JavaScript resources into compressors after debugging and then deploy their applications.
When it comes to source control and automated builds in the satisfying world of continuous integration (thank you CruiseControl.NET); hand compression will simply not do. The only way to maintain source control and offer compressed resources is to keep JS/CSS source & their minified brethren in a separate directory structure. Then register only one set of resources or the other in code-behind. However, if a developer makes a change to JS/CSS source and then fails to re-compact it and check in both versions, then you’re code-line is now out of sync. Not to mention inelegant.
I am thinking that it would be nice to write a custom executable (if one does not exist yet) for the CC.NET task block which would find and compress all JavaScript and CSS resources in the target directory after the build action but before the asp.net publish to target. This way, developers would only work on JS and CSS source and users would only get the minified resources.
Is there an application that already performs this task and if not, what kind of resource(s) should I look to install on the build server to have CC.NET execute?
(The closest question I could find here to this one required NAnt, which is not an option in my case.)
EDIT:
Dave Ward now has a great article on how to automatically minify in Visual Studio at his site.
The MSBuildCommunityTasks Project has a few MSBuild tasks that may do what you are looking for including Merge and JSCompress.
You could add these into your MSBuild project in the AfterBuild target to allow the project to perform this action every time the project is built and nothing would ever be out of sync. Your web application could then reference the compacted version for run but the developers would edit the full versions.
Nothing else would be needed on the server except the MSBuild community tasks assembly. You can put this assembly in your own source tree and reference from there and your CI build should get that assembly and everything it needs when it builds.
Another JS (and CSS!) compression library for MSBuild:
http://www.codeplex.com/YUICompressor
This is a .NET port of the java-based Yahoo! compressor.
Not a perfect answer, but if you're using MVC4 they've built this in as a new feature. When running a Debug configuration, it outputs individual files with comments and such but when you switch to Release, it will automatically bundle, minify, and change in page references to the minified files. You can setup separate bundles for, say, jquery and your own js. This works with CSS and JS files.
http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification
If MVC4 doesn't work for you, you can also find packages on Nuget that can help such as this:
https://www.nuget.org/packages?q=minify