Дорогая цена стилей

Никита Дубко, Яндекс

Дорогая
цена стилей

Никита Дубко, Яндекс

Кто я?

Зачем?

Harry Roberts: FaCSSt—CSS and Performance
Парсим CSS: performance tips & tricks

CSS 🤷‍♂️

Я вижу
HTML

Я вижу
CSS

Я не вижу
JavaScript

38% пользователей прекратят пользоваться сайтом, если контент или разметка не привлекательны.
88% онлайн-потребителей скорее всего не вернутся на сайт после плохого впечатления.
27 Eye-Opening Website Statistics: Is Your Website Costing You Clients?
Из-за режима самоизоляции интернет-трафик вырос на 10–30%

0,1с
×
200.000.000

=
232 дня

🕵🏻‍♂️

Замеряйте! 📐

Системный подход к скорости: онлайн-измерения на фронтенде

Инструменты

RUM

Improve your Website’s Performance with Real User Monitoring

Real User Monitoring

Improve your Website’s Performance with Real User Monitoring

🤖 vs 🙋‍♂️

FCP

First Contentful Paint (FCP)

LCP

Largest Contentful Paint (LCP)

Загрузка CSS

Critical Rendering Path

Critical Rendering Path
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS — язык программирования</title>
    <link rel="stylesheet" href="/main.ac74gsac.css">
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS — язык программирования</title>
    <link rel="stylesheet" href="/main.ac74gsac.css">
</head>
<body>
    <h1>Правда-правда!</h1>
</body>
</html>

<link>

<link rel="stylesheet" href="https://awesome.cdn/style.css">

1. Куда идти?

https://awesome.cdn/style.css
What Is DNS? | How DNS Works

awesome.cdn

222.111.3.4

Как ускориться?

static.mysite.zz

mysite.zz/static

https://twitter.com/jsunderhood/status/1243447428918976512
<link rel="dns-prefetch" href="https://awesome.cdn">
Preload, prefetch and other <link> tags

2. Как идти?

https://awesome.cdn/style.css
How HTTPS works

HTTPS

  1. Получить SSL-сертификат с сервера
  2. Проверить сертификат в Центре сертификации
  3. Сгенерировать ключи для общения
  4. Зашифровать запрос приватным ключом
  5. Расшифровать ответ приватным ключом

Как ускориться?

HTTPS

  1. Получить SSL-сертификат с сервера
  2. Проверить сертификат без Центра сертификации
  3. Сгенерировать ключи для общения
  4. Зашифровать запрос приватным ключом
  5. Расшифровать ответ приватным ключом

Не работает в Chrome ☹️

Как ускориться?

CDN 🕸

HTTPS = f(HTTP)

httpvshttps.com

HTTP = f(TCP/IP)

Building Blocks of TCP

TCP Fast Open

tools.ietf.org/html/rfc7413

3. Что забирать?

Сервер

Клиент

User-Agent

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36
.example {
    display: -ms-grid;
    display: grid;
    -webkit-transition: all .5s;
    -o-transition: all .5s;
    transition: all .5s;
    -webkit-user-select: none;
       -moz-user-select: none;
        -ms-user-select: none;
            user-select: none;
    background: -webkit-gradient(linear, left top, left bottom, from(white), to(black));
    background: -o-linear-gradient(top, white, black);
    background: linear-gradient(to bottom, white, black);
}
.example {
    display: -ms-grid;
    display: grid;
    -webkit-transition: all .5s;
    -o-transition: all .5s;
    transition: all .5s;
    -webkit-user-select: none;
       -moz-user-select: none;
        -ms-user-select: none;
            user-select: none;
    background: -webkit-gradient(linear, left top, left bottom, from(white), to(black));
    background: -o-linear-gradient(top, white, black);
    background: linear-gradient(to bottom, white, black);
}
Встречайте бабушку, Виталий Харисов
SSR: DIY, Джеймс Аквух

HTTP/2 Server Push

A Comprehensive Guide To HTTP/2 Server Push
Link: </css /styles.css>; rel=preload; as=style

TCP

Slow-Start

Сегмент = 1460 байт

Первое окно = 14600 байт

Виталий Харисов, 10k

1459 байт = 1 сегмент
1 байт = 1 сегмент

Отправляем меньше

Минификация

Сжатие

159515 bootstrap.min.css
 22783 index.html
 23699 bootstrap.min.css.gz
  6524 index.html.gz
------------
 30223 total gzipped


182145 index-css-inline.html
 30380 index-css-inline.html.gz

Оптимизация

Убрать неиспользуемое ✂️

Find Unused JavaScript And CSS Code With The Coverage Tab In Chrome DevTools
How Do You Remove Unused CSS From a Site?
CSS code coverage: идентификация неиспользуемого CSS кода / Антон Холкин (Booking.com)
victor-homyakov/detect-unused-css-selectors.js

Вам нужен весь
Bootstrap?

Не отдавать неиспользуемое ⚙️

БЭМ
Reduce the Scope and Complexity of Style Calculations

CSS-in-JS

Секрет успеха

<div class="block"></div>

<style>
    .block {
        display: block;
    }
</style>

Убрать значения по умолчанию

currentColor

.wrapper {
    color: #0077FF;
    border-color: #0077FF;
}

.wrapper:hover {
    color: #11EE66;
    border-color: #11EE66;
}
.wrapper {
    color: #0077FF;
    border-color: currentColor;
}

