understanding page load / ziling zhao (google)

Post on 06-Jan-2017

615 Views

Category:

Engineering

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Understanding Page LoadZiling Zhao - Engineer at Google

What I will talk about

● Page Load Latency○ Time leading from a click to a usable website

● Traditional and dynamic page loads● A few tips and things to avoid● How the browser works● Tools that can help you explore site performance● Most of this was picked up while optimizing YouTube

Who am I?

● Software Engineer on YouTube○ Working on Desktop and Mobile Web

● Been at Google for 4 ½ years● Prior to Google, I worked at Cisco Systems● Graduated from the University of Washington● Specialize in web performance

Why care about page load speed?

● Customers are from different parts of the world● People have slow connections and slow CPUs● Malware, antivirus, memory pressure, etc.● Mobile users have resource constraints● People want smooth app-like experiences● Slow websites turn users away!

Two types of page loads.

TraditionalPage Load

First page load, as well as any full page load.

Measured starting from when the request is sent for the page.

Ends when the important parts of the requested page is viewable and ready.

"Cold"

DynamicPage Load

AJAX driven site navigation.

Starts when an action (typically user driven) triggers a navigation to the next page. This should be before the actual request.

Ends when the important parts of the requested page is viewable and ready.

"Warm"

Monitor your performance.

Response-Time Rules of Thumb

0.1s - Instantaneous

1s - Seamless

10s - Attention threshold

Jakob Nielsenhttp://www.nngroup.com/articles/response-times-3-important-limits/

Network dominatesload time.

Examining at a web page load.

Chrome DevTools - Network Panel

WebPagetest

WebPagetest - highload.co

http://www.webpagetest.org

Hmmm...WebPagetest results

Page Load Basics

A CDN serves content closer to your customers.

Low latency. Cookieless, smaller response/request size.

Extra DNS lookup and TCP connection for separate domain

● Use a CDN

● Cache static content

● Connection keep-alive

● Use gzip transfers

● Compress Images

● Minify your javascript/css

● Minimize first byte time

● Reduce number of downloads

List static assets not being served off of a CDN

Page Load Basics

Avoid the roundtrip.

● Use a CDN

● Cache static content

● Connection keep-alive

● Use gzip transfers

● Compress Images

● Minify your javascript/css

● Minimize first byte time

● Reduce number of downloads

Check for cache headers

These images never change● Set a max-age or expires header

ETag still incurs a round trip● Browser needs to ask the server

if content has changed○ RTT 289ms!

Page Load Basics

Do your handshake once.

Reduce your transfer size.

● Use a CDN

● Cache static content

● Connection keep-alive

● Use gzip transfers

● Compress Images

● Minify your javascript/css

● Minimize first byte time

● Reduce number of downloads

Keep connections open and gzip

Page Load Basics● Use a CDN

● Cache static content

● Connection keep-alive

● Use gzip transfers

● Compress Images

● Minify your javascript/css

● Minimize first byte time

● Reduce number of downloads

Image size reduction

Compress Images

Original Image● JPEG Quality 94● Resolution: 1500 x 1001 pixels● File Size: 795KB

Compressed Image● JPEG Quality 70● Resolution: 1024 x 683 pixels● File Size: 152.5KB

WebP● WebP Quality 70● Resolution: 1024 x 683 pixels● File Size: 136.2KB

Page Load Basics

Use something like uglify/closure compiler/YUICompressor.

● Use a CDN

● Cache static content

● Connection keep-alive

● Use gzip transfers

● Compress Images

● Minify your javascript/css

● Minimize first byte time

● Reduce number of downloads

Minify your large javascript files

Probably don't need another version.

Page Load Basics

Chunk your responses if you have RPCs or heavy server processing.

Serve static content early.

● Use a CDN

● Cache static content

● Connection keep-alive

● Use gzip transfers

● Compress Images

● Minify your javascript/css

● Minimize first byte time

● Reduce number of downloads

Transfer-Encoding: Chunked

Page Load Basics● Use a CDN

● Cache static content

● Connection keep-alive

● Use gzip transfers

● Compress Images

● Minify your javascript/css

● Minimize first byte time

● Reduce number of resources

Reduce the number of resources

● This used to be simple○ HTTP/2 makes things complicated

● Under HTTP1○ 6~ concurrent connections per server for all tabs

■ Reduce the total number of resources needed○ Sprite your assets, reduce the number of small images○ Reduce CSS/JS downloads

