{"id":199,"date":"2015-04-15T18:30:54","date_gmt":"2015-04-16T00:30:54","guid":{"rendered":"http:\/\/www.managerjs.com\/blog\/?p=199"},"modified":"2015-04-16T17:30:29","modified_gmt":"2015-04-16T23:30:29","slug":"managerjs-web-performance-grades","status":"publish","type":"post","link":"https:\/\/www.managerjs.com\/blog\/2015\/04\/managerjs-web-performance-grades\/","title":{"rendered":"Talkin&#8217; &#8216;Bout Your Web Perf"},"content":{"rendered":"<p class=\"p1\">I&#8217;ve had a lot of luck using this article to push performance conversations further.\u00a0The numbers are dated but the concepts are real.<\/p>\n<p class=\"p1\">You have to know how good is good enough. How bad is too bad to tolerate. You have to separate user interactions by value and user expectations. Here I break down user expectations and give some (lenient) standards that ought to be worth discussing (and keep people from setting their hair on fire).<\/p>\n<h1 class=\"p1\">Web Sites Don&#8217;t Get Special Dispensation<\/h1>\n<p class=\"p2\"><span class=\"s1\">The guidelines for latency limits are not new. For example, the advice given in <a href=\"http:\/\/www.useit.com\/papers\/responsetime.html\"><span class=\"s2\">Response Times: 3 Important Limits<\/span><\/a> is over 40 years old, but still generally true.\u00a0 In fact, special guidance to web-site operators only tends to emphasize how more and more impatient our users\u00a0are becoming.\u00a0 Consider these excerpts from a white paper by Gomez entitled <a href=\"https:\/\/almtools.ldschurch.org\/fhconfluence\/download\/attachments\/990794\/wp_why_web_performance_matters.pdf?version=1&amp;modificationDate=1305831410682&amp;api=v2\"><span class=\"s2\"><i>Why Web Performance Matters: Is Your Site Driving Customers Away<\/i><\/span><\/a>:<\/span><\/p>\n<blockquote>\n<p class=\"p3\"><span class=\"s1\">The average online shopper expects your pages to load in <b>two seconds or less, down from four seconds in 2006<\/b>; after three seconds, up to 40% will <b>abandon your site<\/b>.<\/span><\/p>\n<p class=\"p3\"><span class=\"s1\">Gomez&#8217; own studies reveal [a] lack of visitor loyalty. By analyzing page abandonment data across more than 150 websites and 150 million page views, Gomez found that an increase in page response time from 2 to 10 seconds increased page abandonment rates by 38%.<\/span><\/p>\n<p class=\"p3\"><span class=\"s1\">[The] average impact of a <b>1-second delay<\/b> meant a <b>7% reduction<\/b> in conversions.<\/span><\/p>\n<\/blockquote>\n<p class=\"p2\" style=\"text-align: right;\"><span class=\"s1\">(original emphasis.)<\/span><\/p>\n<p class=\"p2\"><span class=\"s1\">The industry advice continues on and on: incremental decay in performance causes decay in retention and conversion. Slowing down matters. A lot.<\/span><\/p>\n<h2 class=\"p1\"><span class=\"s1\">Shades of Success and Failure<\/span><\/h2>\n<p><!--more--><\/p>\n<p class=\"p2\"><span class=\"s1\">We often boil this all down to &#8220;How long is too long?&#8221;\u00a0 We want a line in the sand.\u00a0 The problem with that is it doesn&#8217;t express the continuum of bad consequences that arise from bad performance.\u00a0 There isn&#8217;t a magic upper limit to response times. We can&#8217;t naively say, &#8220;As long as the response time is better than X we&#8217;re OK, but once it crosses X there&#8217;s a crisis.&#8221;<\/span><\/p>\n<p class=\"p2\"><span class=\"s1\">There is certainly a <b>lower limit<\/b> on how fast something operates: getting an operation to return in 500 microseconds instead of 2 milliseconds isn&#8217;t going to pay dividends if the observer is a human.\u00a0 We just can&#8217;t tell the difference. \u00a0<\/span><\/p>\n<p class=\"p2\"><span class=\"s1\">Instead of asking how long is too long, start with how fast is fast enough. This helps us limit our investment in things that are already doing well enough.\u00a0 Remember, this is only applicable to <i>human<\/i> interaction.\u00a0 When something is &#8220;fast enough&#8221; it gets an &#8220;A&#8221;.\u00a0 At that point, the return on investment falls off &#8212; sometimes dramatically.<\/span><\/p>\n<p class=\"p2\"><span class=\"s1\">The <b>upper limit<\/b> of latency &#8212; the demarcation of total failure &#8212; is harder to quantify and certainly less static.\u00a0 The lower bound on latency is caused by physiological limitations in the human body. The upper bound is subject to the changing expectations of ever refining tastes.<\/span><\/p>\n<p class=\"p2\"><span class=\"s1\">With this in mind it should be clear that a set of criteria for judging grades of success will be subject to change.\u00a0 However, that doesn&#8217;t stop us from making our current, best guess.<\/span><\/p>\n<table class=\"t1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"td1\" valign=\"top\">\n<p class=\"p4\"><span class=\"s1\"><b>Grade<\/b><\/span><\/p>\n<\/td>\n<td class=\"td2\" valign=\"top\">\n<p class=\"p4\"><span class=\"s1\"><b>Motto<\/b><\/span><\/p>\n<\/td>\n<td class=\"td3\" valign=\"top\">\n<p class=\"p4\"><span class=\"s1\"><b>Notes <\/b><\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">A <\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">Leave it Alone <\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">From a human factors perspective, it is wasteful to make it faster than this.\u00a0 You&#8217;re stealing from other features that need remediation or creation. <\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">B <\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">Acceptable <\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">Users will generally be pleased by this.\u00a0 A margin (up to 10%) of the snobbiest (most discerning) users will still be dissatisfied. <\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">C <\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">Tolerably Slow <\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">Users will generally dislike this, but tolerate it.\u00a0 Up to 20% of your users may fail to convert or continue the flow simply because of performance. Snobby (highly discerning) users will declare this a total failure. <\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">D <\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">Dangerously Slow <\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">Majority of users will deem this unacceptable relative to their other web experiences. <\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td4\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">F <\/span><\/p>\n<\/td>\n<td class=\"td5\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">Automatic Ship-Stopper <\/span><\/p>\n<\/td>\n<td class=\"td6\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">Unusable for all but the most intensely motivated users. <\/span><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2 class=\"p1\"><span class=\"s1\">User Expectations Vary Across Categories of Interaction<\/span><\/h2>\n<p class=\"p2\"><span class=\"s1\">Again, there is no clear line between success and failure. To make matters worse not all operations have to meet the same standards. Users allow some operations to take longer than others based on many complex factors. Let&#8217;s\u00a0boil these down to four categories of interaction, represented in the following table. We name each category, give an example of an interaction falling roughly into that category, and a typical black-and-white limit for that category based on articles like those mentioned above.<\/span><\/p>\n<table class=\"t1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"td7\" valign=\"top\">\n<p class=\"p4\"><span class=\"s1\"><b>Category<\/b><\/span><\/p>\n<\/td>\n<td class=\"td8\" valign=\"top\">\n<p class=\"p4\"><span class=\"s1\"><b>Example<\/b><\/span><\/p>\n<\/td>\n<td class=\"td9\" valign=\"top\">\n<p class=\"p4\"><span class=\"s1\"><b>Typical Limit<\/b><\/span><\/p>\n<\/td>\n<td class=\"td10\" valign=\"top\">\n<p class=\"p4\"><span class=\"s1\"><b>Impression of the Interaction<\/b><\/span><\/p>\n<\/td>\n<td class=\"td11\" valign=\"top\">\n<p class=\"p4\"><span class=\"s1\"><b>Notes<\/b><\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td12\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">Point <\/span><\/p>\n<\/td>\n<td class=\"td13\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\"><b>Stimulus<\/b>: click on a check-box <\/span><\/p>\n<p class=\"p2\"><span class=\"s1\"><b>Response<\/b>: check mark appears <\/span><\/p>\n<\/td>\n<td class=\"td14\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">100 ms <\/span><\/p>\n<\/td>\n<td class=\"td15\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">What interaction? The computer is invisible. <\/span><\/p>\n<\/td>\n<td class=\"td16\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">The user does not tolerate a perceptible delay.\u00a0 The expectations on these interactions are so high that a round trip to the server is (generally) out of the question. <\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td12\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">Chunk <\/span><\/p>\n<\/td>\n<td class=\"td13\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\"><b>Stimulus<\/b>: click on a drop-down that lazy loads it&#8217;s content.<\/span><\/p>\n<p class=\"p2\"><span class=\"s1\"><b>Response<\/b>:\u00a0after a brief delay, the content appears in a relatively small portion of the screen<\/span><\/p>\n<\/td>\n<td class=\"td14\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">1.0 s <\/span><\/p>\n<\/td>\n<td class=\"td15\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">The computer is working for me. I&#8217;m in the flow. <\/span><\/p>\n<\/td>\n<td class=\"td16\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">Ajax interactions that change a small portion of the page generally fall in this category.\u00a0 <\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td12\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">Page <\/span><\/p>\n<\/td>\n<td class=\"td13\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\"><b>Stimulus<\/b>: click on a search result<\/span><\/p>\n<p class=\"p2\"><span class=\"s1\"><b>Response<\/b>:\u00a0a new article appears taking up most or all of the screen<\/span><\/p>\n<\/td>\n<td class=\"td14\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">3.0 s <\/span><\/p>\n<\/td>\n<td class=\"td15\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">Hmm.. That took a moment.\u00a0 I will allow it. <\/span><\/p>\n<\/td>\n<td class=\"td16\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">When the whole screen gets redrawn.\u00a0 We play games with user perception by getting something to render without waiting for everything.\u00a0 Be careful, if the user is actually waiting for something that is last to render then these games fail to improve perception. <\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td12\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">Commit <\/span><\/p>\n<\/td>\n<td class=\"td13\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\"><b>Stimulus<\/b>: click &#8220;Commit&#8221; at the end of a wizard. <\/span><\/p>\n<p class=\"p2\"><span class=\"s1\"><b>Response<\/b>: see prompt that the work is done and ready to be inspected <\/span><\/p>\n<\/td>\n<td class=\"td14\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">10 s <\/span><\/p>\n<\/td>\n<td class=\"td15\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">Wow, that was a lot of work. Good thing <i>that<\/i> doesn&#8217;t happen every day. <\/span><\/p>\n<\/td>\n<td class=\"td16\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">This is the upper limit on how much waiting a user is willing to do <i>in-flow<\/i>. You can&#8217;t have many pages like this. You really shouldn&#8217;t even show a spinner.\u00a0 The user should get concrete feedback on progress. <\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td12\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">Batch <\/span><\/p>\n<\/td>\n<td class=\"td13\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\"><b>Stimulus<\/b>: place a stamped envelope in the mail-box on the curb. <\/span><\/p>\n<p class=\"p2\"><span class=\"s1\"><b>Response<\/b>: read the snail-mail reply <\/span><\/p>\n<\/td>\n<td class=\"td14\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">&gt; 10 s <\/span><\/p>\n<\/td>\n<td class=\"td15\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">Huh? Oh yeah! I remember doing that, but my context needs to be totally rebuilt. <\/span><\/p>\n<\/td>\n<td class=\"td16\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">Anything taking longer than about 10 seconds ought to yield the context to the user and communicate completion some other way.\u00a0 Don&#8217;t hold the user staring at a spinner for 30 seconds.\u00a0 Too long! <\/span><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2 class=\"p1\"><span class=\"s1\">Slower Interactions Must Be Less Frequent Than Faster Interactions<\/span><\/h2>\n<p class=\"p2\"><span class=\"s1\">Slower interactions (like lazy-loading a product&#8217;s\u00a0information) should happen much less often than faster operations (like responding to a user click to draw a check-mark).\u00a0 The following graphic gives a qualitative feel for what this means:<\/span><\/p>\n<p class=\"p2\"><a href=\"http:\/\/www.managerjs.com\/blog\/wp-content\/uploads\/2015\/04\/2015-04-15-frequency-comparison.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-medium wp-image-200\" src=\"http:\/\/www.managerjs.com\/blog\/wp-content\/uploads\/2015\/04\/2015-04-15-frequency-comparison-300x174.png\" alt=\"2015-04-15-frequency-comparison\" width=\"300\" height=\"174\" srcset=\"https:\/\/www.managerjs.com\/blog\/wp-content\/uploads\/2015\/04\/2015-04-15-frequency-comparison-300x174.png 300w, https:\/\/www.managerjs.com\/blog\/wp-content\/uploads\/2015\/04\/2015-04-15-frequency-comparison.png 539w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p class=\"p2\"><span class=\"s1\">This image roughly says that Page interactions ought to occur much more often (meaning, at least an order of magnitude more often) than Commit interactions.\u00a0 Chunk interactions are much more frequent than Page. Finally, Point interactions are much, much more frequent than Chunk.<\/span><\/p>\n<p class=\"p2\"><span class=\"s1\">Keep this in mind when trying to decide what latency category an interaction belongs to.\u00a0 <\/span><\/p>\n<blockquote>\n<p class=\"p2\"><span class=\"s1\">Will the user do this rarely (less than daily)? Will they do it regularly (roughly every session)?\u00a0<\/span><\/p>\n<\/blockquote>\n<h2 class=\"p1\"><span class=\"s1\">Mean Stinks at Performance Requirements &#8212; We Use 95th Percentile<\/span><\/h2>\n<p class=\"p2\"><span class=\"s1\">If you suppose that 2 seconds is the acceptable latency for an operation, and testing reveals that the operation is returning in 1.8 seconds, <b>on average<\/b>, then have you succeeded? Probably not.\u00a0 Unless all instances of that operation complete in roughly the same amount of time there is a good chance that about 25% of your users are having an unacceptable experience.\u00a0<\/span><\/p>\n<p class=\"p2\"><span class=\"s1\">We don&#8217;t use average, we use 95th percentile.\u00a0 That allows for a tail of exceptional cases (which still matter but aren&#8217;t our focus) while giving a more correct impression about how fast the system is for <i>all<\/i> of your users.<\/span><\/p>\n<h2 class=\"p1\"><span class=\"s1\">Total User Experience Category Grades Measure End-To-End Latency<\/span><\/h2>\n<p class=\"p2\"><span class=\"s1\">We&#8217;re going to throw out Point and Batch interactions.\u00a0 Point interactions are so fast that we don&#8217;t expect a back-end call to be involved. Batch interactions are so long that we don&#8217;t expect their naked latency to be exposed to the user.\u00a0 That is, we expect such a long operation wouldn&#8217;t block the user from progressing by throwing up a spinner for several minutes.<\/span><\/p>\n<p class=\"p2\"><span class=\"s1\">Here are the guidelines for grading Chunk, Page, and Commit interactions. All numbers are in seconds, and according to the 95th percentile of the measurement.<\/span><\/p>\n<table class=\"t1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"td14\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">\u00a0<\/span><\/p>\n<\/td>\n<td class=\"td17\" valign=\"top\">\n<p class=\"p4\"><span class=\"s3\"><b>A+ <\/b><\/span><\/p>\n<\/td>\n<td class=\"td17\" valign=\"top\">\n<p class=\"p6\"><span class=\"s1\"><b>A<\/b><\/span><\/p>\n<\/td>\n<td class=\"td17\" valign=\"top\">\n<p class=\"p4\"><span class=\"s3\"><b>A- <\/b><\/span><\/p>\n<\/td>\n<td class=\"td17\" valign=\"top\">\n<p class=\"p4\"><span class=\"s3\"><b>B+ <\/b><\/span><\/p>\n<\/td>\n<td class=\"td18\" valign=\"top\">\n<p class=\"p6\"><span class=\"s1\"><b>B<\/b><\/span><\/p>\n<\/td>\n<td class=\"td19\" valign=\"top\">\n<p class=\"p4\"><span class=\"s3\"><b>B- <\/b><\/span><\/p>\n<\/td>\n<td class=\"td20\" valign=\"top\">\n<p class=\"p4\"><span class=\"s3\"><b>C+ <\/b><\/span><\/p>\n<\/td>\n<td class=\"td19\" valign=\"top\">\n<p class=\"p6\"><span class=\"s1\"><b>C<\/b><\/span><\/p>\n<\/td>\n<td class=\"td19\" valign=\"top\">\n<p class=\"p4\"><span class=\"s3\"><b>C- <\/b><\/span><\/p>\n<\/td>\n<td class=\"td19\" valign=\"top\">\n<p class=\"p4\"><span class=\"s3\"><b>D+ <\/b><\/span><\/p>\n<\/td>\n<td class=\"td19\" valign=\"top\">\n<p class=\"p6\"><span class=\"s1\"><b>D<\/b><\/span><\/p>\n<\/td>\n<td class=\"td21\" valign=\"top\">\n<p class=\"p4\"><span class=\"s3\"><b>D- <\/b><\/span><\/p>\n<\/td>\n<td class=\"td22\" valign=\"top\">\n<p class=\"p6\"><span class=\"s1\"><b>F<\/b><\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td23\" valign=\"top\">\n<p class=\"p6\"><span class=\"s1\"><b>Chunk<\/b><\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">0.27 <\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">0.37 <\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">0.50 <\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">0.75 <\/span><\/p>\n<\/td>\n<td class=\"td25\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">1<\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">1.4 <\/span><\/p>\n<\/td>\n<td class=\"td27\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">2 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">2.7 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">3.7 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">5.5 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">7.4 <\/span><\/p>\n<\/td>\n<td class=\"td28\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">10 <\/span><\/p>\n<\/td>\n<td class=\"td29\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">&gt;10 <\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td23\" valign=\"top\">\n<p class=\"p6\"><span class=\"s1\"><b>Page<\/b><\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">0.82 <\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">1.10 <\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">1.5 <\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">2.2 <\/span><\/p>\n<\/td>\n<td class=\"td25\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">3 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">4.0 <\/span><\/p>\n<\/td>\n<td class=\"td27\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">6 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">8.2 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">11 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">16 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">22 <\/span><\/p>\n<\/td>\n<td class=\"td28\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">30 <\/span><\/p>\n<\/td>\n<td class=\"td29\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">&gt;30 <\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td23\" valign=\"top\">\n<p class=\"p6\"><span class=\"s1\"><b>Commit<\/b><\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">2.7 <\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">3.7 <\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">5 <\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">7.4 <\/span><\/p>\n<\/td>\n<td class=\"td25\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">10 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">14 <\/span><\/p>\n<\/td>\n<td class=\"td27\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">20 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">27 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">37 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">55 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">74 <\/span><\/p>\n<\/td>\n<td class=\"td28\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">100 <\/span><\/p>\n<\/td>\n<td class=\"td29\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">&gt;100 <\/span><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"p2\"><span class=\"s1\">Notice that <b>each series progresses exponentially with a &#8220;B&#8221; being roughly OK<\/b>.\u00a0 We realize that this might lead to some easy to lampoon results.\u00a0 For example, what makes a 3.7 second response time a C- and a 20 an F? Sounds a bit like magic numbers. Still, we believe there is value in having a constant relationship between the grades.\u00a0 For example, it is useful to know that a B is exponentially worse than an A, and a C is exponentially worse than a B.\u00a0 Furthermore, performance improvements tend to become exponentially more difficult to achieve.\u00a0 So, improving from a D to a C is about as hard as improving from a B to an A.\u00a0 (If the progression were linear then it would be much easier to go from D to C.)<\/span><\/p>\n<h2 class=\"p2\"><span class=\"s4\"><b>Don&#8217;t Game Your Category<\/b><\/span><\/h2>\n<p class=\"p2\"><strong>WARNING:<\/strong>\u00a0A team may rationalize that a particular measurement is scoring so poorly because it has been miscategorized. For example, you say, &#8220;We can frabinaz in 3 seconds, which is a C for Chunk interactions; but, let&#8217;s just call it a page interaction and then we will have a B.&#8221; That works as long as the user experience is designed with that in mind.\u00a0 Calling something a &#8220;page&#8221; interaction means that we expect users to do it at least an order of magnitude less often than a &#8220;chunk&#8221; interaction, and we assume their expectations will be relaxed and forgiving.\u00a0 You can game the system with categories, but calling everything a Commit doesn&#8217;t achieve patron retention and conversion.<\/p>\n<h2 class=\"p1\">Assume Mobile (3G Budget)<\/h2>\n<p>If you have to simulate bandwidth then start with mobile bandwidth. Most general purpose sites can&#8217;t afford to ignore the mobile experience.<\/p>\n<h2 class=\"p1\"><span class=\"s1\">Keep Back-End Performance on a Tight Budget<\/span><\/h2>\n<p class=\"p2\">Sometimes back-end operations need to be implemented without a UI to surface them. You should still keep them on a tight budget. And it isn&#8217;t fair for the back-end to spend all of the performance budget.<\/p>\n<p class=\"p2\"><span class=\"s1\">According to <a href=\"http:\/\/www.amazon.com\/High-Performance-Web-Sites-Essential\/dp\/0596529309\/ref=sr_1_1?ie=UTF8&amp;qid=1429140403&amp;sr=8-1&amp;keywords=high+performance+web+sites\">High Performance Web-Sites<\/a>, back-end time for most Yahoo properties accounts for 10 to 20 percent of the total latency.\u00a0 Based on that, we budget 20 percent of total Page latency for back-end.<\/span><\/p>\n<p class=\"p2\"><span class=\"s1\">Since Chunk interactions should have far fewer assets, we double the back-end&#8217;s relative allotment of time to 40 percent.<\/span><\/p>\n<p class=\"p2\">Commit interactions should be dominated by the back-end latency of the interaction. They get a relative allotment of 80 percent.<\/p>\n<table class=\"t1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"td30\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">\u00a0<\/span><\/p>\n<\/td>\n<td class=\"td31\" valign=\"top\">\n<p class=\"p4\"><span class=\"s3\"><b>Back-End Budget of Total Latency <\/b><\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td32\" valign=\"top\">\n<p class=\"p6\"><span class=\"s1\"><b>Chunk<\/b><\/span><\/p>\n<\/td>\n<td class=\"td33\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">40%<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td32\" valign=\"top\">\n<p class=\"p6\"><span class=\"s1\"><b>Page<\/b><\/span><\/p>\n<\/td>\n<td class=\"td33\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">20%<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td32\" valign=\"top\">\n<p class=\"p6\"><span class=\"s1\"><b>Commit<\/b><\/span><\/p>\n<\/td>\n<td class=\"td33\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">80%<\/span><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"p2\"><span class=\"s1\">That makes this the Back-end\u00a0Grade Scale for Chunk, Page, and Commit interactions.<\/span><\/p>\n<table class=\"t1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"td30\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">\u00a0<\/span><\/p>\n<\/td>\n<td class=\"td17\" valign=\"top\">\n<p class=\"p4\"><span class=\"s3\"><b>A+ <\/b><\/span><\/p>\n<\/td>\n<td class=\"td17\" valign=\"top\">\n<p class=\"p6\"><span class=\"s1\"><b>A<\/b><\/span><\/p>\n<\/td>\n<td class=\"td19\" valign=\"top\">\n<p class=\"p4\"><span class=\"s3\"><b>A- <\/b><\/span><\/p>\n<\/td>\n<td class=\"td17\" valign=\"top\">\n<p class=\"p4\"><span class=\"s3\"><b>B+ <\/b><\/span><\/p>\n<\/td>\n<td class=\"td19\" valign=\"top\">\n<p class=\"p6\"><span class=\"s1\"><b>B<\/b><\/span><\/p>\n<\/td>\n<td class=\"td17\" valign=\"top\">\n<p class=\"p4\"><span class=\"s3\"><b>B- <\/b><\/span><\/p>\n<\/td>\n<td class=\"td19\" valign=\"top\">\n<p class=\"p4\"><span class=\"s3\"><b>C+ <\/b><\/span><\/p>\n<\/td>\n<td class=\"td17\" valign=\"top\">\n<p class=\"p6\"><span class=\"s1\"><b>C<\/b><\/span><\/p>\n<\/td>\n<td class=\"td17\" valign=\"top\">\n<p class=\"p4\"><span class=\"s3\"><b>C- <\/b><\/span><\/p>\n<\/td>\n<td class=\"td19\" valign=\"top\">\n<p class=\"p4\"><span class=\"s3\"><b>D+ <\/b><\/span><\/p>\n<\/td>\n<td class=\"td19\" valign=\"top\">\n<p class=\"p6\"><span class=\"s1\"><b>D<\/b><\/span><\/p>\n<\/td>\n<td class=\"td34\" valign=\"top\">\n<p class=\"p4\"><span class=\"s3\"><b>D- <\/b><\/span><\/p>\n<\/td>\n<td class=\"td18\" valign=\"top\">\n<p class=\"p6\"><span class=\"s1\"><b>F<\/b><\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td32\" valign=\"top\">\n<p class=\"p6\"><span class=\"s1\"><b>Chunk<\/b><\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">0.11<\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">0.15 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">0.2 <\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">0.3 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">0.4 <\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">0.56 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">0.8 <\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">1.08 <\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">1.48 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">2.2 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">3 <\/span><\/p>\n<\/td>\n<td class=\"td35\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">4 <\/span><\/p>\n<\/td>\n<td class=\"td25\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">&gt;4 <\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td32\" valign=\"top\">\n<p class=\"p6\"><span class=\"s1\"><b>Page<\/b><\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">0.16 <\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">0.22 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">0.3 <\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">0.45 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">0.6 <\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">0.84 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">1.2 <\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">1.6 <\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">2.2 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">3.3 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">4.4 <\/span><\/p>\n<\/td>\n<td class=\"td35\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">6 <\/span><\/p>\n<\/td>\n<td class=\"td25\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">&gt;6 <\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td class=\"td32\" valign=\"top\">\n<p class=\"p6\"><span class=\"s1\"><b>Commit<\/b><\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">2.16 <\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">2.96 <\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">4<\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">5.92<\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">8<\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">11.2<\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">16<\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">21.6<\/span><\/p>\n<\/td>\n<td class=\"td24\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">29.6<\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">44<\/span><\/p>\n<\/td>\n<td class=\"td26\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">59.2<\/span><\/p>\n<\/td>\n<td class=\"td35\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">80<\/span><\/p>\n<\/td>\n<td class=\"td25\" valign=\"top\">\n<p class=\"p2\"><span class=\"s1\">&gt;80<\/span><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Common Language Helps<\/h2>\n<p>In many ways, the categorization and cut-offs are arbitrary. It&#8217;s just a model to provide common language for discussing performance.<\/p>\n<p>Make sure your back-end folks know the experience their call will be part of. \u00a0Tell them if it is a chunk or a page.<\/p>\n<p>Make sure you identify your A interactions. For those critical parts of your experience you should probably target an A, even if some less important part of the site is at a C.<\/p>\n<p>Make your own trade-offs. Those are yours. \u00a0This is just language for discussing them.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve had a lot of luck using this article to push performance conversations further.\u00a0The numbers are dated but the concepts are real. You have to know how good is good enough. How bad is too bad to tolerate. You have to separate user interactions by value and user expectations. Here I break down user expectations&hellip; <a class=\"more-link\" href=\"https:\/\/www.managerjs.com\/blog\/2015\/04\/managerjs-web-performance-grades\/\">Continue reading <span class=\"screen-reader-text\">Talkin&#8217; &#8216;Bout Your Web Perf<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":200,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13],"tags":[53,52,54,51],"class_list":["post-199","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-lab-notebook","tag-latency","tag-page-grades","tag-performance-budget","tag-web-performance","wow fadeInUp","entry"],"_links":{"self":[{"href":"https:\/\/www.managerjs.com\/blog\/wp-json\/wp\/v2\/posts\/199","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.managerjs.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.managerjs.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.managerjs.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.managerjs.com\/blog\/wp-json\/wp\/v2\/comments?post=199"}],"version-history":[{"count":4,"href":"https:\/\/www.managerjs.com\/blog\/wp-json\/wp\/v2\/posts\/199\/revisions"}],"predecessor-version":[{"id":204,"href":"https:\/\/www.managerjs.com\/blog\/wp-json\/wp\/v2\/posts\/199\/revisions\/204"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.managerjs.com\/blog\/wp-json\/wp\/v2\/media\/200"}],"wp:attachment":[{"href":"https:\/\/www.managerjs.com\/blog\/wp-json\/wp\/v2\/media?parent=199"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.managerjs.com\/blog\/wp-json\/wp\/v2\/categories?post=199"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.managerjs.com\/blog\/wp-json\/wp\/v2\/tags?post=199"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}