Год 2025 принёс фронтенд-разработчикам множество долгожданных новинок, которые делают веб-платформу более мощной и удобной. Вот краткий обзор ключевых возможностей, которые уже начинают поддерживаться в современных браузерах.

Promise.try()

Новый статический метод Promise.try() позволяет синхронно запускать функцию, которая возвращает промис, и сразу же обрабатывать любые синхронные ошибки как отклоненные промисы.

Это устраняет разрыв между синхронным и асинхронным кодом, делая обработку ошибок более последовательной и предсказуемой.

Promise.try(() => {
  if (Math.random() > 0.5) throw new Error('Синхронная ошибка');
  return fetch('/api/data');
}).catch(error => console.log('Перехвачено:', error));

Popover

Встроенная поддержка всплывающих окон через HTML-атрибут popover и JavaScript API.

Теперь для создания модальных окон, тултипов и выпадающих меню не нужны кастомные CSS и JavaScript для управления z-index'ом и фокусом.

<button popovertarget="my-popover">Открыть</button>
<div id="my-popover" popover>Содержимое попапа</div>

contenteditable="plaintext-only"

Улучшенная версия contenteditable, которая разрешает ввод только простого текста, без форматирования и HTML-разметки.

Идеально для создания текстовых редакторов, где нужно избежать вставки стилей или HTML-тегов из буфера обмена.

<div contenteditable="plaintext-only">
  Здесь можно вводить только текст
</div>

Intl.DurationFormat

Часть API интернационализации, которая форматирует длительности времени в удобочитаемый вид с учетом локали.

Позволяет единообразно отображать промежутки времени в разных языковых средах без ручного форматирования.

const df = new Intl.DurationFormat('ru', {
  style: 'long'
});
console.log(df.format({ hours: 2, minutes: 30 }));
// "2 часа 30 минут"

ClipboardItem.supports()

Этот метод позволяет проверить, поддерживает ли браузер работу с определенным MIME-типом при записи данных в буфер обмена.

Полезно для определения возможности копирования специализированных форматов данных перед выполнением операции.

if (ClipboardItem.supports('image/webp')) {
  // Можно безопасно копировать WebP изображения
  await navigator.clipboard.write([clipboardItem]);
}

Iterator methods

Массивы и другие коллекции получают новые методы для работы с итераторами, такие как array.values(), array.keys() и array.entries().

Унифицирует работу с различными типами коллекций и делает код более выразительным и последовательным.

const arr = ['a', 'b', 'c'];
for (const [index, value] of arr.entries()) {
  console.log(index, value); // 0 'a', 1 'b', 2 'c'
}

Screen Wake Lock

API, который предотвращает переход устройства в спящий режим или затемнение экрана.

Критически важно для приложений, где нужно постоянно отображать информацию: навигаторы, рецепты на кухне, презентации.

let wakeLock = null;
try {
  wakeLock = await navigator.wakeLock.request('screen');
} catch (err) {
  console.log('Wake Lock не поддерживается');
}

Atomics.pause()

Низкоуровневый метод для многопоточного программирования с Web Workers.

Atomics.pause() оптимизирует циклы ожидания в разделяемой памяти, экономя заряд батареи и снижая нагрузку на процессор.

// В Web Worker
while (Atomics.wait(sharedArray, 0, 0) === 'not-equal') {
  Atomics.pause(); // Эффективное ожидание
  // Выполнение работы
}

Float16Array

Новый типизированный массив для работы с 16-битными числами с плавающей запятой (половинной точностью).

Это особенно важно для машинного обучения и WebGPU, где такой формат данных широко используется для экономии памяти и повышения производительности.

const float16Array = new Float16Array([1.5, 2.3, 3.7]);
// Экономит память по сравнению с Float32Array
// Используется в ML-моделях и графических вычислениях

JSON import attributes

Теперь при импорте JSON-модулей можно явно указывать тип с помощью атрибутов.

Это делает намерения разработчика понятными для браузера и инструментов сборки, улучшая безопасность и предсказуемость.

import config from './config.json' with { type: 'json' };
import data from './data.json' assert { type: 'json' };

print-color-adjust

CSS-свойство, которое заменяет print-color-adjust: economy на print-color-adjust: exact.

Дает больше контроля над тем, как элементы будут выглядеть при печати, позволяя сохранить фоновые цвета и изображения.

.invoice {
  print-color-adjust: exact;
  background-color: #f0f0f0;
  /* Будет напечатано как есть */
}

RegExp.escape()

Статический метод RegExp.escape() экранирует специальные символы в строке для безопасного использования в регулярных выражениях.

Решает распространенную проблему, для которой раньше приходилось писать собственные функции экранирования.

const userInput = 'file.(txt)';
const safePattern = RegExp.escape(userInput);
const regex = new RegExp(safePattern);
// Ищет literal "file.(txt)" вместо групп

dialog.requestClose()

Метод для программного запроса на закрытие элемента <dialog>.

Позволяет унифицировать логику закрытия, например, при нажатии клавиши Esc или по кастомной кнопке "Отмена".

