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.
3. 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?
4. 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.
5. Steps to optimise
1. Plan ahead
1. Know your data set requirements. 300 or 30M users?
2. Know your processing requirements
2. Measure
1. From day one, know how long your application takes to
perform the most common tasks
2. Establish a baseline
3. Watch for any drops in performance during development
3. Fix
1. 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
6. 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
7. 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‟
8. 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
9. 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
10. 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
11. 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.
12. 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
13. Observed Thresholds
Item Excellent Okay Not Ideal
Time to generate page on <50ms 51ms to 150ms 151ms to infinity
server
Overall page load time <200ms 201ms to 600ms 601ms to infinity
Average HTTP requests per <10 11 to 40 41 to infinity
page load
Average Page Download <500KB 501KB to 1024KB 1025KB to infinity
Size
14. 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.
15. 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
16. Tools
MVC MiniProfiler
WAPT and other load testing tools
SQL Tuning Wizard
17. 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.
18. 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
19. 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;
}
}
21. Entity Framework
Don‟t go overboard, .Include(..)ing too much will have a
very negative effect on performance
22. 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
24. 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)
25. Case Study – Media Monitors
Response time range 20ms to 95ms under load
26. 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.
27. 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).