Beyond Breakpoints: Improving Performance for Responsive Sites

Preview:

Citation preview

Beyond Breakpoints

@renettarenula Aysha Anggraini Rakuten Tech Conf ‘16

Improving performance for responsive sites

1. Optimize Web Fonts

2. Reduce Render-Blocking Scripts

3. Optimize Images

Optimize Web Fonts

@font-face {

font-family: 'Open Sans';

src: url('open-sans.woff2') format("woff2"),

url('open-sans.woff') format("woff");

}

CSS

Does not guarantee load of fonts

body {

font-family: 'Open Sans', sans-serif;

}

CSS

Will only load when font is specifically declared under a rule

Problem

Construct DOM

Construct CSSOM

DownloadFonts!

Web fonts are lazy loaded!

Problem

Image Credit: Bram Stein @ Smashing Magazine’s Real Life Responsive Web Design (Web Fonts Performance)

Results in FOUT or FOIT

Problem

Different browsers handles this differently

FOUT & FOIT

Present Solution

Define fallback & web fonts in

CSS

Basic Font Loading Strategy

Leverage browser cache

Load fonts dynamically &

use it

Define fallback & web fonts in CSS

@font-face {

font-family: 'Open Sans';

src: url('open-sans.woff2') format("woff2"),

url('open-sans.woff') format("woff");

}

CSS

Define fallback & web fonts in CSS

Detect specific font loa

body {

font-family: sans-serif;

}

CSS

.fonts-loaded {

body {

font-family: 'Open Sans', sans-serif;

}

}

Present Solution

Define fallback & web fonts in

CSS

Basic Font Loading Strategy

Leverage browser cache

Load fonts dynamically &

use it

Font Face Observerby Bram Stein

https://github.com/bramstein/fontfaceobserver

Detect specific font load (Basic Font Load)

Detect specific font

loafont.load().then(function () {

// Font successfully loads; use webfont class

window.document.documentElement.className += " fonts-loaded";

});

JS

// Font Face Observer is written by Bram Stein:

// https://github.com/bramstein/fontfaceobserver

var font = new FontFaceObserver("Open Sans", {weight: 400});

Toggle class in order to use web fonts

Detect specific font loa

body {

font-family: sans-serif;

}

.fonts-loaded {

body {

font-family: 'Open Sans', sans-serif;

}

}

CSS

<html class="fonts-loaded">

<body>

<!-- Open sans fonts with class added w JS -->

<p>Your content here</p>

</body>

</html>

HTML

Present Solution

Define fallback & web fonts in

CSS

Basic Font Loading Strategy

Leverage browser cache

Load fonts dynamically &

use it

Leverage browser cache

Detect specific font

loa

<!--#if expr="$HTTP_COOKIE=/fonts\-loaded\=true/" -->

<html class="fonts-loaded">

<!--#else -->

<html>

<!--#endif -->

HTML

Set a cookie!

Leverage Browser Cache

Detect specific font

loa

// do not do anything if class is set

if (w.document.documentElement.className.indexOf("fonts-loaded") > -1) {

return;

}

var font = new FontFaceObserver("Open Sans", {weight: 400});

font.load().then(function () {

window.document.documentElement.className += " fonts-loaded";

// Set cookie to optimize for repeat views

document.cookie = "fonts_loaded=true; domain=" + viki.com + "; path=/";

});

JS

Problem

Image Credit: Bram Stein @ Smashing Magazine’s Real Life Responsive Web Design (Web Fonts Performance)

Future Solution

Give ability to define custom loading logic

Preload

Future Solution

FOUT and FOIT can be reduced!Image Credit: https://www.bramstein.com/writing/preload-hints-for-web-fonts.html

Future Solution

<link rel="preload" href="assets/opensans.woff2" as="font" type="font/woff2" crossorigin>

HTML

Important in order to set

priority

Future Solution

Source: http://caniuse.com/#search=preload

Future Solution

Determines how a font-face is displayed when it is downloading & once it is downloaded

Font-Display

Future Solution

@font-face {

font-family: 'Open Sans';

font-display: 'auto';

src: local('Open Sans Light'), local('OpenSans-Light'),

url('open-sans-v13-latin-300.woff2') format('woff2');

}

CSS

Future Solution

@font-face {

font-display: auto | block | swap | fallback | optional;

} Determine by user agent

Invisible text & swap once fonts is loaded

(FOIT)

Show fallback & swap once fonts is loaded

(FOUT)

Same as swap but will show fallback when font fails to

load

Font is used if it is already downloaded; else fallback is used

Source: https://tabatkins.github.io/specs/css-font-display/#font-display-desc

Font Display Specby Tab Atkins

