Перейти к основному содержимому
Технологии

Что на самом деле поставляет Chrome 148 и почему это меняет то, как мы строим

8 минunemployment.team
ChromeCSSПроизводительностьИИ
Что на самом деле поставляет Chrome 148 и почему это меняет то, как мы строим

Что на самом деле поставляет Chrome 148 и почему это меняет то, как мы строим

Каждый цикл выпуска браузера приносит список функций, которые располагаются в диапазоне от «интересного эксперимента» до «меняет то, как мы пишем продакшен-код уже завтра». Chrome 148 beta ближе к последнему концу спектра, чем большинство релизов. Запросы контейнеров получают значимое расширение, медиа-элементы обзаводятся нативной отложенной загрузкой, а Prompt API открывает дверь к ИИ на устройстве, которому не требуется круговая передача данных на удалённую модель. Мы внимательно отслеживали эти изменения, потому что несколько из них напрямую влияют на то, как мы проектируем CSS и работаем с бюджетами производительности в клиентских проектах.

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


Запросы контейнеров только по имени

Запросы контейнеров стали одним из самых значимых дополнений CSS за последние годы. Возможность стилизовать компонент в зависимости от размера его контейнера, а не от вьюпорта, наконец-то позволила создавать по-настоящему переиспользуемые библиотеки компонентов без хаков на JavaScript.

Chrome 148 расширяет эту возможность запросами контейнеров только по имени: теперь можно запрашивать именованный контейнер, не указывая его тип. Раньше нужно было объявлять и имя, и тип:

/* До - тип обязателен */
.card-wrapper {
  container-name: card;
  container-type: inline-size;
}

@container card (min-width: 400px) {
  .card-title {
    font-size: 1.5rem;
  }
}

С контейнерами только по имени объявление container-type становится необязательным, если запрос идёт исключительно по имени:

/* Chrome 148+ - только по имени */
.card-wrapper {
  container-name: card;
}

@container card style(--variant: featured) {
  .card-title {
    font-weight: 700;
    color: var(--color-accent);
  }
}

Особенно полезно это в сочетании со style-запросами - запросами значений CSS-переменных контейнера, а не его размеров. Комбинация позволяет передавать состояние вниз по каскаду CSS вообще без JavaScript. Родитель устанавливает --variant: featured на контейнере, и каждый дочерний компонент внутри него может реагировать на этот сигнал.

Почему это важно для архитектуры компонентов

На практике эта функция снижает трение при создании компонентов дизайн-системы, которым нужно адаптироваться к редакторскому контексту. Представьте карточку, которая ведёт себя по-разному внутри герой-секции и в сайдбаре. Раньше пришлось бы использовать модификатор-класс или пропсу через JavaScript. Теперь всю эту связь можно выразить исключительно в CSS - компонентная логика остаётся легче, а разметка чище.

Мы ждали стабилизации этой возможности, прежде чем рекомендовать её для продакшен-библиотек компонентов. С Chrome 148 её уже стоит использовать в разработке, особенно командам, которые активно применяют запросы контейнеров в своих дизайн-системах.


Отложенная загрузка для элементов video и audio

Атрибут loading="lazy" уже давно доступен для изображений и iframe. Chrome 148 расширяет это поведение на элементы <video> и <audio>.

<!-- Отложенная загрузка до момента приближения к вьюпорту -->
<video src="/assets/demo.mp4" loading="lazy" controls></video>
<audio src="/assets/podcast.mp3" loading="lazy" controls></audio>

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

Что меняется на практике

До появления этой возможности типичный паттерн отложенной загрузки видео выглядел так:

const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      const video = entry.target;
      video.src = video.dataset.src;
      observer.unobserve(video);
    }
  });
});

document.querySelectorAll('video[data-src]').forEach((el) => {
  observer.observe(el);
});

Кода немного, но его нужно поддерживать, тестировать и поставлять. Нативный атрибут полностью избавляет от этого. Кроме того, браузер теперь может применять собственные эвристики момента начала загрузки - они, скорее всего, лучше настроены, чем любой обобщённый порог в пользовательском JavaScript.

Одно важное замечание: loading="lazy" для видео не влияет на поведение автозапуска и атрибут preload. Если вы хотите полностью предотвратить любую сетевую активность до взаимодействия пользователя, явно указывайте preload="none":

<video
  src="/assets/demo.mp4"
  loading="lazy"
  preload="none"
  controls
></video>

Для клиентов, у которых Core Web Vitals - это реальный бизнес-фактор, а так бывает почти всегда, это изменение с минимальными усилиями и максимальной отдачей. Именно такие детали мы проверяем во время аудитов производительности существующих проектов, где несколько неоптимизированных медиа-элементов могут незаметно тянуть вниз показатели LCP.


Ключевое слово CSS revert-rule

Chrome 148 также поставляет revert-rule - новое ключевое слово CSS, которое позволяет избирательно отменить вклад конкретного правила в свойство, не откатывая весь каскад целиком.

.button {
  background-color: var(--color-primary);
  color: white;
  padding: 0.5rem 1rem;
}

.button--ghost {
  background-color: revert-rule;
  border: 2px solid var(--color-primary);
  color: var(--color-primary);
}

В примере выше revert-rule для background-color внутри .button--ghost откатывает только правило, заданное селектором .button, и возвращается к тому значению, которое каскад вычислил бы без этого конкретного правила, а не к браузерному умолчанию и не к initial. Это важное различие.

Когда это действительно нужно

Самый практичный сценарий - условные переопределения в вариантах компонентов, когда нужно «отменить» базовый стиль, не зная, что было до него в каскаде. Особенно полезно в многослойных архитектурах CSS с использованием @layer, где взаимодействие слоёв делает unset или initial слишком грубыми инструментами.

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


Prompt API: ИИ на устройстве без круговой передачи данных

Самое перспективное дополнение в Chrome 148 - Prompt API, доступное в рамках origin trial. Оно предоставляет прямой доступ к языковой модели на устройстве, на данный момент Gemini Nano, прямо из JavaScript без единого сетевого запроса.

// Проверяем доступность перед использованием
const availability = await ai.languageModel.availability();

if (availability !== "unavailable") {
  const session = await ai.languageModel.create({
    temperature: 0.7,
    topK: 40,
  });

  const result = await session.prompt(
    "Summarize this in one sentence: " + articleText
  );

  console.log(result);
}

API включает параметры сэмплирования - temperature и topK, - которые дают реальное влияние на поведение вывода. Более высокие значения temperature дают более разнообразные ответы; более низкие делают модель более детерминированной. Это та же терминология, что и в любом хостинговом LLM API, поэтому ментальная модель легко переносится.

Что это открывает

Практические последствия значительны для определённых сценариев:

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

Важное ограничение на текущий момент - аппаратное обеспечение: Gemini Nano требует достаточно мощного устройства, и проверка availability() обязательна перед созданием сессии. Graceful degradation здесь не опция; это базовое требование.

Пока это origin trial, то есть API ещё не стабилен. Мы бы не выкатывали его в продакшен без надёжного пути отката. Но уже сейчас стоит собирать прототипы, потому что паттерн, состоящий из проверки доступности, создания сессии и промпта с параметрами сэмплирования, скорее всего останется стабильным, даже если названия методов немного изменятся.


Обновления WebGPU и подключение последовательных устройств

Два дополнительных изменения, которые стоит отметить:

WebGPU получает новые возможности в Chrome 148, которые расширяют границы GPU-ускоренных вычислений в браузере. Для большинства веб-приложений это остаётся специализированной областью, но для команд, которые разрабатывают инструменты визуализации данных, среды креативного кодирования или пайплайны ML-инференса в браузере, расширение поверхности WebGPU заслуживает внимания.

Улучшения подключения последовательных устройств упрощают обмен данными с аппаратными устройствами через последовательные порты прямо из браузера. Это нишевая, но актуальная тема для команд, создающих браузерные интерфейсы для IoT-устройств, промышленного оборудования или maker-хардвера, - область, где Web Serial API уже давно тихо развивается.


Chrome Web Store: более удобные апелляции для разработчиков расширений

Отдельно от самого браузера Chrome Web Store внедрил улучшенный процесс апелляций для разработчиков расширений. Теперь апелляции можно инициировать прямо из Developer Dashboard: идентификаторы расширений, детали нарушения и контактная информация подставляются автоматически.

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

Если ваша команда поддерживает расширения Chrome - для внутренних инструментов, клиентских продуктов или утилит для разработчиков, - это заметное улучшение качества жизни. Единственное исключение: апелляции по верификации продавца по-прежнему идут через форму One Stop Support.


Ключевые выводы

Краткий обзор того, что поставляет Chrome 148 и как это приоритизировать:

  • Запросы контейнеров только по имени - готовы к продакшену для команд, которые уже активно используют запросы контейнеров. Комбинируйте со style-запросами, чтобы передавать состояние через CSS без JavaScript.
  • loading="lazy" для video и audio - внедряйте сразу на любых страницах с несколькими медиа-элементами. Добавляйте preload="none" для максимального эффекта. Минимальные усилия, измеримый прирост производительности.
  • Ключевое слово revert-rule - полезно в многослойных CSS-архитектурах. Стоит внедрять, если вы используете @layer и вам нужен точечный контроль над каскадом.
  • Prompt API - только origin trial. Собирайте прототипы, реализуйте graceful degradation, не выкатывайте в продакшен без fallback. Преимущества приватности и низкой задержки реальны там, где позволяет железо.
  • WebGPU и Web Serial - отслеживайте, если это касается вашей области. Для большинства веб-приложений сегодня это не общие задачи.

Общая тенденция здесь заслуживает внимания: платформа последовательно движется в сторону функций, которые уменьшают необходимость в JavaScript для того, что CSS и браузер могут делать нативно. Отложенная загрузка, запросы контейнеров, ключевые слова каскада - всё это случаи, когда платформа догоняет паттерны, которые раньше требовали пользовательского кода. Это хорошее направление, и мы стараемся опережать его при принятии архитектурных решений в новых проектах.

Если вы проводите аудит производительности, рефакторинг CSS-архитектуры или решаете, внедрять ли какую-то из этих функций в существующую кодовую базу, наша команда с удовольствием обсудит компромиссы. Именно такие решения выигрывают от второго мнения, прежде чем они будут зашиты в продакшен-систему.

VK