yahoo homepage yahoo homepage
play

Yahoo! Homepage Yahoo! Homepage Nicholas C. Zakas Nicholas C. - PowerPoint PPT Presentation

flickr.com/photos/eyesplash/4268550236/ Performance on the Performance on the Yahoo! Homepage Yahoo! Homepage Nicholas C. Zakas Nicholas C. Zakas Principal Front End Engineer, Yahoo! Principal Front End Engineer, Yahoo! Velocity, June 24


  1. flickr.com/photos/eyesplash/4268550236/ Performance on the Performance on the Yahoo! Homepage Yahoo! Homepage Nicholas C. Zakas Nicholas C. Zakas Principal Front End Engineer, Yahoo! Principal Front End Engineer, Yahoo! Velocity, June 24 2010 Velocity, June 24 2010

  2. Principal Front End Engineer

  3. Contributor

  4. Author

  5. The Challenge: Create a new Yahoo! homepage* *add a ton of new functionality **without sacrificing performance

  6. By the Numbers 345 110 million million unique users per month unique users per month worldwide in United States (no pressure)

  7. The Legacy

  8. 1996

  9. 1997

  10. 1999

  11. 2002

  12. 2004

  13. 2006

  14. Today

  15. flickr.com/photos/yodelanecdotal/3620023763/ We strapped ourselves in, believing we could make the fastest Yahoo! homepage yet

  16. Performance is hard The best features for users aren't always the fastest flickr.com/photos/thetruthabout/2831498922/

  17. Content Optimization Engine determines which stories to display at request time

  18. Sites can be completely customized by the user

  19. Popular search topics are determined at request time to display up-to-date info

  20. Random information about other parts of the Yahoo! network

  21. Apps provide more info on-demand

  22. The Cost of Customization • Spriting is difficult – Hard to know which images will be on the page together • Limited image caching – With content constantly changing, getting images into cache doesn't help much • A lot more JavaScript/CSS – And very different, depending on how the user has customized the page

  23. flickr.com/photos/thetorpedodog/458336570/ Performance reboot Many of the optimizations made on the previous homepage won't work

  24. Coming to peace with reality We can't optimize everything – so let's just focus on the parts we can flickr.com/photos/hape_gera/2123257808/

  25. Areas of Focus • Time to interactivity • Ajax Responsiveness • Perceived performance flickr.com/photos/hape_gera/2123257808/

  26. The time to interactivity is the time between the initial page request and when the user can complete an action

  27. Time to Interactivity • For most pages, happens between DOMContentLoaded and onload – Can actually happen earlier • Links work, forms can be submitted even while the page is loading – As long as JavaScript isn't running • Difficult to measure

  28. Net tab reveals some information Where DOMContentLoaded and onload occur

  29. YSlow reports onload time Useful, but doesn't really determine time to interactivity

  30. Goal: Ensure interactivity by DOMContentLoaded

  31. Simple User Actions • Clicking a headline to read the story • Performing a search • Clicking on a favorite Wait a second! You don't need JavaScript for any of that! flickr.com/photos/marcoarment/2035853550/

  32. alistapart.com/articles/understandingprogressiveenhancement Progressive Enhancement FTW! The more tasks that don't require JavaScript, the faster the user can complete an action

  33. The page is very functional even without JavaScript

  34. Not relying on JavaScript for everything allows us an opportunity to deliver what appears to be a faster experience

  35. JavaScript Loading onto the page without pain

  36. Traditional thinking was put scripts at the bottom

  37. <html> <head> <!-- head contents --> </head> <body> <!-- body contents --> <script type="text/javascript" src="yourfile.js"> </script> <script type="text/javascript" src="yourfile2.js"> </script> </body> </html>

  38. flickr.com/photos/kartik_m/2724121901/ Our results were upsetting Putting scripts at the bottom actually caused other problems

  39. flickr.com/photos/kartik_m/2724121901/ Results • Page would fully render, but be frozen – User can't interact while JavaScript is being fetched/parsed/executed • Delayed onload to after 5s on fast connection • Time to interactivity tied to onload • Experience was especially bad over slower connections – Page was unresponsive for 30s or more

  40. flickr.com/photos/19613690@N05/3687563687/ In order to fix things, we had to get lazy

  41. stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/

  42. nczonline.net/blog/2009/07/28/the-best-way-to-load-external-javascript/

  43. function loadScript(url, callback){ var script = document.createElement("script") script.type = "text/javascript"; if (script.readyState){ //IE script.onreadystatechange = function(){ if (script.readyState == "loaded" || script.readyState == "complete"){ script.onreadystatechange = null; callback(); } }; } else { //Others script.onload = function(){ callback(); Dynamically loaded scripts }; don't block page load } script.src = url; document.getElementsByTagName("head")[0].appendChild(script); }

  44. <html> <head> <!-- head contents --> </head> <body> <!-- body contents --> <script type="text/javascript" src="smallfile.js"> </script> <script type="text/javascript"> loadScript(filename, function(){ //initialization }); </script> </body> </html>

  45. Y.Get.script(YUI.presentation.lazyScriptList, { onSuccess: function() { Y.use("*"); Y.ModulePlatform.init(Y.dali.config, true); }});

  46. First script file Everything else

  47. flickr.com/photos/nateandmiranda/2625399653/ Results • Page is interactive as soon as each section is rendered • Reduced onload time to ~2.5s on fast connections • Slow connection experience vastly improved

  48. JavaScript Loads • Small amount on page load • Larger amount loaded in non-blocking manner – Everything necessary for core JavaScript interactivity • Ajax responses can specify more JavaScript is needed to handle the response – True, on-demand loading

  49. Page Flushing Getting data out to the browser fast

  50. Traditional thinking is to flush after <head>

  51. Flushing after <head> ensures CSS starts to download as quickly as possible But the user still sees a blank screen until the rest of the HTML is rendered to the browser Solution: flush after major sections of the page have been output flickr.com/photos/conskeptical/354951028/

  52. <div class="doc"> <div class="hd"> </div> <!-- flushing here does nothing --> <div class=”bd”> </div> </div> The browser won't render a block-level element inside of <body> until the closing tag has been received

  53. <div class="hd"> </div> <!-- flushing here causes the head to render --> <div class=”bd”> </div> Removing page-level wrapper <div> allows the head to render as quickly as possible

  54. Flush Flush

  55. (Actually, we flush a bunch of times as the page is output) Even when the browser can't render yet, it can still start to download other resources such as images

  56. Areas of Focus • Time to interactivity • Ajax Responsiveness • Perceived performance flickr.com/photos/hape_gera/2123257808/

  57. The biggest area of concern regarding Ajax performance was around the apps. For our very first test, it sometimes took as long as 7 seconds to load a single app.

  58. start stop What exactly is taking 7 seconds? The measurement itself was a huge black box – before doing anything, we had to figure out exactly what was happening in that time

  59. roundtrip start stop Roundtrip Time The first step is the amount of time between when the browser sends the request and the time it receives the response

  60. roundtrip parse start stop Parse Time Next, the JSON response returned from the server has to be parsed

  61. roundtrip parse download start stop JavaScript/CSS Download Time Each response can indicate it needs more JavaScript/CSS before the content can be used

  62. roundtrip parse download render start stop Render Time The amount of time it takes to actually change the display via innerHTML

  63. Where We Started

  64. Fixing Roundtrip Time What's taking so damn long?

  65. The right-side ads were a roundtrip issue The server-side ad call took extra time plus the ad markup represented 50-60% of the returned markup

  66. “Fixing” the ad Entire right column now renders in an iframe. This defers the ad call until after the app has been loaded in the browser, saving both server time for app rendering and bytes in the response.

  67. Fixing Parse Time What's taking so freakin' long??

  68. { "msg": "Hello world!", "day": 6, "found": true, } JSON is super-efficient for transporting numbers, Booleans, simple strings, objects, and arrays

Recommend


More recommend