From nothing to a video under 2 seconds / Mikhail Sychev (YouTube)

Preview:

Citation preview

From nothing to a video under 2 secondsMikhail Sychev, Software Engineer Unicorn at Google

Who am I?● Software Engineer at YouTube● Evangelist of modern web technologies● Member of the “Make YouTube Faster” group

What we will talk about● Types of page load, associated challenges and our

approach to handling them● Tools that we use to build and monitor YouTube● Tricks we learned along the way

1 Second...users notice the short delay, they stay focused on their current train of thought during the one-second interval … this means that new pages must display within 1 second for users to feel like they're navigating freely; any slower and they feel held back by the computer and don't click as readily.

JAKOB NIELSEN http://www.nngroup.com/articles/response-times-3-important-limits/

YouTube is a video streaming service, starting video playback as early as possible is the most

important task of the Watch page

....yet everything else is important too

Video PlayerGuide

Metadata

Actions

Playlist and related videos

Comments

Metadata

Masthead

Cold load

Warm load

Hot load

Navigation types

Users opening YouTube page with a plain HTTP(s) request

● Full HTML page downloaded and parsed● Some or no static resources in cache● Some DNS cache● Thumbnails have to be downloaded

● Various “pre-browse” techniques○ http://www.slideshare.

net/souders/prebrowsing-velocity-ny-2013○ http://www.slideshare.

net/MilanAryal/preconnect-prefetch-prerender● Browsers are really good at rendering HTML soup

○ Because this is what the most of internet is

But that’s pretty much it...

Good news we have plenty of room for optimizations (bad news is up to us to do all of it)

● How fast can we send data to the browser?● How much data should be downloaded?● How much data should be processed?● Do we have CPU/thread or network congestion?

● HTTP2/SPDY(for http) + QUIC(for video)● gzip● Image crushing● JS compiled by Google closure and modularized● Icon sprites (WebP where supported)● Minified CSS● CDN

https://developers.google.com/speed/pagespeed/

Basic things you would expect

● Why should you care?○ Typed JavaScript

■ Absolutely critical for large teams○ A set of advanced optimizations○ HUGE size savings and dead code removal

○ Kind of hard to setup and writing annotations is time consuming

Closure compiler

Chunking

GET /

INIT RPC DATA TRANSFER

PAGE RENDERING...

TEMPLATE

STATIC

Typical request lifetime

● Browser performs a request● Backend parses this requests and necessary data is

fetched / RPCs called● Page is rendered via some templating language and

sent to browser● Browser starts to render while fetching the page and

downloads external resources

● Browser has nothing to do while we are blocked by RPCs on the backend

● But when we start sending the data it’s forced to render the page while downloading and executing all external resources

● Result - CPU/thread and bandwidth congestion

Chunking approach

● Render and send to the browser first chunk containing references to external resources

● Browser starts to fetch them while the connection is still open

● Send extra chunks of data as RPCs are completed● Serialize data as JSON to be used later if UI is

blocking

GET /

INIT T0 DATA TRANSFER

RNDR ...

RPC1

STATIC

T1 RPC2 T2

RNDR RNDR

Chunking approach

Works for client side applications too

● Send links to application resources early● Render the application chrome, do not wait for page

onload event● Append data as JSON to the end of the page● Be careful of timing issues

○ You can’t predict if the application is initialized first or if the page is completely downloaded

GET /

INIT T0 DATA TRANSFER

RNDR ...

RPC

STATIC

JSON

RNDR

350kb of compiled and compressed JS

Here comes the player

Player

● Player is large○ It’s not just a video tag○ Ads, format selection logic, UI, annotations, etc…○ Sometimes we have to fallback to Flash

● Just executing all the necessary JS is a significant CPU task

● We really don’t want to do this on every page load (but nothing we can do for cold loads)

● Player can be blocked by OS (video and audio init)

Player

● No silver bullet for cold load● Have to carefully profile and optimize the code● Send the player early and init early● But the page may still be downloading/painting● So try not to get in the way e.g. asking the page for

the container size of the player may trigger relayout blocking the browser for 10x ms

Player

