Chrome Audit на 500: Частина 1. Лендінг

Інструменти розробника браузера хром є вкладка «Audit». На ній розташувався інструмент який називається Lighthouse, служить він для аналізу-наскільки добре зроблено веб додаток.


Нещодавно я вирішив протестувати один додаток і жахнувся результатами. Відразу за декількома розділами оцінка перебувала в червоній зоні. Я почав вивчати що ж з моїм додатком не те. І знайшов у результатах аналізу дуже великий список корисних рекомендацій, виконав їх отримав 500 балів. У результаті додаток стало завантажуються значно швидше, а я переглянув кілька концепцій щодо методу побудови додатків. А в цій статті я хочу поділитися самими цікавими рішеннями до яких я прийшов.

Якщо у вас немає можливості встановити хром, то можна поставити lighthouse з npm і працювати з ним з консолі.

У статті я не став порівнювати кожну рекомендацію за конкретним розділом, замість цього я розбив розділи за рішеннями які я застосував і які сподобалися Ligthouse. Це далеко не все, що він рекомендує, це тільки найцікавіше. Решта рекомендації дуже прості, а такі як SEO всім вже давно знайомі.

Performance

 

Вибір сервера

Це самий банальний рада, але саме це є фундаментом для всієї продуктивності. На щастя знайти гарне рішення просто, це будь ЦОД рівня Tier 3 або Tier 4. Сам цей статус нічого не говорить про швидкість, він говорить про те що власники подбали про якість.

Ініціалізація програми

Коли то в браузерах був тільки html. Потім з’явився javascript і бізнес логіка. Сьогодні логіки на клієнті стало настільки багато, що html з нею не справляється і став зовсім не потрібен. Але, т. к. браузер не може почати завантажуватися з JavaScript файлу, нам доведеться розмістити невеликий шматок html для запуску додатку.

В ідеалі він повинен виглядати приблизно так:

<!DOCTYPE html>
<html lang="ru">
<head>
 <title>Назва сайту</title>

 <link rel="manifest" href="./manifest.webmanifest">
 <link rel="shortcut icon" href="content/images/favicon.ico" type="image/x-icon">

 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" charset="utf-8"/>
 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
 <meta name="viewport" content="width=device-width" />
 <meta name="theme-color" content="#425566">
 <meta name="Description" content="опис сайту>
</head>
<body>
 <div id="loader">
loading
</div>
 <script async>
 // todo: пізніше додамо скрипти завантаження
</script>
</body>
</html>

У ньому не повинно бути ніякого контенту, тільки код, необхідний для ініціалізації додатка, який довантажити вже сам додаток і контент.

У даній статті не розглядаємо оптимізацію для пошукових роботів, але скажу що простіше всього відловити конкретного бота і віддати то що конкретного боту потрібно. Бот гугла сам все зрозуміє з контенту, який довантажити пізніше.

Використовувати сплеш скрін

Ми всі звикли до сплеш скринам при завантаженні в мобільних додатках, і навіть при завантаженні операційної системи, але мало хто використовує сплеш скрін веб додатку. Саме його ми будемо розміщувати в блоці loader, щоб користувач не нудьгував поки вантажиться сам додаток.

Як сплеш скрін, як варіант, можна використовувати css анімацію або просто картинку, як робиться на мобільних телефонах. Єдина умова, він повинен бути дуже легкий.


Що ми отримуємо? Користувачі з повільним інтернетом миттєво отримають реакцію від сайту, вони не будуть милуватися білим екраном і гадати працює сайт взагалі чи ні. Користувачі з швидким інтернетом швидше за все його не побачать, але навіть у них бувають лаги в роботі інтернету.

В якості цікавого прикладу використання сплеш скрін наведу сайт dockstation, де ну дуже довге завантаження сайту прикрашає симпатична хвиля. Насправді саме так будуть бачити ваш додаток люди з повільним інтернетом.