.wrapper:hover {
    color: #11EE66;
}

base64 ⚠️

Использование base64

Base64 Encoding & Performance, Part 1: What’s Up with Base64?

SVG + base64 =

SVG + URL-encoder = 💛

URL-encoder для SVG

CSS Grid

.container {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-gap: 20px;
}

Слабо повторить в 5 строчек на float? 🙃

4 CSS Grid Properties (and One Value) for Most of Your Layout Needs

Atomic CSS 🤭

            <div class="Row Bgc(#0280ae) C(#fff)">
    <div class="Fl(start) W(300px) Ta(c) P(10px)">
        Box-1
    </div>
    <div class="Fl(end) W(300px) Ta(c) P(10px)">
        Box-2
    </div>
</div>
        
Atomic CSS

Tailwind CSS

tailwindcss.com
<div class="md:flex bg-white rounded-lg p-6">
    <img class="h-16 w-16 rounded-full" src="avatar.jpg">
    <div class="text-center md:text-left">
    <h2 class="text-lg">Erin Lindford</h2>
    <div class="text-purple-500">Customer Support</div>
    <div class="text-gray-600">erinlindford@example.com</div>
    <div class="text-gray-600">(555) 765-4321</div>
    </div>
</div>
tailwindcss.com
.block { }
.name { }

.a { }
.b { }
Reduce bundle size via one-letter css classname hash strategy

Замеряйте! 📐

Скачали! 🥳

Что всё это время видел пользователь?

@import "blocks/header.css";

Preload Scanner

CSS and Network Performance

@import ❌

Constructing the Object Model
body > div.card > p.text > span.icon ~ * + * {
    color: red !important;
}
.card_type_warning {
    color: red;
}
* + * + * + * {
    /* WHY??? */
}
Writing efficient CSS selectors
background: url(img.jpg) 20px 20px / 20px 20px no-repeat;

background-image: url(img.jpg);
background-position-x: 20px;
background-position-y: 20px;
background-size: 20px 20px;
background-repeat-x: no-repeat;
background-repeat-y: no-repeat;
background-attachment: initial;
background-origin: initial;
background-clip: initial;
background-color: initial;
Braces to Pixels

Размер ⚖️ Скорость

JS заблокирован

Adding Interactivity with JavaScript

Critical CSS ⚡️

Extract critical CSS
<!DOCTYPE html>
<html>
<head>
    <style>
    .critical {
        /* ... */
    }
    </style>
</head>
<body>
    ...
    <link rel="stylesheet" href="after.css">
</body>
</html>

Инструменты

filamentgroup / loadCSS

<link rel="preload"
    href="path/to/mystylesheet.css"
    as="style"
    onload="this.onload=null;this.rel='stylesheet'">
<noscript>
    <link rel="stylesheet" href="path/to/mystylesheet.css">
</noscript>
filamentgroup / loadCSS
<link rel="stylesheet"
      href="style.css"
      media="(min-width: 1000px)">
<head>
</head>
<body>
    <!-- HTTP/2 push this resource, or inline it -->
    <link rel="stylesheet" href="/site-header.css">
    <header>…</header>

    <link rel="stylesheet" href="/article.css">
    <main>…</main>

    <link rel="stylesheet" href="/comment.css">
    <section class="comments">…</section>
</body>
The future of loading CSS

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

Intersection Observer

#define FOR_EACH_COMPOSITING_REASON(V)                                        \
/* Intrinsic reasons that can be known right away by the layer. */          \
V(3DTransform)                                                              \
V(Video)                                                                    \
V(Canvas)                                                                   \
V(Plugin)                                                                   \
V(IFrame)                                                                   \
V(BackfaceVisibilityHidden)                                                 \
V(ActiveTransformAnimation)                                                 \
V(ActiveOpacityAnimation)                                                   \
V(ActiveFilterAnimation)                                                    \
V(ActiveBackdropFilterAnimation)                                            \
V(ScrollDependentPosition)                                                  \
V(OverflowScrolling)                                                        \
V(OverflowScrollingParent)                                                  \
V(OutOfFlowClipping)                                                        \
V(VideoOverlay)                                                             \
V(WillChangeTransform)                                                      \
V(WillChangeOpacity)                                                        \
V(WillChangeFilter)                                                         \
V(WillChangeBackdropFilter)                                                 \
...
compositing_reasons.h

Меньше слоёв

А если вернусь? 👋🏻

Мгновенно 🤔

Cache-Control: public, max-age=31536000
HTTP Caching

Инвалидация кэша 😅

Служебные работяги!

Service Workers

Про сервис-воркеры. Снова! Кирилл Чугаинов

⚠️ Браузер ничего не обещает ⚠️

Local Storage?

Медленный 🐌

IndexedDB?

Замеряйте! 📐

Спросить заранее!

<link rel="prefetch" href="/style.css" as="style" />
<link rel="preload" href="/style.css" as="style" />

<link rel="preconnect" href="https://example.com" />
<link rel="dns-prefetch" href="https://example.com" />

<link rel="prerender" href="https://example.com/about.html" />
Preload, prefetch и другие теги
Как мы научились предсказывать запрос пользователя и ускорили загрузку поисковой выдачи

Что дальше?

Web Performance 101

Прибирайтесь 🧽

Спасибо за внимание!

mefody.dev/talks/css-cost/
@dark_mefody
mefody@yandex-team.ru
Parser DOM / CSSOM Cascade Layout Paint Composite