Оптимизируй это

WSD #2017 Kiyv

Привет, WSD!

ChernivtsiJS
ChernivtsiJS

Оптимизируй это

Постер к фильму Анализируй это
кадр из фильма Чужой Завет

Первый звоночек

Колокол Херсонеса

Первый звоночек

chrome dev tools
chrome dev tools
chrome dev tools
chrome dev tools

Что не так?

Пользователь начнет взаимодействовать с сайтом минимум через 6 секунд

Изображение секундомера

Да ладно

Мем Питер Паркер

leBoutique

chrome devtools

otto.ua

chrome devtools

В сравнении

  Сайт друга leBoutique otto.ua modnakasta.ua
Transferred, Mb 5,7 4,9 1,6 4,0
TTFB, ms >2000 62 1020 115
DOMContentLoaded, sec
(DCL)
6,34 3,72 3,92 0,8
High priority request 19+ 6 12 1

DCL vs TTFI

+ 1 сек = – 7% конверсии, по версии Айри.рф

100 мс задержки приводят к снижению продаж на 1%, по версии Amazon

Мем Питер Паркер

Подходы к оптимизации

Оптимизация для первой загрузки

1. Доставка

На скорость доставки контента влияет

Мы начали с ограничений

DOMContentLoaded

Как было

			<head>
			    <link rel="stylesheet" href="main.css">
			    <script src="small.js"></script>
			    <script src="main.js"></script>
			    <script src="second-1.js"></script>
			    <script src="second-2.js"></script>
			    <script src="second-7.js"></script>
			</head>
		
inspector
inspector

Популярный совет

			<head>
			    <link rel="stylesheet" href="main.css">
			    <script src="small.js"></script>
			    <script src="main.js"></script>
			</head>
			    <script src="second-1.js"></script>
			    <script src="second-2.js"></script>
			    <script src="second-7.js"></script>
			</body>
		
inspector

Добавляем асинхронности

			<head>
			    <link rel="stylesheet" href="main.css">
			    <script src="small.js"></script>
			    <script src="main.js"></script>
			</head>
			    <script src="second-1.js" defer></script>
			    <script src="second-2.js" defer></script>
			    <script src="second-7.js" defer></script>
			</body>
		
inspector

Нужно больше асинхронности

			<head>
			    <link rel="stylesheet" href="main.css">
			    <script src="small.js"></script>
			    <script src="main.js"></script>
			</head>
			    <script src="second-1.js" async></script>
			    <script src="second-2.js" async></script>
			    <script src="second-7.js" async></script>
			</body>
		
inspector

Что мы сделали

25 кадр

google chrome logo

2. Приоритет загрузки

Приоритеты загрузки

Помогаем браузеру

			<link rel="prefetch" href="/source/">
			<link rel="dns-prefetch" href="https://youdomain.com">
			<link rel="prerender" href="/next-page/">
			 
			<link rel="preload" href="some.js" as="script">
			<link rel="preload" href="some.css" as="style">
			<link rel="preload" href="picture.jpg" as="image">
			<link rel="preload" href="some.woff" as="font">
			...
		

Как посмотреть?

chrome://net-internals/#prerender

opera://net-internals/#prerender

prefetch

vs

preload

Очень низкий приоритет приоритет по "as"
dns-prefetch, prerender, prefetch, preconnect любой ресурс
can i use
can i use
отображается в браузере
отображается в браузере

Что мы сделали

3. Ленивая загрузка

Ленивая загрузка изображений

			<img src="blank.gif" data-src="cool.jpg">
			/* или */ 
			<img src="cool-patch.svg" data-src="cool.jpg">

			...
		

Ленивая загрузка изображений

С 2015 года в обсуждении
6 октября появился Intent to Implement: image async attribute

<image src="photo.jpg" async=on>

4. Critical CSS

Addy Osmani photo Addy Osmani critical css plugin

Critical CSS

Addy Osmani

  1. собираем css для видимой части страницы
  2. инйлайним полученный css
  3. остальной css подключаем ниже с понижением приоритета

Critical CSS

Critical CSS

5. Оптимизация графики

Работаем с форматами

JPEG, PNG, GIF
WebP
JPEG-XR
JPEG-2000

WebP

JPEG

JPEG

WebP

Отдавайте графику под клиент

			<picture>
			    <source srcset="photo.jxr" type="image/vnd.ms-photo">
			    <source srcset="photo.jp2" type="image/jp2">
			    <source srcset="photo.webp" type="image/webp">
			    <img src="default.jpg" alt="image description">
			</picture>
		

