- PVSM.RU - https://www.pvsm.ru -

Но стремление к минимизации может пойти дальше, если вы хотите поместить весь сайт в адресную строку браузера. А с помощью сокращателя ссылок даже большой сайт сжимается до восьми байт. В этом случае и не нужен (то есть роль
Вот концептуальный пример:
https://smolsite.zip/UEsDBAoAAAAAAEZkYVdE9j5DPAAAADwAAAAKAAAAaW5kZXguaHRtbDwhRE9DVFlQRSBIVE1MPjx0aXRsZT7S5fHyPC90aXRsZT48cD7P8Oji5fIg9+jy4PLl6//sINXg4fDgIVBLAQIfAAoAAAAAAEZkYVdE9j5DPAAAADwAAAAKACQAAAAAAAAAIAAAAAAAAABpbmRleC5odG1sCgAgAAAAAAABABgAd3HKkqYM2gF3ccqSpgzaAfnEyWumDNoBUEsFBgAAAAABAAEAXAAAAGQAAAAAAA==
Это делается очень просто: создаём статичный HTML-сайт из index.html и других файлов, архивируем всё в ZIP и кодируем в Base64:
$ zip -DXjq9 somesite.zip index.html mylogo.png
$ echo "https://smolsite.zip/`cat somesite.zip | base64 --wrap 0`"
И всё, потом полученный ZIP можно вставлять в адресную строку после https://smolsite.zip/ — и сайт откроется в браузере (на КДПВ). Согласно FAQ [3], сервер разархивирует его содержимое и хранит в памяти 15 минут, хотя теоретически извлечение контента из архива может сделать и сам браузер [4], так что нынешнее серверное решение не вполне оптимально.
Этот сайт можно ещё сильнее сжать с помощью сокращателя ссылок: https://tinyurl.com/4a7huvj2 [5]. В этом случае мы используем сервис сокращения ссылок в качестве бесплатного веб-хостинга.
Smolsite.zip [3] — это часть проекта LWAN [6] по созданию инфраструктуры для максимального производительного, эффективного и легковесного веб-сервера.
Точно также в качестве бесплатного веб-хостинга можно использовать QR-коды, распечатанные на бумаге. Такие сайты откроются в браузере даже в отсутствие интернета. Полностью офлайновый
Такие же URL можно составлять по схеме Data URI [7], например:
data:text/html,<h1>My%20small%20website</h1><p>Look,%20it's%20real!</p>
Вставьте это в адресную строку — и у вас откроется «сайт». Можно использовать его как ">блокнотик для записей, если у вас нет отдельного notepad'а (например, на хромбуке).
Это чем-то напоминает сервис NoPaste [8], который тоже превращает произвольный текст в URL вроде такого [9]. Аналогичные проекты itty.bitty.site [10] и goog.space [11].
Если браузер по какой-то причине обновил страницу и текст в окне потерялся, можно воспользоваться этим советом [12]: сделать дам памяти Firefox и поискать потерянный текст там. Инструкция работает для любых текстовых форм, в том числе для самодельных браузерных «блокнотиков» из предыдущего раздела.
Есть ещё расширение Textarea Cache (Chrome [13] и Firefox [14]), которое сохраняет в кэше текстовые данные из форм.
На Хабре упоминали [15] клуб 1kB [16] для сайтов размером меньше 1 КБ. Кроме него, есть и другие содружества минималистов: например, No JS [17] для сайтов, которые не используют JavaScript, а также No CSS [18].
Наверное, такими темпами стоит ожидать в будущем появления клуба No HTML [19] с веб-страницами в чистом тексте, без необязательных тегов, только необходимый минимум. На самом деле в HTML много опциональных тегов [20], которые необязательно использовать. Согласно официальной спецификации, тег <html> не является обязательным. Его можно удалить и в начале, и в конце документа.
Кроме того, во многих случаях можно безболезненно опустить теги <head> и <body> (в начале и в конце), а также закрывающие теги <li>, <dt>, <dd>, <p>, <rt>, <rp>, <optgroup>, <option>, <colgroup> (в начале и конце), <caption>, <thead>, <tbody> (в начале и конце), <tfoot>, <tr>, <td> и <th> (только внимательно прочитайте условия, при которых теги можно игнорировать). Это информация из официальной документации WHATWG по ссылке выше.
Например, такая таблица:
<table>
<caption>37547 TEE Electric Powered Rail Car Train Functions (Abbreviated)</caption>
<colgroup><col><col><col></colgroup>
<thead>
<tr>
<th>Function</th>
<th>Control Unit</th>
<th>Central Station</th>
</tr>
</thead>
<tbody>
<tr>
<td>Headlights</td>
<td>✔</td>
<td>✔</td>
</tr>
<tr>
<td>Interior Lights</td>
<td>✔</td>
<td>✔</td>
</tr>
<tr>
<td>Electric locomotive operating sounds</td>
<td>✔</td>
<td>✔</td>
</tr>
<tr>
<td>Engineer's cab lighting</td>
<td></td>
<td>✔</td>
</tr>
<tr>
<td>Station Announcements - Swiss</td>
<td></td>
<td>✔</td>
</tr>
</tbody>
</table>
И её полный аналог после удаления необязательных тегов:
<table>
<caption>37547 TEE Electric Powered Rail Car Train Functions (Abbreviated)
<colgroup><col><col><col>
<thead>
<tr> <th>Function <th>Control Unit <th>Central Station
<tbody>
<tr> <td>Headlights <td>✔ <td>✔
<tr> <td>Interior Lights <td>✔ <td>✔
<tr> <td>Electric locomotive operating sounds <td>✔ <td>✔
<tr> <td>Engineer's cab lighting <td> <td>✔
<tr> <td>Station Announcements - Swiss <td> <td>✔
</table>
Или взять стандартный шаблон документа:
<!DOCTYPE HTML>
<html>
<head>
<title>Hello</title>
</head>
<body>
<p>Welcome to this example.</p>
</body>
</html>
Он полностью аналогичен следующему:
<!DOCTYPE HTML><title>Hello</title><p>Welcome to this example.
Если вспомнить, то оригинальная спецификация языка HTML от Тима Бернерса-Ли, опубликованная 29 октября 1991 года, содержала всего 18 тегов [21]: <title>, <nextid>, <a>, <isindex>, <plaintext>, <listing>, <p>, <h1>…<h6>, <address>, <hp1>, <hp2>…, <dl>, <dt>, <dd>, <ul>, <li>,<menu> и <dir>. Недавно документу исполнилось 32 года. Говорят, что HTML был разработан под сильным влиянием универсального языка разметки SGML, оттуда вся его структура и логика.
В этом году инженеры Википедии рассказали [22], как они оптимизировали JS-скрипты, значительно ускорив загрузку страниц. Этот опыт может быть полезен и другим веб-разработчикам.
Оптимизация Википедии свелась к двум простым шагам:
_enable, который отвечает за разворачивание/сворачивание контента.

Внутри него больше всего времени уходит на вызов метода .on("click") jQuery. Если посмотреть код, то вызов .on("click") прикреплял прослушку событий почти к каждой ссылке на странице, чтобы открывался соответствующий раздел, если это внутренняя ссылка с хэшем.
function _enable( $container, prefix, page, isClosed ) {
...
// Restricted to links created by editors and thus outside our
// control T166544 - don't do this for reference links - they will
// be handled elsewhere
var $link = $container.find("a:not(.reference a)");
$link.on("click", function () {
// the link might be an internal link with a hash. if it is check
// if we need to reveal any sections.
if (
$link.attr("href") !== undefined &&
$link.attr("href").indexOf("#") > -1
) {
checkHash();
}
});
util.getWindow().on("hashchange", function () {
checkHash();
});
}
В длинных статьях Википедии тысячи ссылок [24], что и увеличивало время выполнения на 200+ мс на слабеньких устройствах.
Этот факт не заметили раньше по двум причинам:
Самое интересное, что этот фрагмент, по сути, вообще не нужен. Дальше в коде страницы уже была прослушка события hashchange. Поэтому метод checkHash вызывался дважды при нажатии на ссылку, так что предыдущий код является полностью избыточным. Оказалось, что его можно удалить полностью [25], сразу же резко сократив время загрузки мобильных страниц на сайте.
initMediaViewer, который выполнялся около 100 мс. Он прикреплял прослушку событий к каждой уменьшенной картинке на странице, чтобы нажатие по ней выводило на экран полное изображение:
/**
* Event handler for clicking on an image thumbnail
*
* @param {jQuery.Event} ev
* @ignore
*/
function onClickImage(ev) {
ev.preventDefault();
routeThumbnail($(this).data("thumb"));
}
/**
* Add routes to images and handle clicks
*
* @method
* @ignore
* @param {jQuery.Object} [$container] Optional container to search
* within
*/
function initMediaViewer($container) {
currentPageHTMLParser
.getThumbnails($container)
.forEach(function (thumb) {
thumb.$el.off().data("thumb", thumb).on("click", onClickImage);
});
}
Аналогично предыдущему случаю, от этого страдают страницы с тысячами картинок [26], а задержка может составить сотни миллисекунд.
Решением стало делегирование событий [27]. Это мощная техника, позволяющая прикрепить обработчик событий не ко всем элементам, а только к одному общему предку. В нашем случае он прикрепляется к контейнеру, который содержит все картинки, а источник событий проверяется через свойство event.target в обработчике. Как вариант, можно использовать event.target.closest(selector) из API [28]. Проверка показывает, откуда поступило нажатие: по уменьшенной копии или нет.
Вот как выглядит новый код [29]:
/**
* Event handler for clicking on an image thumbnail
*
* @param {MouseEvent} ev
* @ignore
*/
function onClickImage(ev) {
var el = ev.target.closest(PageHTMLParser.THUMB_SELECTOR);
if (!el) {
return;
}
var thumb = currentPageHTMLParser.getThumbnail($(el));
if (!thumb) {
return;
}
ev.preventDefault();
routeThumbnail(thumb);
}
/**
* Add routes to images and handle clicks
*
* @method
* @ignore
* @param {HTMLElement} container Container to search within
*/
function initMediaViewer(container) {
container.addEventListener("click", onClickImage);
}
До оптимизации время загрузки скриптов на мобильных устройствах нижнего уровня доходило до 600 мс [30], что неприемлемо долго для интерактивных интерфейсов. В такой ситуации страница блокируется: ни прокрутка, ни переход по ссылкам, ни нажатие кнопок не работают, что вызывает раздражение у посетителей. И нужно учитывать, что выполнение скриптов 600 мс — это только первый этап ожидания. Затем пользователь должен ещё дождаться выполнения соответствующей задачи обработчика кликов (click handler) и рендеринга страницы.
В результате оптимизации удалось снизить время выполнения скриптов вдвое, т. е. до 300 мс. Хотя это тоже долговато. По современным стандартам веб-разработки [31] всё, что дольше 100 мс, считается «медленным» процессом, поскольку пользователь не считает такое взаимодействие мгновенным и нативным.
Разработчики Google ввели для измерения подобных «блокирующих» взаимодействий специальную метрику Total Blocking Time. Из-за фоновых задержек на простаивающие задачи реальный бюджет для обработки ввода не превышает 50 мс:

По крайней мере, таковы рекомендации экспертов [32].
Синтетические тесты Википедии [33] показали, что в результате оптимизаций время загрузки мобильной версии на телефоне Moto G (5) сократилось на 280 мс, из них примерно 200 мс принесла первая оптимизация с удалением кода. Конечно, это старенький бюджетный смартфон, но и на новых моделях ускорение загрузки мобильной Википедии в апреле-мае 2023 года тоже было заметно на глаз.

После выпуска в продакшн мониторинг на реальных пользователях подтвердил эти изменения [34].
Для дальнейшей оптимизации TBT опытные специалисты рекомендуют разбивать большие задачи [35] на ряд мелких.

После разбиения задач на части у браузера больше возможностей реагировать на более приоритетную работу, в том числе и на взаимодействие с пользователем. Другими словами, время отклика может кардинально уменьшиться.

Так или иначе, но этот пример ещё раз доказывает, что заметный результат приносят точечные, целевые воздействия. Иногда достаточно потратить пять-десять минут, посидеть, внимательно посмотреть профайлер и подумать. Этого достаточно, чтобы выполнить какую-нибудь простую, но очень важную оптимизацию.
Автор: Анатолий Ализар
Источник [38]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/vikipediya/388403
Ссылки в тексте:
[1] в портативный формат одного исполняемого файла: https://habr.com/ru/companies/ruvds/articles/682150/
[2] хостинг: https://www.reg.ru/?rlink=reflink-717
[3] FAQ: https://smolsite.zip/
[4] извлечение контента из архива может сделать и сам браузер: https://developer.mozilla.org/en-US/docs/Web/API/Compression_Streams_API
[5] https://tinyurl.com/4a7huvj2: https://tinyurl.com/4a7huvj2
[6] LWAN: https://lwan.ws/
[7] Data URI: https://en.wikipedia.org/wiki/Data_URI_scheme
[8] NoPaste: https://nopaste.boris.sh/
[9] вроде такого: https://nopaste.boris.sh/#XQAAAQArAAAAAAAAAABoJ9YnxwgTkhVTSJ0dZKG62HJepQhVmNsN/bFECJJiIA0sPuQpGzUeSFeZuA3++4PDgA==
[10] itty.bitty.site: https://itty.bitty.site/#/?eJyzKbC7MP9iw4UdFzZd2HqxSeFi+4UdF5subADirRd2X+y/sEfhwtILGy5sBKrZoGijX2AHADWGH1A=
[11] goog.space: https://goog.space/#data=eyJ2YWx1ZSI6ItCf0YDQuNCy0LXRgiDRh9C40YLQsNGC0LXQu9GP0Lwg0KXQsNCx0YDQsCEifQ%3D%3D
[12] этим советом: https://merveilles.town/@j3s/110981322978284262
[13] Chrome: https://chrome.google.com/webstore/detail/textarea-cache/chpphekfimlabghbdankokcohcmnbmab
[14] Firefox: https://addons.mozilla.org/en-US/firefox/addon/textarea-cache/
[15] упоминали: https://habr.com/ru/companies/ruvds/articles/692840/
[16] клуб 1kB: https://1kb.club/
[17] No JS: https://no-js.club/
[18] No CSS: https://nocss.club/
[19] No HTML: https://web.archive.org/web/20230122032143/https://no-ht.ml/
[20] много опциональных тегов: https://html.spec.whatwg.org/multipage/syntax.html#optional-tags
[21] всего 18 тегов: https://www.w3.org/History/19921103-hypertext/hypertext/WWW/MarkUp/Tags.html
[22] рассказали: https://www.nray.dev/blog/300ms-faster-reducing-wikipedias-total-blocking-time/
[23] самый простой и быстрый способ: https://timkadlec.com/remembers/2020-04-21-the-cost-of-javascript-frameworks/
[24] тысячи ссылок: https://en.wikipedia.org/wiki/United_States
[25] удалить полностью: https://gerrit.wikimedia.org/r/c/mediawiki/extensions/MobileFrontend/+/908333/6/src/mobile.startup/Toggler.js#22
[26] страницы с тысячами картинок: https://en.wikipedia.org/wiki/B8_polytope
[27] делегирование событий: https://learn.javascript.ru/event-delegation
[28] API: https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
[29] новый код: https://gerrit.wikimedia.org/r/c/mediawiki/skins/MinervaNeue/+/908675/10/resources/skins.minerva.scripts/initMobile.js#66
[30] до 600 мс: https://phabricator.wikimedia.org/T241139
[31] современным стандартам веб-разработки: https://web.dev/rail/#response-process-events-in-under-50ms
[32] рекомендации экспертов: https://web.dev/articles/optimize-long-tasks#task_management_strategies
[33] Синтетические тесты Википедии: https://developer.mozilla.org/en-US/docs/Web/Performance/Rum-vs-Synthetic#synthetic_monitoring
[34] подтвердил эти изменения: https://www.nray.dev/_astro/long-task-duration-results.a598c9a5.png
[35] разбивать большие задачи: https://web.dev/articles/optimize-long-tasks#task-management-strategies
[36] 1: https://habr.com/ru/companies/ruvds/articles/731960/
[37] 2: https://habr.com/ru/companies/ruvds/articles/748950/
[38] Источник: https://habr.com/ru/companies/ruvds/articles/771388/?utm_source=habrahabr&utm_medium=rss&utm_campaign=771388
Нажмите здесь для печати.