$30 off During Our Annual Pro Sale. View Details »

The Surprising Path to a Faster NYTimes.com

The Surprising Path to a Faster NYTimes.com

The current mantra in performance thinking is “Tools not Rules.” The premise is simple: The path to faster websites is not only about fast requests, but how they interact with paints, animations, and script execution. But tools are only part of the solution. What The New York Times discovered is that performance is about truly understanding your product and users, and the sum total of your site. Following this approach can lead to surprising results.

The New York Times underwent a major redesign that involved a rewrite of the entire technology stack. The Product team not only bought into the idea that performance should be a goal, but mandated that it be part of the product’s success. While we implemented many of the community’s best practices, our biggest wins were a little surprising, and at first glance, counter to community best practices. Front-end software architect Eitan Koningsburg covers those changes, what worked, what didn’t, and how we got there.

(Presented at Velocity New York.)

The New York Times Developers

September 16, 2014
Tweet

More Decks by The New York Times Developers

Other Decks in Technology

Transcript

  1. The Surprising Path to a
    Faster NYTimes.com
    Eitan Konigsburg
    Frontend Software Architect
    @eitanmk

    View Slide

  2. Technology company?
    Tony Cenicola/The New York Times

    View Slide

  3. Performance Golden Rule
    80-90% of the end-user response time is spent
    on the frontend. Start there.
    - Steve Souders

    View Slide

  4. It wasn’t always this way.
    Before the WPO Enlightenment, where was the
    performance focus?

    View Slide

  5. The Backend.

    View Slide

  6. NYTimes.com went online in 1996

    View Slide

  7. Back then...
    ● Static pages
    ○ Less processing server-side meant faster responses
    ○ Very limited caching
    ○ Needed a lot of servers to scale
    ○ Handled traffic spikes caused by news events

    View Slide

  8. Back then...
    ● Server-side dynamicism via a proprietary language called
    “Context”
    ○ HTML macros
    ○ Compiled to execute quickly
    ○ Execution delegated to special server software
    ○ Context server maintained “always on” database
    connections
    ○ It was fast

    View Slide

  9. Back then...
    ● Ultimately switched to PHP
    ○ Never could match Context for live execution speed
    ○ Relegated to server side templating
    ○ Context remained to provide dynamic features

    View Slide

  10. We created a monster

    View Slide

  11. We created a monster
    ● Now have over 1 million static pages on disk
    ○ Only way to change them is to republish them
    ○ Would take ~90 days to re-publish all of them
    ○ Not feasible to do this for every code change
    ○ So we didn’t re-publish at all

    View Slide

  12. It gets worse...

    View Slide

  13. Permutations
    ● New variations of page markup created with each
    deployment
    ○ Older pages were not updated
    ○ Extrapolate over 10 years of development
    ○ Smallest code tweak created a lot of technical debt
    ● We have an unknown number of permutations
    ○ Maintenance nightmare!

    View Slide

  14. WPO? We tried…
    ● Our unknown number of page permutations made
    optimizing the frontend almost impossible
    ○ Combined files together, but couldn’t remove
    references from older pages
    ○ Download sizes increased as we had to support older
    permutations
    ○ Needed low cache TTLs to ensure files got updated in
    a timely manner
    ● Made things worse, not better

    View Slide

  15. Surprise #1
    A lot of static pages are a barrier to WPO

    View Slide

  16. Isn’t that obvious?
    ● Not mentioned often in performance discussions
    ○ Who would have 1M static pages?
    ● Didn’t become a barrier right away
    ○ Not every page we have is intended to live forever
    ○ Recent articles receive more traffic than older ones
    ● No practical alternative available
    ○ Couldn’t avoid the static page problem

    View Slide

  17. Shift + Refresh

    View Slide

  18. 2013: A Rare Opportunity
    ● Given a product pause to fix major infrastructural debt
    ○ This doesn’t happen very often (if at all)
    ● Nothing was safe:
    ○ Infrastructure
    ○ Server configuration
    ○ Code organization
    ○ Development process
    ○ Build process
    ○ Deployment process

    View Slide

  19. Going dynamic
    ● Slowly migrating all content into databases
    ● Ongoing process
    ○ Some things will be dynamic sooner than others
    ● Use Varnish cache to hide backend slowness
    ○ We get great TTFB times with Varnish
    ○ Simple caching strategy
    ○ All per-user customizations pushed client-side

    View Slide

  20. Surprise #2
    Performance increase mandated as part of
    redesign

    View Slide

  21. Supported from the top
    ● First project to have a performance goal as part of its
    definition of success
    ● Why all of a sudden?
    ○ Performance became a factor in SEO
    ○ NYT became an E-Commerce site since last redesign
    ● Conservative goal
    ○ A certain percentage faster than the old site
    ○ Attainable, but wouldn’t risk shipping the product

    View Slide

  22. Where to begin?

    View Slide

  23. Conflicting advice
    ● Basic rules sometimes contradict
    ○ Reduce number of HTTP requests, but not all the way
    so you can take advantage of parallel downloads
    ○ Combine files together, but soon, with HTTP/2.0
    doing so will be less than optimal
    ○ Set long cache TTLs, but remove unused code
    ● “Tools, not rules”
    ○ Create the product, then inspect, then optimize
    ○ Need to have a product first

    View Slide

  24. Fundamental overhaul
    ● RequireJS for non-blocking and asynchronous loading
    ○ One blocking script needed in the head
    ● Modern build system to concatenate and minify files
    ○ Automatic sprite atlas creation
    ● New caching strategy
    ○ Timestamp in the URL
    ○ Inserted dynamically by the backend application
    ○ New file downloaded after code push
    ○ Far-future cache TTL

    View Slide

  25. Lazy loaded ads
    ● Worthwhile investment
    ● Before the redesign, ads were part of the markup and
    would block rendering
    ○ Often the slowest part of our page load
    ● Injected ads into iframes which worked surprisingly well
    ● Minor issue: differences in browsers regarding how to
    track history in embedded frames
    ● Blogged about this: http://nyti.ms/1qgoJ0b
    ● Allowed us to hit DOMReady really quickly

    View Slide

  26. Surprise #3
    Sometimes you have to slow down to seem
    faster

    View Slide

  27. Don’t move the things
    ● Want to avoid moving content around based on the ads
    ● Preferable to show an ad above the fold, if present
    ● If no ad, want to use the space for other content
    ● Bonus: use NYT web fonts to make the headline look like
    the newspaper
    ○ Browsers differ on how to handle text while a font
    downloads - FOUT
    ● If we were fully asynchronous, the content could shift
    around during load which looks and feels slow

    View Slide

  28. Variant #1

    View Slide

  29. Variant #2

    View Slide

  30. Initial solution
    1. Request the ads synchronously
    2. Inspect the response to see if there is an ad to draw
    3. Add a class to the HTML to determine which layout to
    show
    4. Continue loading the page
    ● Requires an intentionally (!) blocking script to achieve this
    ● While it slowed down the page, things didn’t shift around
    ● The perception mattered more than the numbers

    View Slide

  31. Unexpected Surprise
    Discovered another solution

    View Slide

  32. Even better solution
    ● Some of the time, make room for an ad
    ○ Otherwise, use full width for content
    ● Allows for both goals:
    ○ Prevents content shifting
    ○ Maximizing ad placement
    ● Ad request can be asynchronous again!
    ● Drawback: sometimes space can be made for an ad that
    is never served
    ○ Tweak the numbers to minimize this

    View Slide

  33. Profit

    View Slide

  34. New possibilities
    Things we’re exploring

    View Slide

  35. Measure and improve
    ● Smoother animations
    ○ Scroll event listeners causing jank
    ○ Exploring patterns involving requestAnimationFrame
    ○ Promoting some of our fixed position elements to the
    GPU
    ○ Optimizing code paths to achieve better FPS
    ○ Challenge: requires refactoring large portions of the
    codebase

    View Slide

  36. Measure and improve
    ● Memory management
    ○ We have to load a lot of content
    ○ Approaching memory limits on some mobile devices
    ○ There are a lot of candidates for things retaining too
    much memory
    ○ Challenge: tools are complex but getting better
    ○ Challenge: sometimes the memory issue is difficult to
    track down

    View Slide

  37. Measure and improve
    ● Above-the-fold, critical path optimizations
    ○ Inlining of critical CSS
    ○ Lazy loading of other resources
    ○ Keeping 3rd-party code out of
    ○ Challenge: editorial desire to put nice interactive
    material above the fold
    ○ Challenge: A/B testing support

    View Slide

  38. Other things we’re following
    ● HTTPS
    ○ Interested in using HTTPS by default
    ○ Huge hurdles to overcome to make this a reality
    ○ All that static content is still holding us back

    ○ Will be a huge help to our responsive site
    ● Web Components
    ○ Following development on this closely
    ○ Interested in seeing whether this can be used for ads
    ● ServiceWorker (pretty please???)
    ○ Better offline access

    View Slide

  39. Developer portal: http://developers.nytimes.com/
    Open Blog: http://open.blogs.nytimes.com/
    Twitter: @nytdevs
    Other NYTDevs slides: https://speakerdeck.com/nytdevs/

    View Slide

  40. Thanks!
    @eitanmk

    View Slide