Отдавайте графику под клиент

			<picture>
			    <source srcset="photo.webp, photo-2x.webp 2x" type="image/webp">
			    <source srcset="photo-2x.jpg 2x" type="image/jpeg">
			    <img src="default.jpg" alt="image description">
			</picture>
		

Инструментарий

Инструментарий

Инструментарий

Командная строка, runtime

Что выбрать?

bike in winter

Что выбрать?

react, angular and vue.js logo
react, angular and vue.js logo

NGINX + PageSpeed, с ноября 2010

Что мы сделали

Не думайте о том, что умеет клиент

			<picture>
			    <source srcset="photo.webp" type="image/webp">
			    <img src="photo.jpg" alt="image description">
			</picture>
		
Accept: image/webp

Важно

rewrite_css, rewrite_javascript

Внимание! Опасно!

Оптимизация для повторной загрузки

Кэширование

Кэширование

Ты можешь быть бесконечно прав,
но какой в этом толк,
если у тебя Cache-Control: max-age=0

Фото девушки под дождем

HTTP 1.1

Cache-Control

ETag

HTTP 1.0

Expires

Кэширование

Где смотреть метрики

Результат

  Было Стало
Transferred, Mb 5,7 3,2
TTFB, ms >2000 442
DOMContentLoaded, sec 6,34 2,09
High priority request 19+ 1

Вжух
и у нас быстрый сайт

Мем

Спасибо!

Denis Zavgorodny
web technologist, founder of @ChernivtsiJS,
co-founder @NodeSchool Chernivtsi

@DenisZavgorodny

denis.zavgorodny@gmail.com

https://www.google.com.ua/search?q=%D0%B2%D0%BB%D0%B8%D1%8F%D0%BD%D0%B8%D0%B5+%D1%81%D0%BA%D0%BE%D1%80%D0%BE%D1%81%D1%82%D0%B8+%D1%81%D0%B0%D0%B9%D1%82%D0%B0+%D0%BD%D0%B0+%D0%BA%D0%BE%D0%BD%D0%B2%D0%B5%D1%80%D1%81%D0%B8%D1%8E&oq=%D0%B2%D0%BB%D0%B8%D1%8F%D0%BD%D0%B8%D0%B5+%D1%81%D0%BA%D0%BE%D1%80%D0%BE%D1%81%D1%82%D0%B8+%D1%81%D0%B0%D0%B9%D1%82%D0%B0+%D0%BD%D0%B0+%D0%BA%D0%BE%D0%BD%D0%B2%D0%B5%D1%80%D1%81%D0%B8%D1%8E&aqs=chrome..69i57.6606j0j7&sourceid=chrome&ie=UTF-8 https://xn--80aqc2a.xn--p1ai/blog/%D0%BA%D0%B0%D0%BA-%D1%81%D0%BA%D0%BE%D1%80%D0%BE%D1%81%D1%82%D1%8C-%D1%81%D0%B0%D0%B9%D1%82%D0%B0-%D0%B2%D0%BB%D0%B8%D1%8F%D0%B5%D1%82-%D0%BD%D0%B0-%D0%B4%D0%BE%D1%85%D0%BE%D0%B4/ https://habrahabr.ru/company/netologyru/blog/337842/ https://www.google.com.ua/search?q=%D1%83%D0%B2%D0%B5%D0%BB%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D0%B5+%D1%81%D0%BA%D0%BE%D1%80%D0%BE%D1%81%D1%82%D0%B8+%D0%B7%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B8+%D1%81%D0%B0%D0%B9%D1%82%D0%B0+%D1%81%D0%BD%D0%B8%D0%B6%D0%B0%D0%B5%D1%82&oq=%D1%83%D0%B2%D0%B5%D0%BB%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D0%B5+%D1%81%D0%BA%D0%BE%D1%80%D0%BE%D1%81%D1%82%D0%B8+%D0%B7%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B8+%D1%81%D0%B0%D0%B9%D1%82%D0%B0+%D1%81%D0%BD%D0%B8%D0%B6%D0%B0%D0%B5%D1%82&aqs=chrome..69i57.10147j0j7&sourceid=chrome&ie=UTF-8 http://denis-zavgorodny.github.io/2016/12/25/Image-Optimization/ http://denis-zavgorodny.github.io/ https://moz.com/blog/optimizing-page-speed-actionable-tips-for-seos-and-web-developers https://www.keycdn.com/blog/website-performance-optimization/ https://medium.com/web-standards/webp-worth-it-fc08e230f46e https://www.zachleat.com/web/webp/ https://w3c.github.io/preload/#x2.link-type-preload https://html.spec.whatwg.org/multipage/links.html# https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content https://developer.mozilla.org/ru/docs/Web/HTTP/Headers/Cache-Control