The importance of being Small (AKA bundling and minification)

By AdamJuly 14, 2017 at 2:50 PM

When developing a web application, one must think about optimising the user experience.  And one of the things one must think about is the number and size of the files being downloaded.  

If you have ever gone to a web page where they have forgotten to optimise the graphics and you have a 2MB background picture; it can be painfully slow.  But one thing that many people forgot about is that most browsers can only download a small number of files at once, so the more files you have, the longer it will take the site to load.

Here at Cognitive X Solutions, we use the Angular framework for developing web sites that approach the speed and ease of use of a desktop application, and we do it with Microsoft's Typescript, which allows us to manage our JavaScript code bases with a greater level of ease, all the while helping us catch errors before they make it into production.  But combined, we end up with sometimes 100s of Javascript files.  Which is simply not acceptable for developing fast user experiences.

So what we do is we bundle and minify our javascript.  Simply put, we combine all of those 100 files into 1 or 2 larger files (that's bundling) and then we strip out all comments, extra lines and spaces, and apply optimisations to the JavaScript itself so that the resulting file(s) are much smaller.  (It has the (un)fortunate side effect of making the JavaScript extremely hard to read).

Originally we were doing this with a technology called Browserify, which analyses the interdependencies of our JavaScript files and produces a single file output that has all dependencies satisfied in an optimised way.  We would then combine this technology with another one called Gulp that would allow us to automate this process (it would watch for file changes and rerun Browserify when they did).  Gulp also handled compiling our CSS and inlining our HTML templates into a single file (Angular works by using templates, which without this inlining process meant that Angular, even if we combined it all into a single JavaScript file, would still be making calls to the server to load all those HTML snippets.  With inlining, we load one large file that contains all the snippets by name.  This allows a single call to be made to retrieve all templates, greatly increasing the speed / responsiveness of our web applications).

More recently, a new technology has come on the scene called Webpack.  Webpack is the official bundler of Angular 2 (we currently still use Angular 1.6+ as it has more llibraries available for it, Angular 2 was a complete rewrite of the technology and component libraries are still catching up), as well as the React framework (a competitor to Angular).  On one of our current projects, I decided to give Webpack a try.  And I was quite impressed.  It allowed me to accomplish in a much more succinct way (and in some cases more powerful way), what I had done with Gulp + Browserify.  The end result was that I combined all our JavaScript, HTML, and CSS into a single Javascript file.  So with one file download, a whole web application would spring to life.  That is powerful.  We will be switching our development practices to use this new technology so that our clients websites will experience this performance and responsiveness.

If you are interested in more information about exactly how we are using Webpack, you can check out my personal blog here

Posted in: Programming | Open Source

Tags:



DevJEDI Academy or #maritimedevcon 2016

By Sebastien AubeJune 6, 2016 at 9:27 AM

On the morning of June 4th, 2016 at 7:15 AM a contingent of seven padawans met at the Cognitive X Solutions offices to make the trip to Fredericton where fellow Padawans and DevJEDIs are hosting #martimtimedevcon. 

After a few years hiatus, the organisers brought it back in 2015 and in 2016 the conference has already gained some astonishing momentum.  Hundreds of developers and technologist congregated at the WU Centre to learn new tricks and news methods to wield the technology force and a few soft skill sessions brought in the mix. 

Among the many subjects, the overarching theme seemed to be building highly available, scalable and fault tolerant solutions. Topics such as Docker, the Actor Model, and Recursive Architecture helped us peer into the world of (micro, nano)services. As a dev padawan, I just want to dig deeper and see how we can apply these techniques to what we do at Cognitive X Solutions.

On the other hand, we were lucky to see presentations on soft skills such as product management, dealing with a complex project with tight deadlines and a presentation on making a presentation. What the presentation is for the audience and not for the presenter? There were some great tidbits in each of those presentations that I will indeed adopt or adapt in my daily activities.

Kudos to the organising team, sponsors and speakers for putting on such a great conference. I would give you the titles of dev Jedi, but you're probably too humble. We'll go with high padawan, seems to fit your persona better. This conference made many dev padawans happy.

Posted in: Learning | Programming

Tags:



ASP.NET MVC 4 and Mocking ModelState

By AdamAugust 23, 2012 at 8:37 AM

Actually, mocking isn’t quite the word (but we’ll talk about that in a moment).

At Cognitive X, we specialize in web development using ASP.NET MVC (currently using V4), and we very much love Test Driven Development.  So as part of our development process with MVC, we write tests for our Controller Actions.  One of the problems that we run into with testing controllers outside of the MVC framework is that they are not fully setup and many pieces are missing that allow the controller to function properly.  The biggest one being ModelState.

For example, given the following piece of code, no matter what, it always returns true because the ModelState is actually empty, when run outside the normal MVC pipeline:

if (ModelState.IsValid)
{
    // Perform action
}

So inorder to properly test our controllers, we wrote a method that would take the model and setup ModelState correctly (including running all validations on the model).  It was quite easy with V3 of ASP.NET MVC to do this, but with MVC 4 and the introduction of so many new providers (ModelMetaDataProviders, ValueProviders, etc), the old way no longer worked. I spent a morning chasing ModelStateDictionaries through the MVC code (thank goodness for ILSpy, it made my life so much easier), trying to figure out where it actually got filled out.  What I eventually hit upon was the code hidden within the Controller.TryValidateModel, which did exactly what I wanted it to do. The only problem is that it’s protected internal and no good for a general support extension.  So I pulled the code out, rewrote it a bit, and here it is:

public static void SetupModel<T>(this Controller ctrl, T model)
        {
            if (ctrl.ControllerContext == null)
            {
                Mock<ControllerContext> ctx = new Mock<ControllerContext>();
                ctrl.ControllerContext = ctx.Object;
            }

            DataAnnotationsModelMetadataProvider provider = new DataAnnotationsModelMetadataProvider();

            var metadataForType = provider.GetMetadataForType(() => model, typeof(T));
            var temp = new ViewDataDictionary();

            foreach (var kv in new RouteValueDictionary(model))
            {
                temp.Add(kv.Key, kv.Value);
            }

            DefaultModelBinder binder = new DefaultModelBinder();

            ctrl.ViewData = new ViewDataDictionary(temp) { ModelMetadata = metadataForType, Model = model };

            foreach (ModelValidationResult current in ModelValidator.GetModelValidator(metadataForType, ctrl.ControllerContext).Validate(null))
            {
                ctrl.ViewData.ModelState.AddModelError(CreateSubPropertyName("", current.MemberName), current.Message);
            }
        }

So like I said, Mocking is not really the right word for it, it’s actually setting up ModelState to contain the right validation information / model errors, so that controller actions work as expected.

Posted in: Programming

Tags: