Как отменять устаревшие fetch-запросы в автодополнении
Быстрый ввод запускает несколько запросов. Если ранний ответ придёт позже нового, он перезапишет актуальную выдачу. AbortController убирает эту гонку: его
В React схему можно собрать в
Я сохранил себе ключевое ограничение: отменённый контроллер одноразовый, для следующего запроса нужен новый. Проверить весь сценарий можно на демо автодополнения с готовым кодом.
Быстрый ввод запускает несколько запросов. Если ранний ответ придёт позже нового, он перезапишет актуальную выдачу. AbortController убирает эту гонку: его
signal передают в fetch, а перед следующим запросом вызывают abort() у предыдущего контроллера.В React схему можно собрать в
useEffect: поставить задержку на 250 мс, после паузы отправить запрос, а при очистке эффекта сбросить таймер и отменить запрос. Задержка сокращает число обращений, отмена не даёт запоздавшему ответу дойти до отрисовки. AbortError при этом обрабатывают отдельно от остальных ошибок.Я сохранил себе ключевое ограничение: отменённый контроллер одноразовый, для следующего запроса нужен новый. Проверить весь сценарий можно на демо автодополнения с готовым кодом.
❤3
Как связать TanStack Router и Query для загрузки данных до рендера
Если одни и те же данные нужны на нескольких маршрутах React-приложения, кэша отдельного маршрута может быть недостаточно: загрузка остаётся привязана к странице, а результат сложнее переиспользовать.
Связка разделяет обязанности.
Практическую схему интеграции 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, пока текст поступал на страницу. Такие области используют
Исправление доступно только в тестовой сборке для macOS Golden Gate и macOS Tahoe. Переносить результат на стабильный Safari пока нельзя.
Если поддерживаете чат или другой интерфейс с потоковым текстом, сравните одну и ту же область
В 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-композицию:
В разборе рабочего процесса с Remotion интерфейс пришлось отделить от состояния: компоненты получают данные через props, а действия пользователя заменяет сценарий с номерами кадров. Начальная настройка заняла около 85 минут, зато следующие ролики используют те же компоненты, тестовые данные и временную шкалу.
Такой подход пригодится для повторяемых обзоров функций и списков изменений: обновляете объект с данными, запускаете
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. Такую сверку лучше добавить в сборку и останавливать её при первом расхождении.
Китайские страницы сайта исчезли из поиска, хотя канонические адреса указывали на них правильно. Причиной оказалось расхождение в одном символе: в canonical стоял завершающий слеш, а в sitemap его не было. Cloudflare дополнительно переписывал адреса, поэтому Google объединял китайскую страницу с английской. После синхронизации URL число ошибок в Search Console упало до нуля примерно за три дня. Весь разбор сбоя и исправления пригодится при запуске многоязычного сайта.
Перед релизом сравните canonical, перекрёстные ссылки hreflang и записи sitemap посимвольно: регистр, завершающий слеш и обработка параметров запроса должны совпадать. Затем проверьте правила нормализации URL в Cloudflare и плагинах, которые меняют атрибуты href. Такую сверку лучше добавить в сборку и останавливать её при первом расхождении.
❤1👍1
Next.js перестал обновлять серверный код для страниц, которые вы уже закрыли
В большом проекте изменение общего серверного модуля могло запускать обновления маршрутов, открытых раньше в этой сессии. В Next.js 16.4 Turbopack компилирует и применяет такие изменения, когда они понадобятся запросу. Текущая страница обновляется сразу, остальные ждут следующего обращения.
Для клиентских динамических импортов появился отдельный эксперимент:
Начать стоит с сравнения запуска dev-сервера и первого открытия тяжёлого экрана. Часть работы переносится на момент обращения к коду, поэтому быстрый старт нужно оценивать вместе с задержкой первого использования.
В большом проекте изменение общего серверного модуля могло запускать обновления маршрутов, открытых раньше в этой сессии. В 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 и запросов к стилям контейнера. Для проекта я бы оставил безопасную базовую вёрстку, а такое поведение добавил как улучшение.
Картинка рядом с карточками меняет размер и положение вместе с контейнером. Фиксированный брейкпоинт не всегда попадёт в момент, когда между ними закончится место. Ахмад Шадид показал, как привязать скрытие к реальному расстоянию средствами 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. Это пригодится при автоматизации: один и тот же сценарий можно сравнивать с одинаковыми настройками процессора, не ограничиваясь результатом на рабочем ноутбуке.
Первый экран может загружаться быстро, а переход в каталог зависать на секунды. При клиентской навигации документ не перезагружается, поэтому запись одного холодного старта не покажет весь сценарий.
В сентябрьском обновлении Chrome анализ soft navigation появился в Insights панели Performance. Теперь такие переходы можно разбирать вместе с уже доступными метриками и временной шкалой. Запишите переход от клика до нового экрана и посмотрите, какие задачи и загрузки приходятся на этот участок.
Для повторяемых замеров через Chrome DevTools Protocol добавили калиброванные уровни производительности CPU. Это пригодится при автоматизации: один и тот же сценарий можно сравнивать с одинаковыми настройками процессора, не ограничиваясь результатом на рабочем ноутбуке.
❤2
В React 19.3 можно анимировать смену содержимого через ViewTransition
Компонент
Обычные срочные обновления состояния переход не запускают. Анимация срабатывает для
Для загрузки данных в разборе React 19.3 есть полезная настройка:
Компонент
<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`: например,
Одного CSS у родителя недостаточно. Страница внутри iframe должна разрешить передачу размера через
В Firefox и Safari поддержки пока нет. Приём подойдёт как улучшение для встраиваемых форм и виджетов, где вы контролируете обе стороны и можете сохранить запасной вариант изменения высоты.
Форма внутри iframe переходит на следующий шаг, становится выше и получает собственную полосу прокрутки. В Chrome 154 для этого появился `frame-sizing`: например,
content-height позволяет подбирать высоту по содержимому встроенного документа.Одного CSS у родителя недостаточно. Страница внутри iframe должна разрешить передачу размера через
<meta name="responsive-embedded-sizing" content="allow-origins=*">. Вместо звёздочки можно ограничить список разрешённых источников. После изменения содержимого новый размер передают вызовом window.requestResize().В Firefox и Safari поддержки пока нет. Приём подойдёт как улучшение для встраиваемых форм и виджетов, где вы контролируете обе стороны и можете сохранить запасной вариант изменения высоты.
🔥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
Forwarded from Инструменты программиста
От чатбота к агентам: опыт Митчелла Хашимото
Для работы с кодом Хашимото перешёл от отдельного чата к агенту, который читает файлы проекта и запускает программы. После этого начал повторять собственную работу: сначала решал задачу сам, затем давал её агенту без готового решения.
Так он выяснял, какие задачи можно поручать ИИ. Дальше добавлял инструкции в AGENTS.md, файл с правилами проекта, и способы проверить изменения, включая запуск тестов.
В истории освоения ИИ в разработке Хашимото связывает выбор задач с настройкой рабочего окружения. Отдельные чаты при этом остались в его повседневной работе.
#ии #инструменты
Для работы с кодом Хашимото перешёл от отдельного чата к агенту, который читает файлы проекта и запускает программы. После этого начал повторять собственную работу: сначала решал задачу сам, затем давал её агенту без готового решения.
Так он выяснял, какие задачи можно поручать ИИ. Дальше добавлял инструкции в AGENTS.md, файл с правилами проекта, и способы проверить изменения, включая запуск тестов.
В истории освоения ИИ в разработке Хашимото связывает выбор задач с настройкой рабочего окружения. Отдельные чаты при этом остались в его повседневной работе.
#ии #инструменты
❤1
Forwarded from Инструменты программиста
Где вы чаще всего работаете с ИИ-инструментом?
Anonymous Poll
33%
В отдельном окне чата или веб-версии
21%
Прямо в редакторе кода
26%
В терминале
2%
Через корпоративные сервисы или платформы
18%
По-разному, зависит от того, что нужно сделать
🤔1
Как добавить в поиск фильтры вида author: и year:
В поиске GitHub обычный текст соседствует с фильтрами
Настройки задаются через вложенные
В Chromium 152+ подсветка и расположение подсказок используют OpaqueRange внутри нативного input. Для других браузеров автор предусмотрел вариант с
В поиске 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. Компонент `<mermaid-element>` позволяет поместить этот текст в HTML: подключаете модуль, добавляете тег и записываете внутри описание диаграммы.
По умолчанию компонент загружает Mermaid через jsDelivr по требованию и рисует схему в Shadow DOM. Несколько диаграмм на странице используют одну загрузку библиотеки. Через атрибут
mermaid можно закрепить версию или указать собственный адрес.Если Mermaid уже входит в сборку приложения, свою копию можно передать через
MermaidElement.defaultMermaid. Тогда дополнительный запрос к CDN не понадобится. В статье есть песочница, где можно собрать пример и сразу скопировать получившийся HTML.🔥4
Почему сотни маленьких JS-чанков тоже могут замедлять сайт
Один большой бандл заставляет каждую страницу скачивать код всего приложения. Отдельный бандл на маршрут дублирует общие компоненты. Если же разнести каждый модуль в свой файл, браузер получит сотни запросов, а сжатие будет хуже находить повторяющиеся фрагменты.
Команда Next.js разобрала, как Turbopack выбирает между этими расходами. Он учитывает группы чанков, которые загружаются вместе, и оценивает объединение с учётом переходов между страницами и повторного использования кода из кеша.
Разбор полезен, когда вкладка Network заполнена файлами и хочется «просто уменьшить их количество». Сначала посмотрите, какой код нужен первому экрану, что переиспользуется на соседних маршрутах и сколько посетитель скачивает за весь сценарий.
Один большой бандл заставляет каждую страницу скачивать код всего приложения. Отдельный бандл на маршрут дублирует общие компоненты. Если же разнести каждый модуль в свой файл, браузер получит сотни запросов, а сжатие будет хуже находить повторяющиеся фрагменты.
Команда Next.js разобрала, как Turbopack выбирает между этими расходами. Он учитывает группы чанков, которые загружаются вместе, и оценивает объединение с учётом переходов между страницами и повторного использования кода из кеша.
Разбор полезен, когда вкладка Network заполнена файлами и хочется «просто уменьшить их количество». Сначала посмотрите, какой код нужен первому экрану, что переиспользуется на соседних маршрутах и сколько посетитель скачивает за весь сценарий.
🔥1
Почему мобильная клавиатура прячет панель с position: fixed
Когда открывается клавиатура, браузер может уменьшить только видимую область страницы. Область, относительно которой рассчитывается вёрстка, остаётся прежней, и закреплённая снизу панель оказывается под клавиатурой.
Директива
Поддержка есть в Chrome и Firefox на Android. В сентябрьском разборе автор проверил реализацию в WebKit, но она ещё не была доступна в публичном Safari. Форму с нижней панелью всё равно нужно проверить на iPhone и предусмотреть поведение для браузеров без этой настройки.
Когда открывается клавиатура, браузер может уменьшить только видимую область страницы. Область, относительно которой рассчитывается вёрстка, остаётся прежней, и закреплённая снизу панель оказывается под клавиатурой.
Директива
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 относительно
Раньше браузер ждал, пока сервер соберёт и head, и остальные секции шаблона. Теперь подходящие Liquid-страницы отправляют начало документа сразу: браузер уже ищет стили и шрифты, пока сервер продолжает готовить содержимое.
У медианного магазина TTFB на 75-м перцентиле снизился примерно на 29%. Видимые метрики FCP и LCP улучшились скромнее: на 2–6%. Ранний первый байт помогает начать работу, но эффект зависит от того, какие ресурсы попали в первую часть ответа.
В разборе Shopify сравнивают темы Dawn и Horizon и показывают ограничения стриминга. Для своей темы стоит проверить расположение stylesheet и preload относительно
content_for_header: если ссылки придут во второй части HTML, браузер начнёт скачивание позже.🔥2