Веб-страница
22.2K subscribers
2.15K photos
559 videos
2 files
4.43K links
Всё по фронтенду, бэкенду и девопсу в одном месте

Разместить рекламу: @tproger_sales_bot

Правила общения: https://tprg.ru/rules

Другие каналы: @tproger_channels

Сайт: https://tprg.ru/site

Регистрация в перечне РКН: https://tprg.ru/64ai
Download Telegram
Как отменять устаревшие fetch-запросы в автодополнении

Быстрый ввод запускает несколько запросов. Если ранний ответ придёт позже нового, он перезапишет актуальную выдачу. AbortController убирает эту гонку: его signal передают в fetch, а перед следующим запросом вызывают abort() у предыдущего контроллера.

В React схему можно собрать в useEffect: поставить задержку на 250 мс, после паузы отправить запрос, а при очистке эффекта сбросить таймер и отменить запрос. Задержка сокращает число обращений, отмена не даёт запоздавшему ответу дойти до отрисовки. AbortError при этом обрабатывают отдельно от остальных ошибок.

Я сохранил себе ключевое ограничение: отменённый контроллер одноразовый, для следующего запроса нужен новый. Проверить весь сценарий можно на демо автодополнения с готовым кодом.
❤3
Как связать TanStack Router и Query для загрузки данных до рендера

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

Связка разделяет обязанности. loader вызывает ensureQueryData до рендера и заранее заполняет общий кэш TanStack Query. Компонент читает подготовленные данные через useSuspenseQuery. Маршрут определяет момент загрузки, Query хранит результат, а компонент занимается отображением.

Практическую схему интеграции Router и Query стоит открыть, когда один запрос обслуживает несколько экранов и загрузку нужно отделить от рендера.
👍2❤1👎1
В Safari Technology Preview 253 исправили повторное озвучивание текста

В Safari Technology Preview 253 исправили сбой: VoiceOver мог снова и снова произносить одно и то же содержимое live region, пока текст поступал на страницу. Такие области используют aria-live, чтобы скринридер сообщал об обновлениях без перевода фокуса, например в ответах веб-чата.

Исправление доступно только в тестовой сборке для macOS Golden Gate и macOS Tahoe. Переносить результат на стабильный Safari пока нельзя.

Если поддерживаете чат или другой интерфейс с потоковым текстом, сравните одну и ту же область aria-live в стабильном Safari и Technology Preview с VoiceOver. Так можно проверить, исчезли ли повторы и не потерялись ли новые фрагменты ответа.
❤1
Как собирать демо продукта на React вместо записи экрана

Remotion превращает видео в React-композицию: useCurrentFrame() задаёт текущий кадр, interpolate() меняет значения по ходу ролика, а Sequence размещает сцены на временной шкале. Результат рендерится в MP4 через Chrome без интерфейса и FFmpeg.

В разборе рабочего процесса с Remotion интерфейс пришлось отделить от состояния: компоненты получают данные через props, а действия пользователя заменяет сценарий с номерами кадров. Начальная настройка заняла около 85 минут, зато следующие ролики используют те же компоненты, тестовые данные и временную шкалу.

Такой подход пригодится для повторяемых обзоров функций и списков изменений: обновляете объект с данными, запускаете npx remotion render и получаете новый ролик без повторной записи кликов.
❤1👍1
Как не потерять языковые страницы из-за слеша в URL

Китайские страницы сайта исчезли из поиска, хотя канонические адреса указывали на них правильно. Причиной оказалось расхождение в одном символе: в canonical стоял завершающий слеш, а в sitemap его не было. Cloudflare дополнительно переписывал адреса, поэтому Google объединял китайскую страницу с английской. После синхронизации URL число ошибок в Search Console упало до нуля примерно за три дня. Весь разбор сбоя и исправления пригодится при запуске многоязычного сайта.

Перед релизом сравните canonical, перекрёстные ссылки hreflang и записи sitemap посимвольно: регистр, завершающий слеш и обработка параметров запроса должны совпадать. Затем проверьте правила нормализации URL в Cloudflare и плагинах, которые меняют атрибуты href. Такую сверку лучше добавить в сборку и останавливать её при первом расхождении.
❤1👍1
Next.js перестал обновлять серверный код для страниц, которые вы уже закрыли