● But can you serve SPDY/HTTP2?

SPDY/HTTP2 and QUIC

● Connection multiplexing○ Allows multiple requests over one socket

■ Only creates one connection per server■ Reduces the need to sprite your images or shard static

domains● Header compression● Faster SSL handshake● Serverpush resources before client asks for them● QUIC is a UDP-based transport

○ currently used for YouTube video serving

Dev Tools

After the first byte

The browser starts getting busy

● The browser must take the CSS and HTML and join them together○ HTML is parsed into a DOM (Document Object Model)○ CSS is parsed into an CSSOM

● Styles are applied/recalculated● The page is layed out and painted

○ Elements are positioned and pixels are drawn● Resources linked to in your page must be

downloaded● Javascript must be executed

Rendering is (mostly)

single threaded.

The render-thread has a lot to do

● A single render thread (per tab) handles a lot of important tasks○ Parsing○ Styling○ Layout○ Painting○ Javascript○ Event handling, etc.

● Network operations are on a separate process○ One shared network manager across tabs

Page load walkthrough.

After the first byte

● Browser parses HTML to construct the DOM (Document Object Model)

● CSS is parsed to form the CSSOM

● DOM + CSSOM = Render Tree○ This is how the

visible elements will be displayed.

● Render Tree is painted

HTML

DOM Tree

After the first byte

● Browser parses HTML to construct the DOM (Document Object Model)

● CSS is parsed to form the CSSOM

● DOM + CSSOM = Render Tree○ This is how the

visible elements will be displayed.

● Render Tree is painted

HTML

DOM Tree

CSS

CSSOM

Where does the CSS come from?

The browser has to read the <link> before CSS downloads.

After the first byte

● Browser parses HTML to construct the DOM (Document Object Model)

● CSS is parsed to form the CSSOM

● DOM + CSSOM = Render Tree○ This is how the

visible elements will be displayed.

● Render Tree is painted

HTML

DOM Tree

CSS

CSSOM HTML Parser

Network Manager

After the first byte

● Browser parses HTML to construct the DOM (Document Object Model)

● CSS is parsed to form the CSSOM

● DOM + CSSOM = Render Tree○ This is how the

visible elements will be displayed.

● Render Tree is painted

HTML

DOM Tree

CSS

CSSOM HTML Parser

Network Manager

Render Tree

Javascript is blocking.

Parser + Javascript on the same thread

● Javascript can read and write to the DOM○ The parser is cautious and will pause until javascript is

downloaded and run● The browser can paint the partial page while blocked

○ Being blocked in <head> means there is nothing to paint● General advice:

○ Have stylesheets in the head and send them early○ Put javascript at the bottom of your page to avoid

blocking the parser

Be careful with JS in <head>

● Stylesheets block painting● Putting inline <script> right after <link rel="

stylesheet"> will block the parser until stylesheet is downloaded○ Browser assumes js will read stylesheet

● If you must put scripts in the head.○ Keep it small, maybe inline○ It may be better to put it before your external CSS

■ Otherwise it will block until CSS is done downloading before executing

After the first byte

● Browser parses HTML to construct the DOM (Document Object Model)

● CSS is parsed to form the CSSOM

● DOM + CSSOM = Render Tree○ This is how the

visible elements will be displayed.

● Render Tree is painted

HTML

DOM Tree

CSS

CSSOM HTML Parser

Network Manager

Render Tree

Paint

Display

The Preloader

The Preloader

● Also known as: Speculative/look-ahead pre-parser● Making your site run-faster since 2008● 20%~ page load improvement● While the parser is blocked, another parser flies

ahead and finds all downloadable resources○ Stylesheets, scripts, images, html imports

Network Priorities - Chrome

● Network requests are executed in priority order○ Layout blocking network requests are HIGHEST/MEDIUM

priority (CSS/HTML)○ Layout blocking mode allows one low priority request at

a time (this may change).○ Scripts are LOW○ Async XHR's are LOW priority○ Images are LOWEST or IDLE priority

Pre-loader - Chunked Transfer

● Chunked encoding + scripts at the end○ Pre-loader can't see it until the chunk is sent

■ Your script download will be after other resources○ Can use async and defer to put scripts earlier

■ async - Doesn't block parser for download, will pause to execute● This will put it in LOWEST priority

■ defer - Doesn't block for download, execute after parser is completed (keeps order)

Scripts at footer can load earlier than images