● tldr: Efficient video playback is HARD, we have a whole team dedicating to making it fast

● Pick your battles and don’t try to support every browser/platform unless you absolutely have to

● Focus on HTML5 if possible, Flash is slowly going away

Thumbnails

Thumbnails

● 10+ thumbnails above the fold on the Watch page● Some of the pages are mostly thumbnails● Important for users to decide what to watch, we

want thumbnails as fast as possible unless they are in the path of video

Thumbnails

● Only images above the fold are important on initial page display, everything else can be loaded later

● But some extra ones can still be preloaded to prevent thumbnail popping

Delay/Lazy loading

● Can’t start loading of the images until JS can be executed and forces re-layout

● Not the best solution if most of the images are above the fold

● We use hybrid approach, do not preloader thumbnails that are always above the fold and affect user behavior

Delay/Lazy loading

Visible to the user on page load

Invisible, but preloaded

Invisible to the user, not loaded

“WebP is a new image format that provides lossless and lossy compression for images on the web. WebP lossless images are 26% smaller in size compared to PNGs. WebP lossy images are 25-34% smaller in size...”

● Chrome (+mobile)● Opera (+mobile)● FF and IE through WebPJS● Android 4.0+● iOS (through 3rd party libraries)● WebKit based console applications

http://caniuse.com/webp

Use WebP for sprites and for thumbnails if you can afford extra space and wants to serve to native

clients.

mileage may vary but expect 10% faster page load

Delay loading

● Browsers already has priorities● Sometimes we want more control● Fetching of video bytes should be more important

than thumbnails● But this requires large codebase refactoring

○ Triggers potential race conditions and issues of various kinds

● setInterval and setTimeout hijacking as a simple introduction of scheduling

Cold load

Warm load

Hot load

● A navigation from one YouTube page to another in the same tab/window

● We have full control, can use rel=”pre-whatever”● Can we do better?

○ Only transfer JSON data?■ Requires to rewrite all backend templates■ Browser are actually really good at rendering

html soup

http://youtube.github.io/spfjs/

https://www.youtube.com/watch?v=yNe_HdayTtY

aka “that red bar on top of the page”

● State and history management

● In memory caching● Chunked JSON

responses● Partial DOM updates

● Lightweight alternative to rewriting all of the backend templates

● Chunks of the page are send from backend as chunked JSON ○ Some overhead on escaping (don’t mess up your

JSON)○ Overall JSON responses are smaller

● Player preinit on non Watch and persistent player across page boundaries

● Less DOM changes on navigation● Custom caching

Critical Stages of Playback

With player preinit

13% QPS decrease

40% faster playback

Cold load

Warm load

Hot load

● Can we do better? Cache?○ Visited pages/history - necessary to get the

back/forward right○ Tricky, first page load problem

■ If first page is rendered on backend, how do we go back?

○ How does this affect the metrics?○ Can we do even better? Cache pages that would

visited with high probability(next video in autoplay for example?)

○ But what if the user does not go to next page?■ Even more metric craziness■ More QPS

● Every latency impacting change goes through A/B testing

● Monitor both latency impact and user behaviors● Making things fast is good, but sometimes we

have to revisit experiments due to behavior changes (especially for delay loading)

Monitoring

● Regressions happen all the time○ Some are expected, like YouTube logo doodles○ Some are real issues

● A lot of things can change○ Sizes of common static resources○ Number of images on the page○ Latency of server responses

● We log timestamps of important events, server time, aft, qoe, etc..

● Browsers react differently, so we collect data per browser○ Version, background state, etc...

● http://www.webpagetest.org ● In addition we use many in-house tools to for

monitoring and notification

Summary

● Aim for average page load latency of 1 second or better

● Different types of page loads may require different approach

● Use WebP for sprites(usually) and thumbnails(if possible)

● Google closure compiler is awesome, but hard to set up - use it if you can

● Minimize amount of work done on every load (persistent player)

● Understand how the browser works● SPF is a reasonable alternative to replacing

everything with client side templating, saves QPS and makes everything faster

● Chunking unblocks the browser, but requires backend to support it

● Monitor everything, A/B testing is important, profiling is critical

Questions?