І відразу поспішаю засмутити тих хто думає що сплеш скріном можна обдурити Lighthouse і розмістити важке додаток за ним. Він все бачить, і не видасть вам гарну оцінку за тяжкий додаток.

Ініціалізація програми

Тепер, коли ми відволікаємо увагу користувача картинками, настав час завантажити додаток. Для цього ми всередину блоку script вставимо наступний скрипт.

// 1. Підключаємо ServiceWorker, детальніше розглянемо в блоці PWA
if (navigator.serviceWorker && !navigator.serviceWorker.controller) {
 navigator.serviceWorker.register('pwabuider-sw.js', { scope: './' });
}

// 2. Підключаємо необхідні стилі
[
"./content/font.css",
"./content/grid.css"
].forEach(function(url){
 var style = document.createElement("link");
 style.href = url;
 style.rel = "stylesheet";
document.head.appendChild(style);
});

// 3. Підключаємо необхідні скрипти
[
 "./scripts/polyfills.min.js", // або vendors.min.js
 "./scripts/main.min.js" // spa додаток
].forEach(function(url){
 const script = document.createElement("script");
 script.src = url;
 script.async = false;
document.head.appendChild(script);
});

З чого він складається:

  1. Підключення PWA — розглянемо у відповідному розділі. Підключати його треба якомога раніше, тому що можливо в pwa вже буде все необхідне для роботи сайту й запитів на сервер більше не буде.
  2. Підключення стилів — по мірі необхідності підключаємо стилі. В ідеалі цього коду взагалі не повинно бути і стилі повинні підключати ваші компоненти по мірі необхідності.
  3. Підключення скриптів — підключаємо програму. Він повинен складатися всього з двох цих скриптів. Всі інші скрипти (карти, аналітика, бібліотеки) не впливають на відображення першого екрана (не всієї сторінки) завантажуються вже після показу першого екрана програми. Аналітику вже повинен довантажити компонент аналітики після завантаження програми. Якість аналітики від цього не постраждає, а системи аналітики підтримують завантаження після завантаження програми. Карти повинні зануритися тільки після того, як користувач до них доскролит і вони потраплять в екран. Зі сторонніми бібліотеками, необхідних для роботи конкретних компонентів, аналогічно.

В результаті, трохи змінивши пріоритети, ми отримуємо швидку видачу додатка. Тим самим користувачі та пошукові боти задоволені швидкістю, і при цьому не ущемили аналітику.

Лінива завантаження і відтворення

Дуже важливим параметром є те наскільки швидко отрисуется перший екран, і користувач зможе почати взаємодіяти з цією сторінкою. І тут варто використовувати наступні оптимізації:

1. Ліниве відтворення. Необхідно відображати тільки ту частину сторінки куди дивиться користувач, а малювання важких компонентів або картинок вже робити коли користувач до них доскролился.

Читайте також  Де брати посилання для сайту, якщо купувати не можна?

Хорошим рішенням тут може служити компоненти lazy-block і lazy-img:

<div>
<p>текст</p>
 <lazy-img src="..."/>
</div>
<lazy-block>
 важкі блоки
</lazy-block>
<lazy-block>
 важкі блоки
</lazy-block>
<lazy-block>
 важкі блоки
</lazy-block>

Сенс в тому що вони буду стежити за скролом користувача і у випадку, якщо компонент потрапляє в область екрана буде отрисовываться. Це можна порівняти з технікою віртуального скрола (приклад) який усім добре знайомий по стінах соціальних мереж. Ми можемо скролити вічно, а вони ніколи не гальмують.

Але не варто забувати і про гугл боте, який бачить spa, але не скролит всю страниу. Тому якщо ви не подбаєте, то він не побачить ваш контент.

2. Якщо який-небудь з компонентів використовує зовнішню залежність, він повинен буде завантажити її сам по мірі необхідності. Наприклад це може бути блок з картами, графіками або 3D графікою. А з недавніх пір в JS з’явився спосіб зробити це дуже просто:

class Demo {
 constructor() {
this.init();
}
 private async init() {
 const module = await import('./external.mjs'); // динамічний імпорт
module.default();
module.doStuff();
}
}

В результаті користувач завантажує тільки те що йому треба, що сильно економить ресурси користувача і сервера.

Мінімізація бандла

І… так, ви подумали не про те, мова не про минификации в Terser (UglifyJS), а про те що б конкретному браузеру віддавати тільки те, що йому потрібно.

Справа в тому що браузери постійно розвиваються, у них з’являється нове API, розробники починають використовувати його, а для сумісності зі старими браузерами підключають полифиллы і транспиллеры. В результаті утворюється проблема що користувачі з новітніми браузерами, яких близько 80%, отримують код який призначений для користувачів IE11, транспиленный і з полифилами.

Проблема цього коду в тому що він містить багато зайвого тексту, а продуктивність його в 3 рази менше (за моїми суб’єктивними оцінками) чим оригіналу. Набагато логічніше робити кілька бандлів для різних версій браузерів. Бандл з ES2017 кодом для Chrome 73 з мінімумом полифилов, бандл з ES5 для IE11 з максимум полифилов і т. д.

Про те, як за один раз зібрати бандли різних версій я писав у попередній статті. А для вибору правильної версії в браузері трохи модифікуємо скрипт підключення програми:

var esVersion = ".es2017";
try{
 eval('"use strict"; class foo {}');
}catch(e){
 esVersion = ".es5";
}

[
 "./scripts/polyfills" + esVersion + ".min.js",
 "./scripts/main" + esVersion + ".min.js"
].forEach(function(url){
 const script = document.createElement("script");
 script.src = url;
 script.async = false;
document.head.appendChild(script);
});

В результаті користувачі сучасних браузерів отримають максимально легку і продуктивну програму, а користувачі IE11 отримають те, що вони заслужили.

Ще один цікавий спосіб минификацииДуже цікава бібліотека для скорочення бандла на 50%, на жаль, з непередбачуваним результатом.

Мінімізація коду

Дуже популярна проблема коли розробники починають підключати все на що впаде на їх погляд. В результаті іноді можна спостерігати програми які важать по 5-15 мб і навіть більше. Тому до вибору бібліотек треба підходити з розумом.

Замість важких фреймворків начебто Angular або React, краще вибрати більш легкі аналоги: vue, preact, mithril і т. п. Вони анітрохи не поступаються своїм іменитим аналогам, а ось економія на розмірі бандла може скласти рази.

Уникайте використання важких бібліотек. Замість використання таких бібліотек як jquery, lodash, moment, rxjs і будь-яка інша в минифицированном розмірі >100кб, постарайтеся глибше вивчити алгоритми і знайти рішення на нативному JS. Як правило на нативному скрипті можна написати простіше, а ви позбавляєтеся від зайвої важкої залежності.

Минификация картинок

Напевно всі фронтэнд розробники знають про формат картинок webp, а так само знають про необхідність минифицировать картинки під необхідний розмір відображення. Але чомусь майже всі розробники це ігнорують. І причина в цьому на мою вкрай проста, люди не розуміють як це робиться і застосовується в різних браузерах.

З цього тут я наведу дуже простий рецепт вирішення всіх проблем з картинками. В основі цього рецепту лежить інструмент обробки і конвертації зображень Sharp. Виділяється він дуже продуманим пайплайном, за рахунок якого швидкість обробки зображень в 30-40 разів вища, ніж у аналогів. А сам час складання сотень зображень з величезних джерел у різні розміри та формати порівнянні зі швидкістю збірки сучасного фронтенда.

Для використання Sharp необхідно написати скрипт, я використовую його в зв’язці з glob для рекурсивного пошуку зображень в папці з вихідними картинками, а сам скрипт ховаю за утилітою запуск завдань gulp. Приклад моєї збірки:

gulp.task('core-min-images', async () => {
 const fs = require('fs');
 const path = require('path');
 const glob = require('glob');
 const sharp = require('sharp');

 // 1. Рекурсивно отримуємо список файлів для обробки за допомогою утиліти glob
 const files = await new Promise((resolve, reject) => {
 glob('src/content/**/*.{jpeg,jpg,png}', {}, async (er files) => {
 !er ? resolve(files) : reject(er);
});
});

 // 2. Запускаємо процес обробки списку зображень
 let completed = 1;
 await Promise.all(files.map(async (file) => {

 const outFile = file.replace(/^src/, 'www');
 const outDir = path.dirname(outFile);

 // 2.1. Перевіряємо наявність директорії для оброблених файлів
 if (!fs.existsSync(outDir)) {
 fs.mkdirSync(outDir, { recursive: true });
}

 // 2.2. Зчитуємо початкове зображення
 const origin = sharp(file);

 // 2.3. Генеруємо зображення в дозволі 1920 по горизонталі з збереженням
 // пропорцій і зберігає у формат jpg/png і webp з дефолтними якістю (80%)
 const size1920 = origin.resize({ width: 1920 });
 await size1920.toFile(outFile.replace(/.(jpeg|jpg|png)$/, '-1920w.$1'));
 await size1920.toFile(outFile.replace(/.(jpeg|jpg|png)$/, '-1920w.webp'));

 // 2.4. Аналогічно для вирішення 480 по горизонталі
 const size480 = origin.resize({ width: 480 });
 await size480.toFile(outFile.replace(/.(jpeg|jpg|png)$/, '-480w.$1'));
 await size480.toFile(outFile.replace(/.(jpeg|jpg|png)$/, '-480w.webp'));

 // 2.5. Аналогічно для вирішення 120 по горизонталі
 const size120 = origin.resize({ width: 120 });
 await size120.toFile(outFile.replace(/.(jpeg|jpg|png)$/, '-120w.$1'));
 await size120.toFile(outFile.replace(/.(jpeg|jpg|png)$/, '-120w.webp'));

 // 2.6. Це для більш цікавих логів
 console.log(`Complete image ${completed++} of ${files.length}:`, file);
}));

});

У підсумку з кожної вихідної картинки величезного розміру ми отримуємо оптимізовані зображення для різних розмірів монітора і різних браузерів. Тепер нам треба навчитися ними користуватися. Тут теж все просто, якщо раніше ми писали так:

<img src="sample.jpg"/>

То тепер треба писати так:

<picture>
 <source srcset="img/sample-480w.webp" type="image/webp">
 <source srcset="img/sample-480w.jpg" type="image/jpeg"> 
 <img src="img/sample-480w.jpg" alt="Альтернативний текст!">
</picture>

І тоді браузер сам вибере найбільш зручний для нього формат. Також цей варіант можна доповнити чуйними картинками:

<picture>
 <source srcset="img/sample-480w.webp, img/sample-960w.webp 2x" type="image/webp">
 <source srcset="img/sample-480w.jpg, img/sample-960w.webp 2x" type="image/jpeg"> 
 <img src="img/sample-480w.jpg" alt="Альтернативний текст!">
</picture>

А з урахуванням того, що тепер можна генерувати картинки на етапі складання програми, виходить на всі картинки буде однаковий набір форматів і дозволів, а значить ми можете уніфікувати цю логіку і приховати за яким небудь компонентом, наприклад тим же <lazy-img src="img/sample.jpg">.

Мініфікація стилів

Завантажуйте тільки ті стилі, які використовують ваші компоненти. В ідеалі коли стилі прив’язані компонентів, і вбудовуються в будинок тільки коли малюється сам компонент.

Читайте також  Red Hat буде поглинений IBM

Мінімізуйте назва класів. Величезна довжина вкладених або БЕМ селекторів в стилях погано впливають на розмір вашого додатка. В даний час повно інструментів які генерують стилі з унікальними селекторами: JSS, Styled Components, CSS Modules.

Мініфікація DOM

