2 Comments

Web Standards Update for Microsoft Visual Studio 2010 SP1We just released the first Web Standards Update for Microsoft Visual Studio 2010 SP1. Despite its name, the update also works for Visual Web Developer Express 2010 SP1. You can read more on our team blog.

In this first release of the update, we have focused on bringing the HTML5 support up-to-date, adding CSS 3 support and bring more new API’s to the JavaScript intellisense.  The plan is to make a release on a regular schedule to keep Visual Studio updated with the changes made by W3C.

HTML5

Last year, we managed to sneak in HTML5 support when working on SP1 for Visual Studio 2010. Normally, a service pack is about bug fixes but we found that HTML5 was so important that the lack of it should be considered a bug. Unfortunately we where not able to do the same with CSS3 or the JavaScript API’s, but it was a good start.

Due to a combination of the instability of the HTML5 specifications at the time and the resources we had to add HTML5 support for SP1, we ended up with very descent support for both intellisense and validation. Now the HTML5 specifications are more stabile and some additions and modifications have been made by the W3C since then. It’s therefore a good time to update the HTML5 and XHTML5 schema files that Visual Studio uses under the hood to provide intellisense and validation.

Among the changes are:

  • Added missing elements like u, s and bdi
  • The type attribute is no longer required on script elements
  • The source element is now supported inside video and audio elements
  • Support for microdata including intellisense for schema.org vocabularies
  • Full WAI-ARIA intellisense

CSS3

For CSS3 we were not as lucky as we were with getting HTML5 into SP1. This was largely due to a combination of time and resources in terms of available developers. CSS3 is more difficult because the specifications change much more frequently than the specification for HTML5. For us it is a constant battle with keeping up to date with these changes and subsequently getting them into the next version of this update. That way we make sure that you will always have the latest and most accurate CSS3 support in Visual Studio.

The CSS3 support includes:

  • Will not invalidate filter, zoom and behaviorproperties
  • Have intellisense for vendor specific schemas (-ms-*, -moz-* and -webkit-*)
  • Up-to-date intellisense and validation for CSS3 properties and values

JavaScript

We’ve gotten a lot of customers asking for better intellisense for some of the new web API’s such as DOM Storage and Geolocation. In this update we are including intellisense for a lot of the API’s found in EcmaScript 5 including:

  • New selectors such as getElementByClassName
  • Geolocation, DOM storage and other new web API’s

More info

Check out the unofficial announcement or Scott Hanselman’s run-through

Download

If you haven’t already, I encourage you to download the Web Standards Update for Visual Studio SP1and try it out today. It’s a small and quick install.

0 Comments

Since the release of Visual Studio 2010 SP1 beta last month, there has been a lot of questions regarding the support for HTML5 and CSS3.

HTML5

Visual Studio 2010 was originally released without HTML5 support, so does SP1 finally add support for it? Yes, to some extent. The entire HTML5 specification isn’t supported but most of the new elements and attributes are. That means you get both intellisense and validation for HTML5 with SP1.

Turn it on

After installing SP1 you have to tell Visual Studio to start using the HTML5 schema. Go to Tools -> Options, and then select Text Editor -> HTML -> Validation. You should now be able to select HTML5 or XHTML5 as the target schema.

clip_image002

Or if you have the HTML Source Editing toolbar enabled, you can select it in the target schema dropdown.

clip_image003

Intellisense support

The new elements that are specific to HTML5 are shown in the intellisense list as you would expect.

clip_image004

Even the new HTML5 specific attribute values for existing elements are shown.

clip_image005

Prior to SP1 there had been a bug that caused a runtime error when an input element used some of the new type attribute values such as email in conjunction with runat=”server”.

<input type="email" runat="server" />

This error has been fixed and will be included in the final SP1. However, it is not part of SP1 beta. In the meantime, you can use the Textbox control instead which doesn’t cause the error.

<asp:textbox type="email" runat="server" />

CSS3

In SP1 there are a few improvements in the CSS3 support as well, though not as elaborate as with HTML5. The editor now supports the more advanced selectors such as div:nth-child(2n+1)without giving validation errors and the new color values rgba, hsl, hsla and 8 digit hex values are also supported.