https://tabatkins.github.io/specs/css-font-display/#font-display-desc

Future Solution

Detect specific font loa

@font-face {

font-family: 'Open Sans';

font-display: 'fallback';

src: local('Open Sans'), local('OpenSans-Light'),

url('open-sans.woff2') format('woff2');

}

CSS

<link rel="preload" href="open-sans.woff2" as="font" type="font/woff2">

HTML

Can be combined to make font loading efficient

Comprehensive Guide to Font Loading Strategy

by Zach Leatherman

https://www.zachleat.com/web/comprehensive-webfonts/

Web Font Loading Patternsby Bram Stein

https://www.bramstein.com/writing/web-font-loading-patterns.html

Reduce Render-Blocking Scripts

Problem

Document Object Model

(DOM)

CSS Object Model

(CSSOM)Render Tree Layout Paint

CSS is render blocking!

Contains both content & style

information

Browser calculates the size & position of

elements

Browser picks up layout results and paint pixels to the

screen

“DOM construction cannot proceed until JavaScript is executed, and JavaScript execution cannot proceed until CSSOM is available.” - Ilya Grigorik

Source: https://hpbn.co/primer-on-web-performance/#hypertext-web-pages-and-web-applications

Problem

HTML ParserScript Download

Parser Paused

Script Execute

HTML Parser

Script

Source: http://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html

Document Object Model

(DOM)

CSS Object Model

(CSSOM)Render Tree Layout Paint

CSS is render blocking!

Contains both content & style

information

Browser calculates the size & position

of elements

Browser picks up layout results and paint pixels to the

screen

Time spent on each process should be minimize!

HTML ParserScript Download

Parser Paused

Script Execute

HTML Parser

Script

Problem

CSSJS

Render-blocking scripts

Fonts

Present Solution

HTML

<script src="script.js" async></script>

<script src="script.js" defer></script>

Present Solution

HTML ParserScript Download

Parser Paused

Script Execute

HTML Parser

Async

Defer

HTML ParserScript Download

Script Execute

Source: http://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html

Present Solution

Async —  Scripts with no dependencies

Execution order implementation is

buggy in IE < 10

Removing dependencies completely or inline themOnly applies to small JS code

Defer —  Scripts with dependencies; Execution order matters

Problem

CSSJS

Render-blocking scripts

Fonts

HTML

<noscript>

<link rel="stylesheet" href="path/to/all.css">

</noscript>

</head>

Present Solution

Library to defer the load of CSS: https://github.com/filamentgroup/loadCSS

Inline CSS for first time page load

Include full CSS path in noscript tag for people without JS

<head>

<script>

function loadCSS( href ) { ... }

loadCSS( "path/to/all.css" );

</script>

<style>

