.NET Oxford November Meetup: Performance in the Javascript Era

21 November 2018 - .NET , dotnetoxford , Meetups

This month at .NET Oxford, we had Benjamin Howarth joining us to talk about Performance in the Javascript Era! Yes, I know - we're a ".NET" user-group - but not to worry - there was tons of server-side .NET in there too - so don't let the talk-title put you off!


This time, it was Matt's turn to do the intro talk, so I got to sit back and relax. Although, I did get a phone-call from him saying he was stuck in heavy traffic - so I almost had to do an ad-hoc intro-talk without any slides! Luckily, the bad traffic seemed quite short-lived, and he arrived in plenty of time.

He started with the usual house-keeping, then moved onto the news and prize-draws (see further down this post for details). The published slides for the intro talk are available here, and the Reveal.js source code can be found on our Github account.

Benjamin Howarth: Performance in the Javascript Era

I always enjoy talks where you come away with a lists of things you want to try out - and Benjamin's talk was most certainly one of those talks! I'm a big fan of leveraging developer tooling to increase productivity and output - and a core focus in this talk was around different tools that you can use to help you with your application performance. Further down this post, there's a list of links to all the tools he referenced - but I'll also try to cover most of them here too.

His talk was split into three sections - frontend performance tools; server-side performance tools; and also a section on how we can improve - including tools for monitoring. This final section also included a very useful looking Dockerfile he wrote to automatically test a lot of stuff! I cover this further down the post.


One of the first tools he covered was a tool called YSlow. This is a browser extension that is available for most popular browsers, and also as a command line utility. Unfortunately, it's quite an old project that no longer seems to work - at least for the Chrome extension. I tried fixing some of the issues, but I kept hitting more and eventually gave up as I didn't want to spent too much time on it. The bookmarklet also didn't work against this site which uses https as Chrome complained it was trying to load mixed content when loading the yslow js file. I know Benjamin was using Opera, and he said he was using a modified version. It's a shame as it looked quite a useful utility!

The yslow webpage has a list of "Web Performance Best Practices and Rules" that yslow tests against. Benjamin picked a few out to go through. Here are the ones he focused on ...

Use a Content Delivery Network: CDNs allow your static content to be both cached and closer geographically to your users. Benjamin also recommended that you ensure your static content is on a separate domain to your dynamic content. This stops all of your cookies being sent for all your static content requests. Obviously, if you're using a service like Cloudflare infront of your entire site, this won't give you this if your content is on the same domain, so Benjamin recommended ensuring that all your static content is on a separate domain, then having that behind a CDN.

Add an Expires or a Cache-Control Header: If you know that content isn't going to change, then use this to tell the browser to cache this request for a certain period of time. As an example, he showed the amount of requests his example Verbier website was making in the browser devtools 'Network' tab. Explaining that by not specifying an expires header, then browser doesn't know that it doesn't need to get the resources again.

Gzip Components: According to the YSlow description on this one, "Gzipping generally reduces the response size by about 70%" - which is a pretty good win for the sake of just adding an HTTP header.

Put StyleSheets at the Top: Put CSS stylesheets in the HTML HEAD. If you put it at the bottom, in some browsers, this will block rendering to avoid the browser having to change styles once it loads the CSS.

Minify JavaScript and CSS: Benjamin spoke a lot about the importance of keeping your request sizes down. He points out that your users are quite likely nowadays to be on a mobile device, which may have a slow connection. He also talked about avoiding lazy loading in SPA apps for this reason. If your user is moving between good an bad connections (say on the London Underground) - if their views suddenly can't load - then they're going to get a poor experience. Whereas, if your views are pre-loaded - even if the AJAX API calls can't get the data itself, you can still provide a nicer experience as the user navigates the different views.

Configure ETags: ETags are a hash representation of the content of the page that gets returned in a response. The browser can then send this back to the server next time in the request, and if the server detects that same hash, it can return a 304 response (not modified).

Do Not Scale Images in HTML: Avoid having images larger than you actually need. If you're specifying a width and height to downscale an image, then you're unnecessarily downloading the larger image size to the users' browser.


The next tool that Benjamin talked about was project Lighthouse. This is actually now built-in to Google Chrome! If you open the Chrome DevTools and switch to the 'Audit' tab - that is Project Lighthouse! It can also run from the command line, and also as a Node module - meaning that it can be run automatically as part of your CI/CD system.

This performs a whole bunch of performance, PWA, accessibility, SEO, and best practice tests - then gives you a score on each, plus suggestions and recommendations on how to improve. I've just run it on this website, and it literally took seconds. Given I haven't intentionally looked into any of this kind of stuff for my blog, I was quite pleased with the results! ...


It's made a few suggestions that I'll fix, but other than the PWA (I have no manifest, so it's not surprising!) - it seems pretty good!

Benjamin demoed this using a local version of the Verbier.com site. He spoke about some of the different results and suggestions that came back, as well as giving some stats about the benefits of ensuring your site performs well. Some interesting stats he mentioned was that Walmart had found that for every 100ms they improved page loading, they saw a 1% uptick in revenue. Given about how many billions Walmart makes per year - this is A LOT of money!


Another Tool he talked about was WebPageTest. This tool enables you to test your website speed from multiple locations around the globe, simulating different connection speeds.

The results of this also has a section called "What Does My Site Cost?". This calculates a price that your website is costing your end-users in different part of the world. To quote the description on their results page: "This is the cost of the site based on data from the ITU, without any adjustment for purchasing power or relative affordability. Prices were collected from the operator with the largest marketshare in the country, using the least expensive plan with a (minimum) data allowance of 500 MB over (a minimum of) 30 days. Prices include taxes. Because these numbers are based on the least expensive plan, they are best case scenarios."

Again, like the other tools, this has a command line version that can be run as part of your automated tests in your build system.


After the break, Benjamin then moved onto server-side tools. The first being Apache JMeter. This is a Java based load testing tool. It has a GUI, but Benjamin suggests that you'll mostly be using it outside of the GUI - just using the GUI for creating test plans, then exporting XML files for automation. He demoed this again on one of his sites, simulating 200 users doing 50 request each (so 10,000 requests). He showed that you can use this, not only or GET requests, but also POST, PUT, etc too. The user interface for setting up these requests looked very Postman-like. He also said that one thing he does is create a sitemap.xml file, and imports that into JMeter.


The next tool he showed was MiniProfiler. This is a profiler for both .NET, Ruby, Go, and Node.js. It allows you to instrument database called, and also explicitly specify your own bit of code you'd like to instrument. It also has plenty of extensions to extend this even further. Benjamin demoed this using his verbier.com site, showing the overlay that appears in the website with various stats on both database calls (showing the SQL), and also other timing information.

A performance issue he said he'd found with this tool was where a site was using the C# dynamic keyword when processing a carousel in a Razor view. This processing was taking 4 seconds, and by removing the use of dynamic and switching to serialisation using statically-typed classes, he managed to get it down to 142ms! He describes how the runtime internally throws exceptions when processing dynamic types, which whilst handled internally, are still very slow. In his own word - he described dynamic as 'evil' and promised to come and pair-program with anyone in the room until all uses of dynamic was gone from their codebases! I might just take him up on this just to get some cheeky performance tips whilst he looks through my code!


The next tool on the list was Glimpse. This is a tool that you can add to your ASP.NET project, and it'll give you a ton of information right in your browser - with a very head-up display experience. This includes performance stats both on the client and server-side; database query stats; and much more. Here's a nice blog post by Scott Hanselman about Glimpse with a bunch of screenshots showing how this works.

Unfortunately, as Benjamin points out - this project seems to have gone offline a few years ago. Whilst it still works - there hasn't seemed to be any further work done on it in a long time, and their website is no longer available. It's a shame, as this is a fantastic tool. Whilst, not quite the same - there is another tool by Stackify called Prefix that does similar (see my dev-tip below).

Wrapping up

In the last section, Benjamin summarises some key points, talking more about CDNs, HTTP2, caching, minification, and much more. And he also talked about tools you can use to monitor performance and gain insites from live applications. He touched on tools like NewRelic and Application Insights.

He also showed off a rather detailed looking Dockerfile which ran most of the tools he mentioned in this talk! It was a Windows image, and ran most of the tools using Powershell. I believe he's going to put this on Github - so I'll provide a link to it if he does. When he asked if anyone had any questions at the end, I asked if he'd tried it with a Linux base image. He hadn't, as it was also running webform tests. If he does put it up on Github, I might try it in a Linux container by stripping out the WebForm tests, and targeting testing ASP.NET Core apps. It looked extremely useful for automating these tests as part of your build pipeline!

Benjamin's talk was littered with tons of useful tips. If you missed it, and can't see him talk in person, I'd highly recommend listing to his talk online (see the links below). He has also very recently appeared on one of my favourite podcast shows - .NET Rocks! In fact, I believe he's been on a few times now.

A massive thank you again to Benjamin for joining us.


Dev Tips

As usual at the end, we had our "dev tips" section. Where anyone can get up and do a 30-second dev-tip. Below are the ones we had this month. If I missed anyone off, then do let me know, and I'll update the list below.

Dan Clarke: PRs in the workplace

"If you use Git in your workplace and don't already use Pull Requests, then consider giving it a go. A company I'm currently working with is the first team I've worked with that uses PRs. One thing I've found is that pretty much all PRs (no matter the experience level of the dev who created it) tends to require some form of change, fix, or improvement. If it hadn't been for using PRs - those improvement / fixes wouldn't have been made! I've actually recently blogged about this, and my post can be found here."

Matt Nield: Knowledge Sharing

"Make time to share the things that you learn. Not only will this pass on knowledge, but explaining your new discovery can help you to understand it more yourself. Don't be concerned if you assume that it's something everyone already knows; assumptions have a certain reputation."

Guy Fletcher-Wood: Track Technical Debt

"A good way to keep track of technical debt is to enter your bodges as issues on GitLab/JIRA/whatever your issue tracker is. Having a list doesn't pay off any tech debt, but it does help you to prioritise, and it can also help to show project management the extent of the problem."

Benjamin Howarth: ZoomIt

"If you're on a conference call and are sharing your screen, use Zoomit, part of Microsoft's free Sysinternals toolkit, to be able to zoom in to a section of your screen with a quick shortcut (Ctrl+1). It supports snipping and drawing on the zoomed-in section too, great for highlighting parts of the UI that need it for those sorts of conference calls or group sessions, and is an absolute must-have if you ever do any public technical speaking at meetups or conferences."

Dan Clarke: Stackify Prefix

"Benjamin mentioned Glimpse a few times in his talk, which reminded me of a similar (but perhaps not quite the same) tool called Prefix by Stackify. You run this locally during development, and it'll give you detailed insights into your web requests during development. Including database queries!"


News Items

Being Matt's turn to do the intro - I had no idea what news items were coming up. To be honest, I've been a bit behind catching up in the news this month. Here's are the news items that Matt mentioned...

Primary Sponsors - Corriculo Recruitment

As usual, a massive thank you to our Primary sponsor - Corriculo Recruitment! An integral part of the .NET Oxford team, helping us out in so many different ways. Not only helping us out financially, but also welcoming people in on the doors, supplying and serving drinks and refreshments, helping us with marketing and promotion, and much more!

Secondary Sponsor - Everstack

Our secondary sponsor is my own company, Everstack. Providing a lot of my own time for organising and managing .NET Oxford. Everstack provides software development and consultation services - specialising in .NET and the Cloud.

Prize Draws

After the news, we then moved onto the prize draws, using my usual WPF Prize Draw app. A massive congratulation to the winners, and a massive thank you to our awesome prize draw sponsors ...


Congratulations to Richard Bygrave for winning a year-long Jetbrains product licence!

Manning Books

Congratulations to Morgan Willis for winning a Manning ebook! The winner has the choice of any of the awesome Manning ebooks from their website.

Remember that we have our special Manning coupon code (ug367) which gives all of our members a 36% discount on any of their e-books! They've also asked me to share a link to some of their new courses for their LiveVideo system.


Congratulations to Hubert for winning the Oz-Code licence!

For those that don't know, Oz-Code is a Visual Studio extension that puts your debugger on steroids. Take a look at their website for videos of their features. If you haven't checked it out, then definitely download the trial and have a play. All our member get a free 3 month trial licence (see below) or 50% off a full licence! To claim, you can visit this link to pick up your licence!


Upcoming Meetups

Below are our upcoming meetups. We'll be announcing more meetups for next year shortly, and if you subscribe to the meetup group, you'll get email notifications as they are announced.

December: More Lightning Talks!

In December, we have another lightning talk event. All slots are currently taken and here are the talks (in no particular order) ...

  • "A Crash Course in Vi" - Dan Clarke (ie. me!) (15mins)
  • "WSL - Linux on Windows? Don't be BASHful!" - Stuart Leeks (10mins)
  • "Elm" - James World (15mins)
  • "Building Xamarin Apps on Azure" - Paul Harding (20mins)
  • "Value converters in EF core" - Tom Lane (5mins)
  • "Building and consuming nuget prerelease packages as part of your development workflow" - Matt Davidson (20mins)

Link to Meetup.com event page

January 2019: NGINX for .NET Developers - Ian Cooper

In January, Ian Cooper will be back (after his very popular 12 Factor App talk) earlier this year. This time, his talk will be all about NGINX for .NET developers!

Link to Meetup.com event page

February 2019: .NET Internals - Chris Bacon

In February, we'll be delving a bit deeper under the hood into .NET with Chris Bacon talking about .NET Internals.

March 2019: Functional C# - Simon Painter

Our March meetup will be with Simon Painter talking about writing Functional C#. This hasn't yet been announced on Meetup.com, but will be shortly.

April 2019: Uncle Bob!

We're very excited to announce that in April, we'll be joined by Uncle Bob himself! A topic hasn't yet been decided - but we'll be announcing this on Meetup very shortly. We're going to aim for the larger St Aldates venue next door (where we had the Jon Skeet event) for this one.

May 2019: Lightning Talks

We're thinking of another lightning talk event for May. If you're interested in doing a 10/15/20 minute talk - then let us know!

Please retweet if you enjoyed this post ...


Recent Posts

Featured Posts

.NET Oxford Links