chrome://net-internals#events

Warning: JS module loaders

● Cannot take advantage of the pre-loader● Script loaders will only load scripts after:

○ Your bootstrap script downloads and is executed○ Bootstrap script execution will be blocked by any

previous CSS or javascript● Same applies to CSS loaders

○ Especially damaging since CSS is typically fetched at MEDIUM priorities

Dynamic Page Transitions

Dynamic page transitions

● Faster than full page loads○ We can make them even faster

● Fewer network requests● Higher expectations for mobile web apps

○ Animate between page loads■ Must be careful to avoid janking the animations.

● We want to hide latency and make it feel seamless○ Ideally instantaneous if you prefetch

Dynamic page load

Jankiness can be introduced at almost every step.

When the user expresses an intent is where it starts.

User Input, can be a touch, click, scroll, anything that signifies a dynamic page load should occur.

User Input

Tim

e

Dynamic page load

Often, page transitions require you to clean up or animate some stuff.

This can involve removing event listeners, turning off animations, removing DOM elements, etc.

We typically will want to fetch the page data and then run dispose because why wait?

User Input

Dispose XHR

Tim

e

Dynamic page load

Note that network happens on a separate thread and does not block the render thread.

The XHR however is on the same thread and cannot run in parallel with dispose.

User Input

Dispose

XHR

Tim

e

Network Manager

hl.c

o/ne

xt-p

age

Dynamic page load

After the response comes back an event handler for the XHR will run and mutate the web page.

After modifying the page, javascript code for the specific page may need to be initialized.

User Input

Dispose

XHR

Tim

e

Network Manager

XHR.onload

Mutate DOM

Init Page JS

hl.c

o/ne

xt-p

age

DOM mutation causes work

Dynamic page load

If you inject HTML, work must be done by the browser to parse the text into a DOM tree and appended.

The part of the DOM that was mutated needs to go through style recalculation and layout.

Then the DOM needs to be re-painted.

User Input

Dispose

XHR

Tim

e

Network Manager

hl.c

o/ne

xt-p

age

XHR.onload

Mutate DOM

Parse

RecalcStyle

Layout

Init Page JS

Paint

Dynamic page load

Your dispose call could have modified the DOM as well. If so, parse, layout, and paint will also occur after dispose.

Your JS + browser work can delay the handling of network responses.

User Input

Dispose

XHR

Tim

e

Network Manager

hl.c

o/ne

xt-p

age

XHR.onload

Mutate DOM

Init Page JS

Parse

RecalcStyle

Layout

Paint

Parse

RecalcStyle

Layout

Paint

Dynamic page load

From the user's perspective, the latency of going from one page to the next is the equivalent of starting with the user input all the way till the last paint.

So, we are done right?

User Input

Dispose

XHR

Tim

e

Network Manager

XHR.onload

Mutate DOM

Init Page JS

hl.c

o/ne

xt-p

age

Parse

RecalcStyle

Layout

Paint

Parse

RecalcStyle

Layout

Paint

DynamicPage Load

Deals with intra-site navigation. Typically AJAX driven.

Starts when an action (typically user driven) decides to load a page. This can be before the actual request.

Ends when the important parts of the requested page is viewable and ready.

"Warm"

Dynamic page load

Just because the DOM was changed via your XHR doesn't mean the page is ready.

You may have loaded additional stylesheets, more images, etc.

User Input

Dispose

XHR

Tim

e

Network Manager

XHR.onload

Mutate DOM

Init Page JS

hl.c

o/ne

xt-p

age

Parse

RecalcStyle

Layout

Paint

Parse

RecalcStyle

Layout

Paint

Dynamic page load

Just because the DOM was changed via your XHR doesn't mean the page is ready.

Often times there are css or images in your new page that need to be loaded.

When the CSS comes in, the page needs to be reflowed and repainted.

Tim

e

Network ManagerXHR.onload

Mutate DOM

Init Page JS

css

imag

e.pn

g

imag

e2.p

ng

Parse

RecalcStyle

Layout

Paint

RecalcStyle

Layout

Paint

Dynamic page load

Sometimes there is additional data to load, maybe from third party sources, or just delay loaded components.

Be aware of where and when your javascript is running during these critical moments.

Tim

e

Network ManagerXHR.onload

Mutate DOM

Init Page JS

mor

e da

ta

css

imag

e.pn

g

imag

e2.p

ng

moreData.onLoad