.carousel { width: 100%; } .card { background-color: #fff; } ...

</style>

Criticalby Addy Osmani

https://github.com/addyosmani/critical

Size of inline scripts & CSS < 14KB

“...server can send up to 10 TCP packets on a new connection (~14KB) in first roundtrip, and then it must wait for the client to acknowledge this data before it can grow its congestion window and proceed to deliver more data.”

“Due to this TCP behavior, it is important to optimize your content to minimize the number of roundtrips required to deliver the necessary data to perform the first render of the page. Ideally, the ATF (above the fold) content should fit under 14KB — this allows the browser to paint the page after just one roundtrip…”

Source: https://developers.google.com/speed/docs/insights/mobile#delivering-the-sub-one-second-rendering-experience

Limitations of HTTP/1.x

No compression of response headers

No effective resource prioritization

Multiple connections instead of one

HTTP/2Awesome extension to HTTP/1.x

Future Solution

“HTTP/2 modifies how the data is formatted (framed) and transported between the client and server, both of whom manage the entire process, and hides all the complexity from our applications within the new framing layer.” - Ilya Grigorik

Source: https://hpbn.co/http2/

HTTP/1.x

No compression of response headers

No effective resource prioritization

Multiple connections instead of one

HTTP/2

Compress response headers

Allow prioritization of request

One connection for multiple concurrent exchange (multiplexing)

Source: https://hpbn.co/http2/#request-and-response-multiplexing

Future Solution

Future Solution

Server PushAllows push of resources to client without client

requesting for it

“By manually inlining the resource into the document, we are, in effect, pushing that resource to the client, without waiting for the client to request it.” - Ilya Grigorik

Source: https://hpbn.co/http2/#server-push

Server Push

Source: https://hpbn.co/http2/#server-push

Cached by client

Can be reused across other pages

Can be multiplexed along side other request

Can be prioritized by the server

High Performance Browser Networkingby Ilya Grigorik

https://hpbn.co/

Optimize Images

“It’s the problem of efficiently loading appropriately sized content images that fit the page’s design” - Yoav Weiss

Problem

Problem

CSS

img {

max-width: 100%;

}

Will cause bloat since image resolution must be large

Variable Width Images

Present Solution

Art DirectionFixed Width

Images

Present Solution

Fixed Width Images

Dimensions remain the same in other viewport

Higher quality image in retina displays; normal quality is lower-end devices.

Examples: Logo or small profile

pictures

Present Solution

<img src="logo_500px.jpg" srcset="logo_700px.jpg 1.5x,

logo_1000px.jpg 2x, logo_1500px.jpg 3x" width="500"

alt="logo image">

A fallback src and also used for DPR

of 1x

X descriptors: Pixel density of

screen

Browsers will choose the best resource that fits the screen DPR

Variable Width Images

Present Solution

Art DirectionFixed Width

Images

Present Solution

Variable width Images

Dimensions vary based on viewport

Examples: Header images or

thumbnails

Present Solution

<img srcset="image_400.jpg 400w,

image_600.jpg 600w,

image_900.jpg 900w,

image_1200.jpg 1200w"

sizes="(min-width: 840px) 50vw,

(min-width: 450px) 75vw,

100vw"

src="image_600.jpg" alt="Some image for example’s sake">

VW is viewport width100vw = 100% of viewport width

75vw = 75% of the viewport width

Browser will use srcset and sizes to serve image that match the condition

So which will the browsers choose?

<img srcset="image_450.jpg 450w,

image_600.jpg 600w,

image_900.jpg 900w,

image_1200.jpg 1200w"

sizes="(min-width: 840px) 50vw,

(min-width: 600px) 75vw,

100vw"

src="image_600.jpg" alt="Some image for example’s sake">

Browser Viewport: 900px

900 * 0.50 = 450

Retina display with DPR of 2 will load (450 * 2) px of image

Srcset —  Browser hint. No guarantee which image browsers will choose

Present Solution Browser may choose lower res image due

to connectivity

Sizes —  Order matters; Browsers choose the first media condition that match in sizes

sizes="(min-width: 840px) 50vw,

(min-width: 450px) 75vw,

100vw"

sizes="(max-width: 320px) 50vw,

(max-width: 800px) 75vw,

100vw"

Min-width should be organize from

largest to smallest

Max-width should be organize from

smallest to largest

Variable Width Images

Present Solution

Art DirectionFixed Width

Images

Present Solution

Art Direction

Customize image for specific breakpoints

Image varies in quality, crop area, proportions, etc.

Image Credit: Yoav Weiss @ Smashing Magazine’s Real Life Responsive Web Design (Responsive Images)

Present Solution

Present Solution

<picture>

<source media="(min-width: 840px)" srcset="image-large.jpg">

<source media="(min-width: 600px)" srcset="image-medium.jpg">

<img src="image-small.jpg" alt="Art directions">

</picture>Must have img tag for fallback & must appear

after all sources

You can have as many sources as you want &

it will be obeyedOrder matters

img {

max-width: 100%;

}

>

<img srcset="image_450.jpg 450w,

image_600.jpg 600w,

image_900.jpg 900w,

image_1200.jpg 1200w"

sizes="(min-width: 840px) 50vw,

(min-width: 600px) 75vw,

100vw"

src="image_600.jpg" alt="Some image for

example’s sake">

Too much syntax

Future Solution

Missing link between server & client for layout information

Client Hints

Browsers Server

DPRViewport-Width

Width

Perfect fit image!

Future Solution

<img srcset="image_400.jpg 400w,

image_600.jpg 600w,

image_900.jpg 900w,

image_1200.jpg 1200w"

sizes="(min-width: 840px) 50vw,

(min-width: 450px) 75vw,

100vw"

src="image.jpg" alt="Example">

<img src="image.jpg"

sizes="(min-width: 840px) 50vw,

(min-width: 450px) 75vw,

100vw"

alt="Example">

Make markup simpler!

Future Solution

No longer need srcset since image resizing will

be done server side

Future Solution

<meta http-equiv="Accept-CH" content="DPR, Viewport-Width, Width">

Enable Client Hints

<img src="sunset.png" alt="Beautiful Sunset" sizes="50vw"/>

Future Solution

Automating resource selection with Client Hints

by Ilya Grigorik

https://developers.google.com/web/updates/2015/09/automating-resource-selection-with-client-hints

The Anatomy of Responsive Imagesby Jake Archibald

https://jakearchibald.com/2015/anatomy-of-responsive-images/

Responsive Imagesby Yoav Weiss

Smashing Magazine Book 5: Real-Life Responsive Web Design

Thank You!

renaysha.me codepen.io/rrenula @renettarenula

Recommended