Всі ми знайомі з html, але мало хто замислювався, що це всього лише проста абстракція над деревом дуже складним об’єктів. Ланцюжок спадкування для елемента div виглядає наступним чином:

HTMLDivElement -> HTMLElement -> Element -> Node -> EventTarget

І у кожного об’єкта в цій ланцюжка від 10 до 100 властивостей і методів, які споживають багато пам’яті. І все це багатство повинен враховувати движок DOM для побудови картинки яку ми бачимо. Тому намагайтеся не використовувати зайві елементи в будинку.

Мініифікуйте HTML. Видаляйте все що ви використовуєте для форматування html на етапі написання. Справа в тому що пробіли які використовуються при написанні коду, в браузері також перетворюються в об’єкти будинку:

TextNode -> Node -> EventTarget

Видаляйте коментарі. Вони також є елементом будинку і споживають багато ресурсів:

Comment -> CharacterData -> Node -> EventTarget

Хорошою практикою може служити використання шаблонізаторів на jsx. Справа в тому що при компіляції він перетворюється в нативний js код, який не генерує прогалин, коментарів і ніколи не помиляється у відкритті і закритті тегів.

Поганою практикою, я б навіть сказав кошмаром, може служити сайт facebook.com. Наведу фрагменти html:

Фрагмент сторінки html

<!-- Фрагмент 1 -->
<div class="">
 <div class="_42ef">
 <div class="_25-w">
 <div class="_17pg">
 <div class="_1rwk">
 <form class=" _129h">
 <div class=" _3d2q _65tb _7c_r _4w79">
 <div class="_5rp7">
 <div class="_1p1t">
 <div class="_1p1v" id="placeholder-77m1n" style="white-space: pre-wrap;">
 Напишіть коментар...
</div>
</div>
</div>
</div>
 <ul class="_1obb">
...li...
</ul>
</form>
</div>
</div>
</div>
</div>
</div>

<!-- Фрагмент 2 -->
<div>
<div>
 <div class="_3nd0">
 <div class="_1mwp navigationFocus _395 _4c_p _5bu_ _34nd _21mu _5yk1" role="presentation" style="" id="js_u">
 <div class="_5yk2" tabindex="-1">
 <div class="_5rp7">
 <div class="_1p1t" style="">
 <div class="_1p1v" id="placeholder-6t6up" style="white-space: pre-wrap;">
 Що у вас нового?
</div>
</div>
 <div class="_5rpb">
 <div aria-autocomplete="list" aria-controls="js_1" aria-describedby="placeholder-6t6up"
 aria-multiline="true" class="notranslate _5rpu" contenteditable="true"
 data-testid="status-attachment-mentions-input" role="textbox" spellcheck="true"
 style="outline: none; user-select: text; white-space: pre-wrap; overflow-wrap: break-word;">
 <div data-contents="true">
 <div class="" data-block="true" data-editor="6t6up" data-offset-key="6b02n-0-0">
 <div data-offset-key="6b02n-0-0" class="_1mf _1mj">
 <span data-offset-key="6b02n-0-0">
 <br data-text="true">
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

Як бачимо використовується вкладеність з десяти елементів, але ця вкладеність не виконує ніякої роботи. Перший фрагмент всього лише виводить текст «Напишіть коментар…» та іконки, другий «Що у вас нового?». В результаті такого не раціонального використання DOM вся продуктивність шаблонізатора React просто зводиться нанівець, і сайт стає одним з найбільш повільних що я знаю.

Progressive Web App

 

Файл маніфесту

PWA дозволяє користуватися вашим веб додаток як нативним додатком. При включенні підтримки на сайті в меню браузера з’являється кнопка інсталяції вашого сайту на пристрій (Windows, Android, iOS), після чого воно починає вести себе як нативне і працювати в режимі оффлайн, і все це в обхід магазинів додатків.

Включити на сайті підтримку PWA насправді дуже просто. Досить включити в html-сторінки посилання на файл маніфесту. Файл маніфесту можна згенерувати на сайті pwabuilder.com.