RecalcStyle

Layout

Paint

Parse

RecalcStyle

Layout

Paint

Keep therenderThreadidle

Break up long running Javascript

● Delay non-essential javascript● Debounce event handlers

○ readyStateChange/scroll/resize events fire way more often than you care■ These events will queue up behind slow js handlers

● Javascript should run in short chunks for animations○ For 60fps animations, limit javascript to < 16ms

(including browser render time!)○ requestAnimationFrame

Don't run js for long periods of time.

RAILResponse Animation Idle Load

https://developers.google.com/web/tools/chrome-devtools/profile/evaluate-performance/rail

0 - 16ms Threshold for animations

0 - 100ms User input response

100 - 300ms Detectable delay

300 - 1000ms Keeps user focus

1000+ms Users lose focus

10s+ Abandonment

RecalcStyle

Layout

Paint

Reduce/eliminate parse time

● Using innerHTML requires the browser to parse HTML text into DOM○ Often faster to use alternatives:

■ createElement/cloneNode/appendChild■ <template> importNode

● innerHTML is also a security issue● Try not to block parse with scripts. Parse

Parse time blocks on inline scripts.

Make recalcstyle and layout faster

● Mutate as few DOM elements as possible○ The browser can optimize for subtree changes

● Reduce the size of your DOM○ Rule of thumb: no more than 3000~ elements on a page

● Simplify the number of CSS rules and selector complexity

● Hide things that are not visible○ display: none

● Avoid mutating stylesheets.

Parse

RecalcStyle

Layout

Paint

RecalcStyle

Layout

Recalculate Style + Layout in Devtools

Speeding up paints

● Use GPU rasterization on mobile web○ Use meta viewport tag containing width=device-width

and minimum-scale=1.0● Use layers where it makes sense

○ Do research, be careful where you do it■ Don't create too many layers

○ Creates separate textures■ can eliminate the need to paint at all

Parse

RecalcStyle

Layout

PaintPaint

Networking for dynamic pages

● Layout blocking mode isn't active anymore● Typically fewer requests for dynamic transitions

○ Be careful cancelling a request with HTTP/1. Socket is closed and requires to be rebuilt

● Do you value images or AJAX?○ Image priorities are LOWEST/IDLE vs. XHR which is LOW

Summary

● Profile your page loads○ Test with webpagetest.org

● Make your page transitions seamless○ Keep your render thread idle and happy

● Understand how the browser loads your page○ Both first page load and intra-site page loads○ Analyze your render thread!

Questions?

Extra Slides

Real User Metrics

● What does your website feel like to the average user?○ Are you optimizing the correct area?

● Fully understand the flow of your website○ What actions/events are important to your users?

■ When does this action/event start?○ What are the blocking steps?

■ Are they blocked on network? CPU? User input?● Need large data sets

○ Server side performance tends to be consistent○ Client side performance is noisy and requires large data

sets.

Measuring start and stop

● Start as early as possible.○ Use the navigation/resource timing APIs.

● Where to stop depends on your site.○ Content above the fold is typical.

■ onLoad is not a good measure.○ If you're a video site, you may care more about the video

playing.

Navigation/Resource Timing API

Profiling tools I use

● DevTools○ All types of goodies○ High overhead, accessible, (mostly) easy to use

● chrome://tracing○ Gives you insight to Chrome○ Hard to use○ High overhead

● Web Tracing Framework○ Setup required○ Low overhead instrumented profiling

Chrome DevTools - Network Panel - Throttling

Chrome DevTools - Timeline

● Arguably most powerful tool in devtools● High overhead● Observe render thread blocking operations

○ What javascript functions were called○ How much time did parse/recalculate style/layout/paint

take?● Style Invalidation Tracing/Paint Inspection/Memory

profiling● Lots more stuff!

Chrome DevTools - Timeline

chrome://tracing

● A very detailed view into Chrome● Hard to use

○ A lot of data■ Collects data from all of chrome, not just your tab

○ Limited collection buffer size○ Limited amounts of app specific JS information available

● Best run in its own Chrome instance

chrome://tracing

Web Tracing Framework

● Written for Google Maps○ http://google.github.io/tracing-framework/○ Made for tracking FPS and inspecting WebGL

● Instrumented profiler○ Low overhead○ Setup cost

■ Minified code exports readable names to profiler○ Does not play with Chrome Devtools○ No network view

Web Tracing Framework

top related