const dialog = document.querySelector('dialog');
dialog.addEventListener('close', (event) => {
  if (event.returnValue === 'cancel') {
    // Обработка отмены
  }
});

// Где-то в коде
dialog.requestClose({ returnValue: 'cancel' });

abs() и sign()

Новые CSS-математические функции. abs() возвращает абсолютное значение числа, а sign() — его знак (-1, 0 или 1).

Полезны для динамических расчетов в CSS, например, для условного применения стилей в зависимости от значения.

.element {
  margin-left: calc(var(--offset) * abs(var(--direction)));
  opacity: calc(sign(var(--visibility)) * 0.5 + 0.5);
}

Selection composed ranges

Расширение API Selection, которое позволяет работать с выделениями, пересекающими границы Shadow DOM.

Это открывает возможности для создания сложных Rich-текстовых редакторов, построенных на веб-компонентах.

const selection = document.getSelection();
const range = selection.getRangeAt(0);
const composedRange = range.getComposedRange();

// Работает с элементами через границы Shadow DOM
composedRange.setStart(shadowHost.shadowRoot, 0);

Uint8Array base64 и hex conversion

Типизированные массивы Uint8Array получают встроенные методы для конвертации в base64 и hex-строки и обратно.

Больше не нужны самописные функции для кодирования/декодирования бинарных данных.

const uint8 = new Uint8Array([72, 101, 108, 108, 111]);
const base64 = uint8.toBase64(); // "SGVsbG8="
const hex = uint8.toHex(); // "48656c6c6f"

const fromBase64 = Uint8Array.fromBase64("SGVsbG8=");

content-visibility

CSS-свойство для серьезной оптимизации производительности рендеринга длинных страниц.

Оно позволяет браузеру пропускать рендеринг элементов, находящихся вне viewport, до момента, когда пользователь приблизится к ним.

.long-list-item {
  content-visibility: auto;
  contain-intrinsic-size: 0 50px;
}
/* Браузер отложит рендеринг невидимых элементов */

<link rel="dns-prefetch">

Хотя этот rel-атрибут существовал и раньше, его стандартизация и повсеместная поддержка улучшают предварительное разрешение DNS-имен.

Ускоряет последующие загрузки ресурсов с внешних доменов за счет заблаговременного DNS-поиска.

<link rel="dns-prefetch" href="https://api.example.com">
<link rel="dns-prefetch" href="https://cdn.static-files.com">

Unsanitized HTML parsing methods

Новые методы для парсинга HTML без автоматического "санитарного" экранирования, такого как удаление скриптов.

Предназначены для узких use-cases, когда разработчик полностью контролирует источник HTML и берет ответственность за безопасность на себя.

const unsafeHtml = '<script>alert("XSS")</script><div>Content</div>';
const document = DOM.parseUnsanitizedHTML(unsafeHtml);
// Скрипт не будет удален - используйте с осторожностью!

URLPattern

API для создания шаблонов URL и их сопоставления.

Позволяет легко проверять, соответствует ли URL заданной маске, и извлекать из него параметры для клиентской маршрутизации.

const pattern = new URLPattern('/users/:id/:action?', baseURL);
const result = pattern.exec('https://example.com/users/123/edit');

if (result) {
  console.log(result.pathname.groups.id); // "123"
  console.log(result.pathname.groups.action); // "edit"
}

::details-content

Псевдоэлемент для стилизации внутреннего контента элемента <details>, не затрагивая сам маркер-треугольник.

Теперь можно гибко менять внешний вид раскрывающегося блока, оставляя стандартное поведение кнопки.

details::details-content {
  background: #f9f9f9;
  padding: 1rem;
  border-radius: 0 0 8px 8px;
  border: 1px solid #ddd;
}

WebRTC encoded transform

Мощное дополнение к WebRTC, которое позволяет перехватывать и программно обрабатывать закодированные аудио- и видеопотоки.

Это открывает двери для фильтров, шифрования, анализа трафика и других операций на уровне кодеков без перекодирования.

const transformer = new RTCRtpScriptTransform(context);
const sender = peerConnection.addTrack(track, stream);
sender.transform = transformer;

// В воркере можно модифицировать закодированные кадры
// перед отправкой по сети

view-transition-class

Дополнение к API View Transitions (переходам между состояниями VIEW).

Позволяет динамически назначать CSS-классы анимируемым элементам во время перехода, давая тонкий контроль над анимацией через CSS.

// JavaScript
document.startViewTransition(() => {
  updateTheDOMSomehow();
}, { classes: ['custom-animation', 'fast-transition'] });

/* CSS */
::view-transition-group(.custom-animation) {
  animation-duration: 0.3s;
}

Полезные статьи — по почте

Подпишитесь на редакторскую рассылку о фронтенде, новых CSS-штучках и всём, что пригодится разработчику.

Присылаем одно письмо в неделю. Без спама и нейросетей.


«Доктайп» — журнал о фронтенде. Читайте, слушайте и учитесь с нами.

ТелеграмПодкастБесплатные учебники