Докладно зупиняти на процесі підключення я не буду, тому що цей розділ вартий окремої великої статті та на хабре вже є достатньо хороші.

Сервіс воркер

На підключенні файлу маніфесту налаштування PWA не закінчується, також необхідно підключити ServiceWorker який буде відповідати за роботу в режимі оффлайн.

Приклад коду можна подивитися там же на pwabuilder.com:

// This is the service worker with the Cache-first network

const CACHE = "pwabuilder-precache";
const precacheFiles = [
 /* Add an array of files to precache for your app */
];

self.addEventListener. ("install", function (event) {
 console.log("[PWA Builder] Install Event processing");

 console.log("[PWA Builder] Skip waiting on install");
self.skipWaiting();

event.waitUntil(
 caches.open(CACHE).then(function (cache) {
 console.log("[PWA Builder] Caching pages during install");
 return cache.addAll(precacheFiles);
})
);
});

// Allow sw to control of current page
self.addEventListener. ("activate", function (event) {
 console.log("[PWA Builder] Claiming clients for current page");
event.waitUntil(self.clients.claim());
});

// If any fetch fails, it will look for the request in the cache and serve it from there first
self.addEventListener. ("fetch", function (event) { 
 if (event.request.method !== "GET") return;

event.respondWith(
fromCache(event.request).then(
 function (response) {
 // The response was found in the cache so we responde with it and update the entry

 // This is where we call the server to get the version of the newest
 // file to use the next time we show view
event.waitUntil(
 fetch(event.request).then(function (response) {
 return updateCache(event.request, response);
})
);

 return response;
},
 function () {
 // The response was not found in the cache so we look for it on the server
 return fetch(event.request)
 .then(function (response) {
 // If request was success, add or update it in the cache
 event.waitUntil(updateCache(event.request, response.clone()));

 return response;
})
 .catch(function (error) {
 console.log("[PWA Builder] Network request failed and no cache." + error);
});
}
)
);
});

function fromCache(request) {
 // Check to see if you have it in the cache
 // Return response
 // If not in the cache, then return
 return caches.open(CACHE).then(function (cache) {
 return cache.match(request).then(function (matching) {
 if (!matching || matching.status === 404) {
 return Promise.reject("no match");
}

 return matching;
});
});
}

function updateCache(request, response) {
 return caches.open(CACHE).then(function (cache) {
 return cache.put(request, response);
});
}

Як бачимо з коду усі відповіді від сервера кешируються, але в режимі онлайн кеш не використовується. А використовуватися вони починають вже коли з’єднання з сервером пропало. Тим самим користувач переміщаючись по сайту може і не помітити короткочасного зникнення інтернету, і навіть якщо інтернет пропав надовго, у користувача зберігається можливість пересуватися по вже закеширувати даними.

Читайте також  Що таке карта релевантності і як її правильно скласти

Наведений скрипт простий, але підходить тільки для лендінгів і є лише відправною точкою для написання воркера для більш серйозного веб додатка. Але про це в другій частині цієї статті. Також технологія зручна тим не ламає роботу в старих браузерах, тобто в браузерах рівня IE11 не треба переписувати логіку, в ньому просто не буде працювати режим оффлайна.

Accessibility

 

Коректність атрибутів для людей з особливими потребами

Людей з ідеальним здоров’ям дуже мало, а от людей з браком здоров’я, у тому числі по зору, на жаль, дуже багато. І щоб цим людям було комфортніше користуватися вашим веб додатком досить дотримуватися досить простих правил:

  • Використовуйте досить контрастні кольори. За статистикою Моз 20% людей мають проблеми із зором. А поганий контраст сайтів тільки ускладнює їм життя, а здоровим людям збільшує стомлюваність.
  • Расставте tabindex. Дозвольте користуватися сайтом без мишки і сенсорних пристроїв. Грамотне розташуванням переходів з допомогою клавіатури сильно спрощує процес заповнення форм.
  • Атрибут aria-label на посиланнях. Дозволяє екранним дикторам зачитувати текст всередині атрибута.
  • Атрибут alt на картинках. Аналогічно попередньому. Крім того відобразить текст в разі неможливості завантаження картинки.
  • Мова документу. Позначте тег html атрибутом з мовою lang=«код мови». Це допоможе допоміжних інструментів правильно налаштуватися на роботу.

