Записки фронтендера
Lazy Loading стал доступным нативно!🔥 Ранее, чтобы подгрузить картинку только в тот момент, когда она нужна, использовали различные библиотеки или писали собственные решения на основе IntersectionObserver. Это было достаточно муторно. Недавно в HTML был…
Новые элементы нативного Lazy Loading
Ранее нам были доступны
⚙️ Поддерживается пока что только в Chrome
Ранее нам были доступны
<img> и <iframe>, но со 148 версии Chrome атрибут loading="lazy" теперь может быть передан и для элементов <audio> и <video>⚙️ Поддерживается пока что только в Chrome
🔥3❤1
This media is not supported in your browser
VIEW IN TELEGRAM
Прокачали подчёркивание текста
В Chrome 148 версии свойству
Значения:
⚙️ Поддержка браузерами широкая
В Chrome 148 версии свойству
text-decoration-skip-ink добавили значение all. Если ещё не сталкивались, то оно управляет тем, будет ли полоса подчёркивания проходить через символы насквозь или будут использоваться небольшие промежутки.Значения:
auto (по-умолчанию) — браузер самостоятельно решает (для латиницы обычно появляются промежутки, а для иероглифов нет)none — промежутки не добавляются, подчёркивание идёт сплошной полосой через весь текстall — промежутки добавляются для любых языков⚙️ Поддержка браузерами широкая
👍3❤1🔥1
HTML в Canvas
В Chrome 148 версии добавили возможность рисовать Canvas при помощи обыкновенного HTML.
Для того, чтобы это работало, необходимо
Для перерисовки всех состояний элемента, скажем
1) 2D API —
2) WebGL —
3) WebGPU —
Для того, чтобы элемент всегда совпадал с фактическим расположением отрисованной картинки (на видео показал разницу), его сдвигают при помощи
Всё это оборачивается в обработчик
Также при помощи метода
⚙️ Таблицу на caniuse ещё не завезли
В Chrome 148 версии добавили возможность рисовать Canvas при помощи обыкновенного HTML.
Для того, чтобы это работало, необходимо
<canvas> элементу передать специальный атрибут layoutsubtree и положить внутрь него любой HTML код.Для перерисовки всех состояний элемента, скажем
:hover эффекта или выделения текста, используются следующие методы:1) 2D API —
ctx.drawElementImage(element)2) WebGL —
gl.texElementImage2D(element)3) WebGPU —
copyElementImageToTexture(...)Для того, чтобы элемент всегда совпадал с фактическим расположением отрисованной картинки (на видео показал разницу), его сдвигают при помощи
transform, полученным из одного из перечисленных выше методов.Всё это оборачивается в обработчик
paint, который реагирует на изменения внутренних DOM элементов и вызывает переданный колбек.<canvas id="canvas" layoutsubtree>
<input id="input-element" type="text">
</canvas>
const ctx = document.getElementById('canvas').getContext('2d');
const inputElement = document.getElementById('input-element');
const canvas = document.getElementById('canvas');
canvas.addEventListener('paint', () => {
ctx.reset();
const transform = ctx.drawElementImage(inputElement, 50, 50);
inputElement.style.transform = transform.toString();
});Также при помощи метода
canvas.requestPaint(), мы можем при надобности принудительно вызвать событие paint.⚙️ Таблицу на caniuse ещё не завезли
🤔4❤2
Топ донатов месяца
Месяц подошёл к концу, поэтому хочу поблагодарить всех, кто поддержал канал в этот раз!
Boosty:
❗️Подписки временно решил приостановить
Телеграм:
⭐️ @maunsh 4 звёздочки
Месяц подошёл к концу, поэтому хочу поблагодарить всех, кто поддержал канал в этот раз!
Boosty:
❗️Подписки временно решил приостановить
Телеграм:
⭐️ @maunsh 4 звёздочки
❤3🤬1
Новый HTML элемент 🔥
В Chrome 148 версии добавили тег
Подобно ранее представленному <geolocation>, внешний вид кнопки может быть изменён стилями, а вот текст и другое содержимое внутри неё изменить уже не получится (они устанавливаются браузером автоматически). Также не получится её скрыть, сделать прозрачной или как-то по-другому "заставить" пользователя нажать на неё неосознанно. Она просто перестанет работать.
Если необходимо установить стороннее PWA приложение, то можно указать его URL в атрибуте
Данный элемент генерирует 3 типа событий:
1)
2)
3)
⚙️ Таблицу на caniuse пока не добавили
В Chrome 148 версии добавили тег
<install>, который представляет собой кнопку, по нажатию на которую, браузер предложит скачать ваше PWA приложение на устройство.<install></install>
Подобно ранее представленному <geolocation>, внешний вид кнопки может быть изменён стилями, а вот текст и другое содержимое внутри неё изменить уже не получится (они устанавливаются браузером автоматически). Также не получится её скрыть, сделать прозрачной или как-то по-другому "заставить" пользователя нажать на неё неосознанно. Она просто перестанет работать.
Если необходимо установить стороннее PWA приложение, то можно указать его URL в атрибуте
installurl:<install installurl="https://awesome-app.com/">
</install>
Данный элемент генерирует 3 типа событий:
1)
promptaction — пользователь установил приложение2)
promptdismiss — пользователь отменил установку3)
validationstatuschanged — кнопка стала доступна / недоступна по причине перекрытия другим элементом или по какой-то другойinstallButton.addEventListener('promptaction', () => {
console.log('Приложение установлено');
});⚙️ Таблицу на caniuse пока не добавили
🔥5❤1
Решена проблема со сбросом кеша 🔥
Ранее, если вы передавали в параметре URL обновлённое значение или меняли порядок нескольких параметров, то браузер считал, что старый HTTP-кеш этой страницы переиспользовать уже нельзя и создавал новый, в результате чего все ресурсы повторно скачивались с сервера.
К примеру, у нас есть параметр
В 148 версии Chrome добавили новый заголовок
Возможные значения:
1)
2)
3)
4)
Через запятую можно указывать сразу несколько подобных конструкций:
⚙️ Поддержка браузерами пока что небольшая
Ранее, если вы передавали в параметре URL обновлённое значение или меняли порядок нескольких параметров, то браузер считал, что старый HTTP-кеш этой страницы переиспользовать уже нельзя и создавал новый, в результате чего все ресурсы повторно скачивались с сервера.
К примеру, у нас есть параметр
utm_source, который позволяет отследить, с какого ресурса к нам пришёл пользователь. Он является всего лишь информационным маркером для нашей аналитики и никак не влияет на отображаемый контент, но из-за него кеширование на странице работать не будет:https://mysite.com/storages/732?utm_source=chatgpt.com
https://mysite.com/storages/732?utm_source=telegram
https://mysite.com/storages/732?utm_source=google
В 148 версии Chrome добавили новый заголовок
No-Vary-Search, который позволяет задать исключения из этих правил:HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
No-Vary-Search: params=("utm_source" "utm_medium" "utm_campaign")
Cache-Control: max-age=300
Возможные значения:
1)
key-order — изменение порядка параметров URL не влияет на кеш2)
params=("utm_source" "utm_campaign") — изменение значений указанных параметров не влияет на кеш3)
params — изменение значений любых параметров не влияет на кеш4)
except=("id" "utm_source") — изменение всех значений, кроме конкретных параметров не влияет на кешЧерез запятую можно указывать сразу несколько подобных конструкций:
No-Vary-Search: key-order, params, except=("id")⚙️ Поддержка браузерами пока что небольшая
👍2❤1
Media is too big
VIEW IN TELEGRAM
Сервис поиска альтернативных библиотек
Позволяет найти аналоги устаревшим, плохо оптимизированным или небезопасным npm-пакетам. Помимо стандартного поиска, есть сканер
🔗 Ссылка на сервис
Позволяет найти аналоги устаревшим, плохо оптимизированным или небезопасным npm-пакетам. Помимо стандартного поиска, есть сканер
package.json, который указывает на плохие зависимости в проекте.🔗 Ссылка на сервис
💘3❤1
Lazy loading HTML фрагментов 🤯
Представим, что наш сервер настроен так, что HTML он нам отдаёт не целиком, а небольшими частями. Тогда кусочки, которые пришли раньше, будут анализироваться и отрисовываться сразу, не дожидаясь оставшейся части приложения. Но у нас вполне может возникнуть ситуация, когда какие-то из них мы не готовы отдать сразу, т.к. предварительно на сервере нужно произвести сложные вычисления. В таком случае оставшаяся загрузка кода может быть заблокирована до полной загрузки отдельного чанка.
Для решения этой проблемы Chrome в 148 версии ввёл специальный синтаксис, который позволяет указать место в коде, которое будет пропущено, но может быть заполнено в будущем, если вернётся
Также существует дополнительный синтаксис, который позволяет на время загрузки подставить какой-то лоадер, чтобы не показывать пользователю пустой экран:
Если HTML уже полностью подгрузился и мы хотим что-то подставить уже впоследствии, то мы можем воспользоваться новыми стриминговыми методами JS (в следующем посте расскажу о них подробнее):
🔗 Ссылка на полифил
⚙️ Таблицу на caniuse пока не добавили
Представим, что наш сервер настроен так, что HTML он нам отдаёт не целиком, а небольшими частями. Тогда кусочки, которые пришли раньше, будут анализироваться и отрисовываться сразу, не дожидаясь оставшейся части приложения. Но у нас вполне может возникнуть ситуация, когда какие-то из них мы не готовы отдать сразу, т.к. предварительно на сервере нужно произвести сложные вычисления. В таком случае оставшаяся загрузка кода может быть заблокирована до полной загрузки отдельного чанка.
Для решения этой проблемы Chrome в 148 версии ввёл специальный синтаксис, который позволяет указать место в коде, которое будет пропущено, но может быть заполнено в будущем, если вернётся
<template> с таким же идентификатором:<div>
<?marker name="placeholder">
</div>
...
<template for="placeholder">
Какой-то <em>HTML код</em>
</template>
Также существует дополнительный синтаксис, который позволяет на время загрузки подставить какой-то лоадер, чтобы не показывать пользователю пустой экран:
<div>
<?start name="placeholder">
Загрузка...
<?end>
</div>
...
<template for="placeholder">
Какой-то <em>HTML код</em>
</template>
Если HTML уже полностью подгрузился и мы хотим что-то подставить уже впоследствии, то мы можем воспользоваться новыми стриминговыми методами JS (в следующем посте расскажу о них подробнее):
const response = await fetch('/dashboard');
await document.body.streamHTMLUnsafe(
response.body
);🔗 Ссылка на полифил
⚙️ Таблицу на caniuse пока не добавили
❤🔥3👍3🔥2😇1
Новые методы для работы с HTML 🔥
Предыдущие методы вроде
Chrome в 148 версии решил это исправить, добавив целый ряд новых методов:
🐥
🐥
🐥
🐥
🐥
Каждый из них внутренне прогоняет код через Sanitizer API, удаляются все вложенные скрипты и прочий потенциально вредоносный код.
Также у всех этих методов стриминговый и "небезопасный" аналоги или и то и другое вместе:
🦆
Небезопасные методы, как вы уже наверное догадываетесь, не имеют встроенного Sanitizer API (его нужно писать самостоятельно), а стриминговые, если у вас бекенд присылает HTML кусочками, позволяют также кусочками его и отрисовывать:
⚙️ Поддержка браузерами (пока таблицы есть только для setHTML и setHTMLUnsafe)
Предыдущие методы вроде
innerHTML, insertAdjacentHTML работали по-разному, были небезопасными, а также имели неявные названия.Chrome в 148 версии решил это исправить, добавив целый ряд новых методов:
🐥
setHTML(html, options) — заменяет внутреннее содержимое элемента на новый HTML
🐥 replaceWithHTML(html, options) — заменяет сам элемент целиком на переданный HTML🐥
beforeHTML(html, options) — вставляет HTML перед элементом🐥
afterHTML(html, options) — вставляет HTML после элемента🐥
prependHTML(html, options) — вставляет HTML внутрь элемента в качестве первого дочернего узла🐥
appendHTML(html, options) — вставляет HTML внутрь элемента в качестве последнего дочернего узлаКаждый из них внутренне прогоняет код через Sanitizer API, удаляются все вложенные скрипты и прочий потенциально вредоносный код.
Также у всех этих методов стриминговый и "небезопасный" аналоги или и то и другое вместе:
🦆
streamHTML(options)
🦆 setHTMLUnsafe(html, options)🦆 streamHTMLUnsafe(options)🦆 и так далее...Небезопасные методы, как вы уже наверное догадываетесь, не имеют встроенного Sanitizer API (его нужно писать самостоятельно), а стриминговые, если у вас бекенд присылает HTML кусочками, позволяют также кусочками его и отрисовывать:
const response = await fetch('/dashboard');
await document.body.streamHTMLUnsafe(
response.body
);⚙️ Поддержка браузерами (пока таблицы есть только для setHTML и setHTMLUnsafe)
❤1👍1🔥1
Исправлена древняя проблема разделения элементов 🔥
Ранее, чтобы отделить
Chrome в 149 версии решил исправить это и расширил контекст, в котором можно применять свойства семейства
Чтобы не писать 3 отдельных свойства, их можно объединить под единым
Можно указывать сразу несколько значений через запятую (тогда они в таком же порядке и будут применяться):
Первому промежутку будет назначен
Также, чтобы несколько раз не прописывать одно и то же значение, была добавлена специальная функция, которая первым аргументом принимает число повторений, а вторым само значение:
⚙️ Таблицу на caniuse пока не добавили
Ранее, чтобы отделить
grid или flex элементы друг от друга рамкой, приходилось использовать стандартный border и это было дико неудобно.Chrome в 149 версии решил исправить это и расширил контекст, в котором можно применять свойства семейства
rule:<div class="container">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
.container {
display: flex;
gap: 10px;
column-rule-width: 2px;
column-rule-style: dashed;
column-rule-color: #000;
}Чтобы не писать 3 отдельных свойства, их можно объединить под единым
column-rule или row-rule:row-rule: 2px dashed #000;
Можно указывать сразу несколько значений через запятую (тогда они в таком же порядке и будут применяться):
row-rule-width: 1px, 2px, 3px;
Первому промежутку будет назначен
1px, второму 2px, третьему 3px, четвёртому снова 1px и так далее.Также, чтобы несколько раз не прописывать одно и то же значение, была добавлена специальная функция, которая первым аргументом принимает число повторений, а вторым само значение:
row-rule-width: repeat(3, 1px);
/* Аналогично */
row-rule-width: 1px 1px 1px;
⚙️ Таблицу на caniuse пока не добавили
Продолжение предыдущего поста
Помимо базовых свойств, которые я перечислил ранее, в Chrome 149 версии были также добавлены и некоторые другие:
🐠
🐠
🐠
🐠
🐠
🐠
🐠
Значения для
🪲
🪲
🪲
🪲
🦊
🦊
🦊
🐬
🐬
❗️За основу в примере был взят именно
❗️Помимо перечисленных свойств, есть ещё ряд других с точно таким же функционалом, которые в рамках поста я решил опустить
🔗 Ссылка на спецификацию
⚙️ Поддержка браузерами (column-rule-inset, row-rule-inset, column-rule-visibility-items, row-rule-visibility-items, column-rule-break, row-rule-break, rule-overlap)
Помимо базовых свойств, которые я перечислил ранее, в Chrome 149 версии были также добавлены и некоторые другие:
🐠
column-rule-inset — позволяет отступами по краям расширить или сузить полосы, разделяющие колонки 🐠
row-rule-inset — позволяет отступами по краям расширить или сузить полосы, разделяющие строки 🐠
column-rule-visibility-items — позволяет скрыть полосы, разделяющие колонки в тех местах, где отсутствуют элементы сетки🐠
row-rule-visibility-items — позволяет скрыть полосы, разделяющие строки в тех местах, где отсутствуют элементы сетки🐠
column-rule-break — указывает правила разрыва полос, разделяющих колонки🐠
row-rule-break — указывает правила разрыва полос, разделяющих строки🐠
rule-overlap — определяет, будут полосы строк отображены поверх полос колонок или наоборотЗначения для
column-* и row-rule-inset могут быть заданы тремя различными способами:🐈 column-rule-inset: 10px; — отступы задаются для всех полос, разделяющих колонки🐈 column-rule-inset: 10px 10px / 10px 10px; — первый параметр задаёт отступ верхним концам полос, которые выходят за край родительского контейнера, второй нижним, третий верхним концам, которые упираются во внутренние элементы сетки, четвёртый то же самое, но для нижних полос🐈 column-rule-inset: 10px / 10px; — первый параметр задаёт отступы для всех полос, которые выходят за край родительского контейнера, второй для всех, которые упираются во внутренние элементы сеткиcolumn-* и row-rule-visibility-items свойства имеют значения:🪲
normal — полосы рисуются по-разному в зависимости от контейнера (grid, flex, мультиколоночный текст)🪲
all — полосы рисуются даже сквозь пустые области🪲
around — полосы в пустых областях рисуются только по кругу🪲
between — полосы в пустых областях вообще не рисуютсяcolumn-* и row-rule-break свойства имеют значения:🦊
none — полосы на части не разбиваются и упираются во внутренние элементы🦊
normal — полосы обрезаются по краям и не упираются во внутренние элементы🦊
intersection — все полосы прерываются в местах пересечения c другими полосамиrule-overlap имеет 2 значения:🐬
row-over-column — полосы строк отображаются поверх полос колонок🐬
column-over-row — полосы колонок отображаются поверх полос строк❗️За основу в примере был взят именно
grid контейнер, но, как вы уже знаете, данные свойства могут быть применены и к flex и к мультиколоночному тексту, в зависимости от чего некоторые свойства могут не работать или работать по-другому.❗️Помимо перечисленных свойств, есть ещё ряд других с точно таким же функционалом, которые в рамках поста я решил опустить
🔗 Ссылка на спецификацию
⚙️ Поддержка браузерами (column-rule-inset, row-rule-inset, column-rule-visibility-items, row-rule-visibility-items, column-rule-break, row-rule-break, rule-overlap)
❤1👍1
Новый HTTP-метод 🔥
На днях опубликовали стандарт RFC 10008, который добавляет новый HTTP-метод — QUERY.
Как вы знаете, для GET не предусмотрено тело запроса, а отправляемые параметры у него сильно ограничены объёмом (обычно 8-16 КБ).
Ранее, для того, чтобы обойти эту проблему, использовали POST, но он, по своей сути, не предназначен для этих целей и должен использоваться для отправки данных на сервер, а не для их получения. Из-за этого переставало работать кеширование и некоторый другой функционал, доступный именно GET запросам.
Собственно, проблему решили новым методом, который работает аналогично GET, но умеет отправлять тело запроса.
На данный момент стандарт уже вышел, но сетевая инфраструктура всего Интернета ещё не готова, поэтому до надёжного использования в своих проектах наверняка придётся подождать ещё несколько лет.
🔗 Ссылка на официальную документацию
На днях опубликовали стандарт RFC 10008, который добавляет новый HTTP-метод — QUERY.
Как вы знаете, для GET не предусмотрено тело запроса, а отправляемые параметры у него сильно ограничены объёмом (обычно 8-16 КБ).
Ранее, для того, чтобы обойти эту проблему, использовали POST, но он, по своей сути, не предназначен для этих целей и должен использоваться для отправки данных на сервер, а не для их получения. Из-за этого переставало работать кеширование и некоторый другой функционал, доступный именно GET запросам.
Собственно, проблему решили новым методом, который работает аналогично GET, но умеет отправлять тело запроса.
На данный момент стандарт уже вышел, но сетевая инфраструктура всего Интернета ещё не готова, поэтому до надёжного использования в своих проектах наверняка придётся подождать ещё несколько лет.
🔗 Ссылка на официальную документацию
🔥5😍4❤1
Забытые и неизведанные свойства
Внезапно узнал, что оказывается существует ряд
🍒
Возможные значения:
Значения из первой и второй группы можно использовать как самостоятельно, так и со значением из другой группы в любом порядке, например:
или
или
🍒
Возможные значения:
единицы измерения (px, %, rem, ...)
🍒
Возможные значения:
числа от 0 до 1 или проценты от 0% до 100%, где 0 означает, что форма будет выстроена по всем пикселям, кроме полностью прозрачных, а 1, что форма будет выстроена по всем пикселям, кроме частично прозрачных
⚙️ Поддержка браузерами широкая (shape-outside, shape-margin, shape-image-threshold)
Внезапно узнал, что оказывается существует ряд
shape-* свойств, которые позволяют управлять формой обтекания при float вёрстке.🍒
shape-outside — указывает тип формыВозможные значения:
inset() — прямоугольникcircle() — кругellipse() — овалpolygon() — любая другая форма, собранная по координатамurl() — путь к изображению (если оно полупрозрачное, то форма образуется по прозрачным областям)content-box — форма рассчитывается от контентной части padding-box — форма рассчитывается от padding области border-box — форма рассчитывается от border области margin-box — форма рассчитывается от margin областиЗначения из первой и второй группы можно использовать как самостоятельно, так и со значением из другой группы в любом порядке, например:
shape-outside: border-box;или
shape-outside: circle(50%) border-box;или
shape-outside: border-box circle(50%);🍒
shape-margin — указывает отступ от элемента до отрисованной формыВозможные значения:
единицы измерения (px, %, rem, ...)
🍒
shape-image-threshold — используется с полупрозрачными элементами и указывает от какой прозрачности пикселей будет выстраиваться формаВозможные значения:
числа от 0 до 1 или проценты от 0% до 100%, где 0 означает, что форма будет выстроена по всем пикселям, кроме полностью прозрачных, а 1, что форма будет выстроена по всем пикселям, кроме частично прозрачных
⚙️ Поддержка браузерами широкая (shape-outside, shape-margin, shape-image-threshold)
👍3