Start today

The conclusion is that with Visual Studio today, you can build HTML5 and CSS3 web applications on top of ASP.NET, and with SP1 we are making it a lot easier for you. We encourage all ASP.NET developers to start taking advantage of what HTML5 and CSS3 has to offer already today. The Web Platform and Tools team takes web standards very seriously and you will see much better support for HTML5 and CSS3 in the future.

3 Comments

Most web developers know the importance of optimizing images for faster page loading times, but it’s also a very cumbersome, time consuming and boring process. Then when you are done, the customer or designer gives you new images to use and you can start the process over and over and over again. The result is that we spend a lot of time optimizing images and also forget to do it from time to time.

That’s why I’ve been experimenting with a way to automate the process of optimizing images for use on web pages. This has resulted in a Visual Studio 2010 extension to do just that.

The extension

The idea with automating the optimization is that the images must have the same quality in color and fidelity as before they were optimized. That is done with proven algorithms, and when an image has been optimized, it cannot be further optimized by the same algorithm. Nothing happens if you run the optimization multiple times on the same image – it will only be optimized the first time.

If you run the optimization on an image that has already been optimized using other tools, you might still be able to optimize further, but often nothing will happen - the image will not be touched when it has been analyzed and no optimization is found possible.

In this beta of the Image Optimizer extension, only JPEG and PNG files are supported, but that should hopefully cover ~90% of images in modern websites.

When you right-click a folder in the Solution Explorer in Visual Studio, you now have a new menu item called “Optimize images”.

When clicking the menu item, the image optimization starts. It looks for all images in the clicked folder and all its subfolders. You can also select multiple folders before right-clicking. As the images are processed, the result of the optimization is printed to the Output Window in Visual Studio.

The extension uses OptiPNG for optimizing PNG files and jpegoptim for optimizing JPEG files. I will go into more details about how it works in the coming weeks when the extension is more polished and open sourced.

Download

Please try it out and give me any feedback that will help improve it.

Download the extension in the Visual Studio Gallery

0 Comments

In part 1 of this series, we looked at some tricks to optimize the performance of any website running in IIS 7 by only modifying the web.config. In this part we will focus on handling browser caching issues and optimize the number of JavaScript and CSS files loaded from an ASP.NET website.

NB! All the code (a single .cs file of 125 lines) is included in the zip file at the bottom of this post.

Browser caching

In part 1, we looked at how it was possible to set an expiration header to any static file such as JavaScript and CSS files, so the browser would cache them for a long time and thereby optimize both for bandwidth and the number of requested files going from server to browser.

The problem with setting a browser cache expiration date of i.e. a JavaScript file to a year in the future becomes clear when you change the file before it expires in your visitor’s browsers. They simply won’t see the changes until they either clear their cache or hits F5 manually.

Adding the version number

The only viable way to maintain a far-in-the-future expiration date is to change the URL of the file when the file changes. So instead of including script files like so:

<script type="text/javascript" src=”/scripts/global.js"></script>

…we really want to get a version number included in the src attribute, like so:

<script type="text/javascript" src=/scripts/v_634174870689341736/global.js"></script>

The problem with this is that ASP.NET doesn’t have any feature that will inject a version number, so we have to create that our selves. It is very simple to do so by looking at when the file was last changed and then retrieve the ticks from that date. In the zip file below you’ll find a method that does exactly that and it can be used like so:

<script type="text/javascript" src="<%=BundleHelper.InsertFile("/scripts/global.js") %>"></script>

The BundleHelper.InsertFile method is one you want to use for Stylesheets as well, like so:

<link rel="Stylesheet" href="<%=BundleHelper.InsertFile("includes/style.css") %>" type="text/css" />

Ok, now all our JavaScript and stylesheet references have the version number in the path. Next thing to look at is getting it working with the updated non-existing path.

The HTTP handler

To be able to serve the correct file even with the version number in the path, we need to register an HTTP handler in the web.config’s <system.webServer> section like so:

<add name="ScriptBundler" verb="GET,HEAD" path="*.js" type="FileBundleHandler" />
<add name="CssBundler" verb="GET,HEAD" path="*.css" type="FileBundleHandler" />

The handler we just registered is called FileBundleHandler and knows how to filter out the version number to find the right file. It supports both .css and .js files. The handler also makes sure to both output cache and browser cache correctly. Just add the FileBundleHandler.cs file from the zip file to your website and you are up and running.

Now the browser cache issue has been resolved by adding a version number to the path of the included file and by adding an HTTP handler that knows how to remove it again when serving the file.

Bundle multiple files

Another common website performance issue is that there are many JavaScript and CSS files included on a page. This scenario results in the browser have to download a lot of extra files and that all slows down the performance of a website. The solution to this is also very simple when you’ve first completed the above steps to register the HTTP handler in web.config and called the BundleHelper.InsertFile method when inserting JavaScript and CSS files.

The folder structure convention

There are many ways of bundling files into a single request, like Justin Etheredge’s Squisher. For this example I have chosen a convention based approach because that doesn’t require any code to implement.

Any given ASP.NET website might have a folder structure similar to this:

The folder convention supported in the FileBundleHandler lets you reference a folder instead of just a file. Both the HTTP handler and the BundleHelper.InsertFile understand when a folder is referenced and automatically bundles all the .js or .css files to a single response. So in order to bundle all the files in a given folder, simply reference the folder name and add the extension of the types of files you want bundled. Having the folder structure above, you can add a bundle like so:

<script type="text/javascript" src="<%=BundleHelper.InsertFile("/scripts/common.js") %>"></script>

Notice that the file /scripts/common.js doesn’t exist, but the folder /scripts/common does. By adding .js at the end, we tell the HTTP handler to look for all files with the same file extension – in this case .js files. It bundles all the files in alphabetical order and serve the as a single response. For security reasons, the HTTP handler will only serve .css and .js extensions.

Minification

Since we are now running all JavaScript and stylesheet files in bundles and through the HTTP handler, it makes sense to also look at the content of the files to optimize even further.

For this example I’m using the Microsoft Ajax Minifier (MAM), which is a single .dll file capable of minifying both JavaScript and stylesheets. The MAM is my favorite JavaScript minifier since it not only removes whitespace, it also rewrites variable and function names and a lot of other things as well. For me it has proven a better choice than the YUI Compressor and Google Closure Compiler. The stylesheet minifier feature of MAM also looks very nice, but I have honestly never used it before except for this example.

Basically what MAM does is that it optimizes and removes unwanted whitespace from both JavaScript and stylesheets. The HTTP handler makes use of MAM for both single files and bundled ones, so you get full benefit no matter your scenario.

Summary

No matter if you use the website model, the web application model or ASP.NET MVC you are now able to utilize the browser cache to the fullest. Furthermore, by bundling your files using the folder convention you can minimize the number of requests sent by the browser. Both JavaScript and stylesheet files are also minified and optimized for even smaller file sizes sent over the wire.

It's worth noticing that the output caching respects file changes and therefore refreshes evertime changes are made to the JavaScript and CSS files tunnelled through this code.

Following the techniques in part 1 combined with this example will improve any website’s server-to-browser performance substantially.

Implementation

  1. Download the zip file below and place the AjaxMin.dll in your bin folder.
  2. Then place the FileBundleHandler.cs in your App_Code folder if you use the website model – otherwise place it where ever it makes sense in your structure.
  3. Now register the HTTP handler in your web.config under the <system.webServer> section like so:

    <add name="ScriptBundler" verb="GET,HEAD" path="*.js" type="FileBundleHandler" />
    <add name="CssBundler" verb="GET,HEAD" path="*.css" type="FileBundleHandler" />
  4. The last thing you need is to start using the BundleHelper.InsertFile method on your pages for both JavaScript and stylesheets like so:

    <script type="text/javascript" src="<%=BundleHelper.InsertFile("/scripts/common.js") %>"></script>
    <link rel="Stylesheet" href="<%=BundleHelper.InsertFile("styles/global.css") %>" type="text/css" />

Download

FileBundler.zip (89,95 kb)