website and application performance - what a developer should do and why
DESCRIPTION
A great presentation by Wiliam Senior Developer, Jason Deacon, on why the performance of an application or website is the most important thing a developer can contribute, and how a developer can go about this. Some good benchmarks from a recent project we've executed.TRANSCRIPT
Performance
It really is a feature – © Wiliam Pty Limited – www.wiliam.com.au – 61 2 9978 8888
Performance?Performance is the result of specific, targetted optimisation efforts.
Performance is not limited to “how fast can this page load”.
Developer performance How long it takes to add new features to the project How long it takes to understand the structure of the project How hard is it to change existing features?
Application performance How many concurrent users can the site sustain? What server resources does it require to maintain that many
users? What is the projected load for the application in six months?
One year? Two years? When will it fall over?
Optimise what?
Optimisation comes in many forms:• Maintainability• Easier to read code• Useful comments• Unit testing
• Code reuse• Decoupled class structures• Clean usage patterns• Flexibility within custom classes.
• Performance• Reduce workload per request, resulting in quicker requests• Algorithmic simplicity, relates to the first point.
Generally, optimising for one of those targets is at the expense of the others.
Steps to optimise1. Plan ahead
1. Know your data set requirements. 300 or 30M users?2. Know your processing requirements
2. Measure1. From day one, know how long your application takes to
perform the most common tasks2. Establish a baseline3. Watch for any drops in performance during development
3. Fix1. Cache is a crutch. Your app should be as usable without
caching as it is with it.2. Target the hot spots first that you identified through step
2
4. goto 2
Platforms Umbraco V4 (a.k.a black box)
Suited to small content sites Absolutely not an enterprise system Falls over with large data requirements
Umbraco V5 is a major improvement on V4 Unproven in the field New architecture appears to be more performant It’s shit, and now dead.
ASP.NET MVC3 (MVC4 currently in RC) Current ideal solution for performance or data critical
websites Maximum control Suited to small and large sites alike
Layer: Database Data structure requirements
Field lengths – Don’t use varchar(2000) when you only need varchar(150)
Table structure; relationship tables – keep it simple and keep it minimal
Indexes; Minimal to start with, only add after you are sure they will provide a positive impact
Field necessity – question the need for fields, don’t add unused fields
Denormalisation Can be useful in very specific circumstances Is essentially duplicate data, so ensure you have a very good
reason for doing it. Question everything you are being told about how much data
the site will need to cater for If in doubt, assume twice as much as what you are being told.
Better to make it ‘too quick’ rather than ‘too slow’
Layer: Data access Commonly the most expensive part of most web
requests Number of DB calls can get out of control
extremely quickly if not monitored Entity Framework
Do not lazy load Use .Include("MyNavigationPropertyName") to include
related data Do not be afraid of using a custom stored procedure if
the EF generated query is out of control, but link it through EF.
Limit the number of results you select to avoid the 'Unbounded Select Statement' trap
Layer: Application Logic (not MVC layer) Reduce the number of steps that a request
has to take in order to complete Don't implement layers of interfaces and classes.
Fewer hops the better. Single responsibility rule, helps to optimise
later on Flexibility at the cost of performance Ensure application logic performs consistently.
Methods with 'fuzzy logic' can skew results and make it harder to track down performance bottlenecks
Layer: Interface Logic & Interaction This layer is the 'Controller Actions' in MVC
terms Extremely important. Treat calls into App Logic
layer as very expensive and minimise them as much as possible
Layer: Http Requests/Responses Network IO is slow and therefore expensive. No pointless HTTP redirects Where it makes sense, store data on the
outbound request Ajax calls that return large blobs of html
should generally be avoided. Return JSON and react to that instead.
Layer: Client Side Reduce the number of requests per page
(Images, CSS files, Javascript files)
Browsers have a limit of concurrent connections per domain. 4-15 depending on browser and version
ETags and Cache Expiry
Observed Thresholds
Item Excellent
Okay Not Ideal
Time to generate page on server
<50ms 51ms to 150ms 151ms to infinity
Overall page load time <200ms 201ms to 600ms
601ms to infinity
Average HTTP requests per page load
<10 11 to 40 41 to infinity
Average Page Download Size
<500KB 501KB to 1024KB
1025KB to infinity
Caching Cache is a crutch
Hides the underlying problems of sites that are poorly built
There are different types of caching Caching data access Caching application requests Caching client-side assets
Cache systems need a mechanism to clear them when data is modified Initiate calls from CMS -> WebApp to clear specific parts
of the cache based on user activity Cache systems should be able to be reported on, to
track and then tweak their performance Without reporting, everything you do is unproven.
Processes Measure Early, Measure Often
See when things go sideways
Establish performance benchmarks Min/max times for your site to load/perform tasks
Cache is a crutch, until it isn't.
Developers responsibility
Tools MVC MiniProfiler
WAPT and other load testing tools
SQL Tuning Wizard
LINQ – Your best friend, your worst enemy Don’t use if (something.Count([condition]) > 0)
Use .Any([condition]) instead LINQ is easy for developers to use, but at a
(sometimes extreme) performance cost. Try to avoid it in performance critical scenarios.
Avoid Parallel LINQ (PLINQ) in web applications except in very specific scenarios. Understand the consequences of parallelising code in an already multithreaded environment.
MVC 3 Use View(“~/views/shared/someview.cshtml”,
myModel) instead of (“someview”, myModel). MVC has to search the view paths for the
‘someview’ view if you do not specify a path, which can be costly
Minimise the use of @Html.ActionLink Order routes in the global.asax.cs by most
used to least used Route collection is searched start to end for each
request based on the incoming path structure Can use a Route extension to test the route
validity in a quicker way than the default route test
Linq – Your best friend, your worst enemy .Count() – Don’t use it unless you don’t have a choice, even then, remember to feel bad.
public static int Count<TSource>(this IEnumerable<TSource> source){ if (source == null) { throw Error.ArgumentNull("source"); } ICollection<TSource> collection = source as ICollection<TSource>; if (collection != null) { return collection.Count; } ICollection collection2 = source as ICollection; if (collection2 != null) { return collection2.Count; } int num = 0; checked { using (IEnumerator<TSource> enumerator = source.GetEnumerator()) { while (enumerator.MoveNext()) { num++; } } return num; }}
Entity Framework Use .Include(..), lazy loading is a death-trap.
Entity Framework Don’t go overboard, .Include(..)ing too much will have a very
negative effect on performance
Case Study – Media Monitors 87 MVC routes, 45 database tables, 7 stored procedures Homepage
Time dropped from 89ms / 6db to 7.1ms / 0db with data caching & optimisations. Difference of 81.9ms.
Increased from 674 sppm to 8450 sppm (11.2/s to 140.8/s) 7776 more chances per minute for users to purchase something 970,000 to 12.1 million pages over 24 hours
Footprint: Cold: 19 requests, 894KB
20K Html, 300K JS, 505K Images Warm: 3 requests, 25.8KB
20K Html, 5K Favicon
SquishIt – used combine CSS and JS into a single client-side file CSS Sprites Layering;
Database Entity Framework *Logic Actions
Case Study – Media Monitors
Case Study – Media Monitors
Note: Old Build
20 concurrent users saw 240 pages per second with IIS using 300MB memory(i7 920 Quad core w/ hyperthreading)
Case Study – Media Monitors
Response time range 20ms to 95ms under load
Themes Control is king. Ability to tweak and
customise to achieve goals of the project is extremely important.
Keep it simple, keep it clean.
Complacency breeds mediocrity.
Hard Truths Building a poorly performing website is a
failure to do your job. It’s equivalent to Ferarri using lawnmower
engines in their cars. Looks great, goes like shit. Slow websites reduce the effectiveness of
the project, which only reflects poorly on the developer(s).