В большом проекте изменение общего серверного модуля могло запускать обновления маршрутов, открытых раньше в этой сессии. В Next.js 16.4 Turbopack компилирует и применяет такие изменения, когда они понадобятся запросу. Текущая страница обновляется сразу, остальные ждут следующего обращения.

Для клиентских динамических импортов появился отдельный эксперимент: experimental.turbopackLazyDynamicImports: true. Код библиотеки, загружаемой через import() по нажатию кнопки, можно компилировать только при запросе из браузера. Это сокращает работу при старте разработки.

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

Картинка рядом с карточками меняет размер и положение вместе с контейнером. Фиксированный брейкпоинт не всегда попадёт в момент, когда между ними закончится место. Ахмад Шадид показал, как привязать скрытие к реальному расстоянию средствами CSS.

Через anchor positioning он растягивает вспомогательный элемент между краями декора и секции. Внутри лежит псевдоэлемент шириной 20 px: когда зазор становится меньше, появляется переполнение. Scroll timeline переключает CSS-переменную, а style container query убирает декор. Пользователю ничего прокручивать не нужно.

Приём требует поддержки anchor positioning, scroll-driven animations и запросов к стилям контейнера. Для проекта я бы оставил безопасную базовую вёрстку, а такое поведение добавил как улучшение.
👍2❤1
Как измерить медленный переход внутри SPA в Chrome DevTools

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

В сентябрьском обновлении Chrome анализ soft navigation появился в Insights панели Performance. Теперь такие переходы можно разбирать вместе с уже доступными метриками и временной шкалой. Запишите переход от клика до нового экрана и посмотрите, какие задачи и загрузки приходятся на этот участок.

Для повторяемых замеров через Chrome DevTools Protocol добавили калиброванные уровни производительности CPU. Это пригодится при автоматизации: один и тот же сценарий можно сравнивать с одинаковыми настройками процессора, не ограничиваясь результатом на рабочем ноутбуке.
❤2
В React 19.3 можно анимировать смену содержимого через ViewTransition

Компонент <ViewTransition> связывает обновления React с браузерными переходами. Оберните меняющийся участок интерфейса и обновите состояние внутри startTransition: по умолчанию старое содержимое плавно сменится новым. Анимации можно настроить через CSS или Web Animations API.

Обычные срочные обновления состояния переход не запускают. Анимация срабатывает для startTransition, раскрытия Suspense и обновлений через useDeferredValue. Сейчас компонент работает с DOM.

Для загрузки данных в разборе React 19.3 есть полезная настройка: <ViewTransition update="auto" default="none">. Она позволяет анимировать смену заглушки на готовое содержимое, сохраняя мгновенное появление самой заглушки и уже закешированного интерфейса.
🔥4👍2👎1
iframe научился подстраивать высоту под встроенную страницу

Форма внутри iframe переходит на следующий шаг, становится выше и получает собственную полосу прокрутки. В Chrome 154 для этого появился `frame-sizing`: например, content-height позволяет подбирать высоту по содержимому встроенного документа.

Одного CSS у родителя недостаточно. Страница внутри iframe должна разрешить передачу размера через <meta name="responsive-embedded-sizing" content="allow-origins=*">. Вместо звёздочки можно ограничить список разрешённых источников. После изменения содержимого новый размер передают вызовом window.requestResize().

В Firefox и Safari поддержки пока нет. Приём подойдёт как улучшение для встраиваемых форм и виджетов, где вы контролируете обе стороны и можете сохранить запасной вариант изменения высоты.
🔥2
Мы тут балуемся немножко. Присоединяйтесь
❤1
Forwarded from Типичный программист
Давайте сыграем в айтишную каламбурю!

Правила простые: берём любой термин, название компании или имя известного айтишника и делаем из него каламбур.

Я начинаю — вы подхватываете: Ада Лавпринглс
😁2
Как убрать dist из опубликованного npm-пакета

Папка dist удобна для сборки, но её название может попасть в публичные пути, особенно при загрузке файлов через CDN. Команда npm publish ./dist позволяет опубликовать содержимое этой папки как корень пакета.

Перед этим в dist нужно положить package.json, README и лицензию. Пути в копии package.json тоже меняются: ./dist/index.js становится ./index.js. Иначе пакет будет искать файлы в несуществующей вложенной папке.

В разборе публикации из подпапки автор автоматизирует подготовку после сборки и отдельно защищается от привычной команды npm publish, которая опубликует корень проекта. Перед первым релизом состав пакета можно проверить через npm publish ./dist --dry-run и npm pack ./dist.
🔥3
От чатбота к агентам: опыт Митчелла Хашимото

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

Так он выяснял, какие задачи можно поручать ИИ. Дальше добавлял инструкции в AGENTS.md, файл с правилами проекта, и способы проверить изменения, включая запуск тестов.

В истории освоения ИИ в разработке Хашимото связывает выбор задач с настройкой рабочего окружения. Отдельные чаты при этом остались в его повседневной работе.

#ии #инструменты
❤1
Как добавить в поиск фильтры вида author: и year:

В поиске GitHub обычный текст соседствует с фильтрами ключ:значение. Веб-компонент `<rich-input>` переносит этот шаблон на свой сайт: подсказывает названия фильтров и допустимые значения, подсвечивает структуру запроса и отмечает неверный ввод.

Настройки задаются через вложенные <datalist>. Компонент участвует в обычной отправке формы и работает с FormData, поэтому поле можно встроить в существующий интерфейс без привязки к конкретному фреймворку.

В Chromium 152+ подсветка и расположение подсказок используют OpaqueRange внутри нативного input. Для других браузеров автор предусмотрел вариант с contenteditable. Заявленная поддержка начинается с Chromium 105, Safari 17.2 и Firefox 140; ввод, выделение и отправку формы стоит проверить в целевых браузерах.
❤2👍1
Диаграмму Mermaid можно положить прямо в HTML

Для схемы запросов или графа зависимостей часто хватает нескольких строк Mermaid. Компонент `<mermaid-element>` позволяет поместить этот текст в HTML: подключаете модуль, добавляете тег и записываете внутри описание диаграммы.

По умолчанию компонент загружает Mermaid через jsDelivr по требованию и рисует схему в Shadow DOM. Несколько диаграмм на странице используют одну загрузку библиотеки. Через атрибут mermaid можно закрепить версию или указать собственный адрес.

Если Mermaid уже входит в сборку приложения, свою копию можно передать через MermaidElement.defaultMermaid. Тогда дополнительный запрос к CDN не понадобится. В статье есть песочница, где можно собрать пример и сразу скопировать получившийся HTML.
🔥4
Почему сотни маленьких JS-чанков тоже могут замедлять сайт

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

Команда Next.js разобрала, как Turbopack выбирает между этими расходами. Он учитывает группы чанков, которые загружаются вместе, и оценивает объединение с учётом переходов между страницами и повторного использования кода из кеша.

Разбор полезен, когда вкладка Network заполнена файлами и хочется «просто уменьшить их количество». Сначала посмотрите, какой код нужен первому экрану, что переиспользуется на соседних маршрутах и сколько посетитель скачивает за весь сценарий.
🔥1
Почему мобильная клавиатура прячет панель с position: fixed

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

Директива interactive-widget=resizes-content в viewport meta позволяет уменьшать обе области. Пример: <meta name="viewport" content="width=device-width, initial-scale=1.0, interactive-widget=resizes-content">. В разборе viewport и interactive-widget показано, как это меняет положение фиксированных элементов.

Поддержка есть в Chrome и Firefox на Android. В сентябрьском разборе автор проверил реализацию в WebKit, но она ещё не была доступна в публичном Safari. Форму с нижней панелью всё равно нужно проверить на iPhone и предусмотреть поведение для браузеров без этой настройки.
🔥4
Shopify начал отправлять HTML до завершения рендеринга страницы

Раньше браузер ждал, пока сервер соберёт и head, и остальные секции шаблона. Теперь подходящие Liquid-страницы отправляют начало документа сразу: браузер уже ищет стили и шрифты, пока сервер продолжает готовить содержимое.

У медианного магазина TTFB на 75-м перцентиле снизился примерно на 29%. Видимые метрики FCP и LCP улучшились скромнее: на 2–6%. Ранний первый байт помогает начать работу, но эффект зависит от того, какие ресурсы попали в первую часть ответа.

В разборе Shopify сравнивают темы Dawn и Horizon и показывают ограничения стриминга. Для своей темы стоит проверить расположение stylesheet и preload относительно content_for_header: если ссылки придут во второй части HTML, браузер начнёт скачивание позже.
🔥2