Як бачите вимог насправді трохи і дотримуватися їх просто. Але чомусь більшість розробників ігнорують ці правила, навіть коли мова йде про спеціалізованих сайтах для людей з особливими потребами.

Best Practices

 

Відокремте фронтенд додаток від серверного додатка

По-перше, якщо ви все ще рендерите html на сервері, то перестаньте вже це робити. Перенесення процесу візуалізації на клієнта на два порядки зменшує навантаження на сервер і, як результат, вартість підтримки серверного додатка. А клієнти отримують додаток з миттєвою реакцією на їх дії.

По друге відокремте ваш клієнтський SPA додаток від бекенд програми. Ви ж не тримайте разом серверний додаток і windows додаток, і андройд додаток, і iOS додаток. Ось і веб додаток вже давно є самодостатнім додатком, яке може працювати і без сервера і навіть у режимі офлайн. Найпопулярніша помилка що я бачу це коли бекенд фреймворк начебто Spring або Asp.Net займаються роздачею статики, в тому числі зібраним SPA додатком. Давно пора перестати так робити і винести статику і SPA в окремий микросервис і заховати за спеціалізованим веб сервером для роздачі статики, наприклад nginx.


У підсумку кожна технологія буде займатися тим, чим вона повинна займатися і в неї це виходить найкраще. Nginx роздасть статику з правильними заголовками і максимальною швидкістю, серверна програма підготує дані для клієнта, клієнтський пристрій збере всі разом і відобразить користувачеві.

Налаштування проксі сервера HTTP/2, gzip, cache

Ваше бекенд додаток не повинно безпосередньо спілкуватися з клієнтом, найкраще заховати його за спеціалізованими воротами, наприклад проксі сервер Nginx. І на ньому вже налаштувати все необхідне для комфортного спілкування клієнтського пристрою із сервером.

  • Налаштування SSL сертифікат. Насправді встановлення SSL з’єднання відносно дороге задоволення, але необхідне, так що зробити його краще на легковажному і швидкому проксі сервер, наприклад Nginx. А ось і Nginx Asp.Net Core вміють переиспользовать між собою наявні з’єднання, що сильно економить ресурси.
  • GZIP Включіть і налаштуйте стиснення відповідей клієнту. Текст добре стискається в десятки разів що економить час і трафік клієнту.
  • Cache Закешируйте всі стислі відповіді. Також можна кешувати всі Get, Head запити до бекенду, що на порядок знижує на нього навантаження.
  • Налаштуйте роутинг і балансування Грамотно розподілити навантаження між бекенд додатками.

Знову з-за того що ця частина гідна окремої великої статті, не описую детально весь процес установки, але порекомендую сайту для генерації конфига nginx nginxconfig.io.

SEO

 

Створіть мета теги в html і використовуйте семантичну розмітку

Про це вже всі знають, і як правило використовують. Тому щоб виправити досить подивитися на список зауважень Lighthouse і поправити.

Кінець

На перший погляд може здатися що тут написано дуже багато інформації, яку важко дотримуватися, але насправді це не так. Вся ця інформація відображає сучасний стан фронтенд розробки, а дотримання всіх цих правил майже не займає часу.

У цій статті не описується як з оптимізувати адмінки, форми та інший ентерпрайз, але про це буде друга частина.

Степан Лютий

Обожнюю технології в сучасному світі. Хоча частенько і замислююся над тим, як далеко вони нас заведуть. Не те, щоб я прям і знаюся на ядрах, пікселях, коллайдерах і інших парсеках. Просто приходжу в захват від того, що може в творчому пориві вигадати людський розум.

You may also like...

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *