Introduction
Technologies Used
Images and 'Painting' elements on a page
A lot of images on web sites need to either be resized or losslessly compressed to reduce size and to optimize its rendering. Unfortunately, a lot of developers don't manually do this to most of the images because:
- The sheer amount of images will take up too much development time; or
- An image needs to be reused on different pages at different sizes.
Developers then use a much larger-than-needed image to able to compensate. This leads to the web browser having to download and cache a large image, resize it manually,
then paint it on the page. If the developer hasn't put dimensions on the <img>
tag, the page would have to paint it twice. This all leads to much
longer load times than necessary per image, per page.
[.css / .js] Script loading
Many sites rely on, and use, stylesheets and JavaScript to add functionality and custom looks to their page. What many developers don't do, however, is look for
'minified' versions of either to help the page load faster. A minified version of a script is one that has all the commenting and whitespace removed, most of
the line-breaks removed, as well as shortening long variable names to one or two digits. After the minification process, the script file is reduced in size from
anywhere between 20%-80%. This allows them to be downloaded and run at a much faster pace.
Other shortfalls include the use of unneeded styles and scripting on the page, and having to download many individual scripting files.
Fighting 'the man'
To combat these scenarios and help alleviate page load and painting times, skilled developers have crafted a set of tools and given it to the general developer
public to freely use. All credits, to the respective projects, go to those developers who have spent many months to develop and refine
their products.
The following tutorial will show you only how to use these products to speed up your site. The author takes no credit on how it works.
Notes
This tutorial will not show you how to use LessCss, only how to implement it in this package. For usage, please refer to http://www.dotlesscss.org.
All web.config and other references should be managed by the NuGet packages.
The technologies work as-is from when this document was compiled. Implementation is at the user's own will. The author takes no responsibility on any impacts
(negative or positive) that this tutorial may have on the site. The following is intended for production use using Microsoft's MVC and RAZOR.
Optimizing images
To continue the tutorial from here, please install the following from the NuGet Package Manager:
ImageResizer
ImageResizer.Mvc
ImageResizer.MvcWebConfig
Simple.ImageResizer
Simple.ImageResizer.MvcExtensions
The goal
To dynamically render an optimized version of the image needed, reducing bandwidth, and saving browser paint time.
Implementation
Following the tutorial at: https://github.com/terjetyl/Simple.ImageResizer#readme
Create a new Controller and call it ImagesController
. This is where the images on your page get cached by the server to their desired dimensions.
Paste into ImagesController
:
using System.IO;
using System.Web.Mvc;
using Simple.ImageResizer.MvcExtensions;
namespace Demo.Controllers
{
public class ImagesController : Controller
{
[OutputCache(VaryByParam = "*", Duration = 60 * 60 * 24 * 365)]
public ImageResult Index(string filename, int w = 0, int h = 0)
{
string filepath = Path.Combine(Server.MapPath("~/images2"), filename);
return new ImageResult(filepath, w, h);
}
}
}
Add the following code into the RegisterRoutes(RouteCollection routes)
method in 'App_Start/RouteConfig.cs'.
routes.MapRoute(
"Image", "images/{filename}",
new { controller = "Images", action = "Index", filename = "" }
);
This will automatically pick up any image on the page and pass it to ImageResizer
to process.
Now all you need to do is call an image with the standard <img>
tag – on any page – add the desired transformation to the querystring, and the package will take it
from there!
Page example
<img src="/Content/images/image.png?w=105&h=90" width="105" height="90" />
Instead of:
<img src="/Content/images/image.png" width="105" height="90" />
Please note to use width and height tags in your <img>
tag to stop the page from double-paints.
Optimizing CSS and J scripting
To continue the tutorial from here, please install the following from the NuGet Package Manager:
Cassette.Aspnet
Cassette.Less
The goal
To minify, bundle, and render compact versions of only the required CSS an JS.
Implementation (CSS)
Create a folder in Content called LessCss.
In LessCss, create subfolders for the categories of CSS needed (optional). You can also use standard
.css files (if you don't want to convert them to .less).
This tutorial will assume the following structure:
(For the .less files)
Content
- LessCss
- jQueryCore
- MainTheme
(For the .css files)
Content
To convert a .css file: Place it in the desired category in
LessCss, change the extension from '.css' to
'.less', open the '.less' file, and click Save. This will make your compiler automatically generate the necessary files. You can continue to edit the file from there, or close it.
In the Infrastructure folder (create in the root directory if you do not
have one already), and create a class called 'CassetteConfiguration.cs'. Paste the following in there:
public class CassetteConfiguration : IConfiguration<BundleCollection>
{
public void Configure(BundleCollection bundles)
{
bundles.Add<StylesheetBundle>(
"Content/lesscss",bundle => bundle.EmbedImages().EmbedFonts());
bundles.Add<StylesheetBundle>(
"Content/css", bundle => bundle.EmbedImages().EmbedFonts());
}
}
This will tell your site to use all the stylesheets located in the set directories, bundle them all up into a package, and minify them.
Page example
In the desired page (preferably the _Layout page), you will need to tell your site to reference your created bundles. Do so by adding the following code before
the <!DOCTYPE html>
tag:
@{
Bundles.Reference("content/lesscss");
Bundles.Reference("content/css");
}
After that, you simply need to add @Bundles.RenderStylesheets()
in your
<head>
tag to render the result.
Notes
Stylesheets often require some order to display content properly. To properly order the way your stylesheets are loaded add a file called 'bundle.txt'
in both Content/LessCss and Content/css. In the bundle.txt file, make a list on the order of the
CSS files loaded. *Make sure not to load the .less (as it compiles to .css).
MainTheme/global.css
MainTheme/header.css
MainTheme/body.css
MainTheme/footer.css
jQueryCore/example1.css
jQuertCore/example2.css
etc.
Implementation (js)
This tutorial assumes you have all your scripts in a Script folder in the root directory.
In CassetteConfiguration
, paste the following below the stylesheet bundle:
bundles.AddPerSubDirectory<ScriptBundle>("Scripts");
This will tell your sites to use all the scripts located in the set directories, bundle them all up into a package, and minify them.
Page example
In the desired page (preferably the _Layout
page), you will need to tell your site to reference your created bundles. Do so by adding the following code underneath your previously referenced bundles:
Bundles.Reference("scripts");
After that, you simply need to add @Bundles.RenderScripts()
[preferably] at the bottom of all your content, within your
<body>
tag, to render the result.
Notes
To sort the loading of your scripts, you need to create a folder called '_reference.js' (if there is none already) and create a list on the order of the js files loaded.
This file must be in the same directory as your js files.
/// <reference path="jquery-2.0.2.js" />
/// <reference path="jquery-2.0.2.intellisense.js"/>
/// <reference path="jQuery.Placeholder.min.js"/>
/// <reference path="modernizr-2.6.2.js" />
/// <reference path="jquery-ui-1.10.3.js" />
/// <reference path="jquery.validate.js" />
/// <reference path="jquery.validate.unobtrusive.js" />
/// <reference path="jquery.unobtrusive-ajax.js"/>
/// <reference path="jquery.bpopup.min.js"/>
References
- Darren Whitfield as 'The Author' - 04 July 2013 – Sources respective to the projects, common knowledge, and various forms of research.