Всем хабровчанам удачной недели!
Хотел поинтересоваться такой темой как школа «Result/University». Кто обучался, как быстро удалось найти работу? Какова оценка по 5 шкале?
Смогут ли ребята ввести в данную тему с минимальными рисками?

Прототипно-ориентированный язык программирования
Solid.js должен был исправить React…но доказал, что React был прав
Все ругали React за массивы зависимостей, странные хуки и непонятные стадии рендеринга. Возникало чувство, что они усложнили фронтенд и добавили в него отложенную реакцию. Команда Solid.js решила это исправить: убрать лишние рендеры и магию по капоту. Идея была проста — использовать реактивность. Solid создавался, чтобы заменить React, но когда они работали над второй версией, тут они уперлись в проблему, которую невозможно решить — ассинхронность.
Представьте: одни данные загрузились, другие ещё нет. Что покажет интерфейс? Фейковый фронтенд, который обманывает пользователя. React решал это с помощью отложенного обновления. Тогда Solid решили встроить ассинхронность прямо в реактивность. Появилось управление загрузкой, ожиданием и обновлениями — реактивность как она есть. Становится понятно, что и та, и та команда приходят к одному выводу с разных сторон, но Solid делает ее частью системы, засовывает ассинхронность прямо в реактивность и внезапно оказывается, что React не был таким уж и плохим дизайном, просто команда React-а пришла к этой проблеме гораздо раньше, чем остальные.
И главный вопрос: что важнее — устоявшийся подход React или более чистая, но сложная реактивность Solid? Или дело вовсе не в фреймворке, а в том, как ты управляешь асинхронностью?
https://dev.to/playfulprogramming/two-react-design-choices-developers-dont-like-but-cant-avoid-d6g
Представлен открытый мультиплатформенный проект Snowify. Это аналог Spotify в виде музыкального плеера с кодом на JavaScript без рекламы и без регистрации. Музыка стримится с YouTube Music. Все функции Spotify на месте: списки треков, текст песен, плейлисты с рекомендациями и даже синхронизация с облаком. При этом в интерфейсе нет ничего лишнего, что отвлекало бы от музыки. Проект поддерживает кастомные плагины.

Расширение AI-Less Habr — Чистим Хабр от ИИ
Надоела лента, забитая ИИ? У меня есть готовое решение для вас. Shut up and take my money:

Расширение для Chrome (и совместимых браузеров) позволяет скрывать статьи про «Искусственный интеллект». Скрывается не контент, написанный ИИ (LLM), а контент про ИИ (что сейчас обычно под этим подразумевается). Бесконечные статьи об очередной революции, вызванной тем, что такая‑то LLM модель опередила конкурентов на 0.1 балл в одном из 186 имеющихся бенчмарков, и вот этот вот всё.
Чтобы видеть счетчик скрытых статей, закрепите иконку расширения на панели инструментов через меню расширений (иконка паззла).
Есть следующие возможности:
скрывать хаб «Искусственный интеллект»
скрывать по словам в заголовке (настраиваемый список)
скрывать по тегам (настраиваемый список)
инвертированный режим (показать, попадающее под фильтры, и скрыть остальное)
По умолчанию включено только скрытие хаба «Искусственный интеллект». Фильтры по словам/тегам с большей вероятностью допускают ложноположительные срабатывания, поэтому выключены по умолчанию. По этой же причине в фильтрах по словам по умолчанию нет слов «ии»/«ai», так как есть достаточно много статей, содержащих что‑то вроде «без ИИ». Внимательно относитесь к добавлению слов в фильтры, чтобы минимизировать ложноположительные срабатывания.
Сделал интерактивный квиз!

Смотрите пробуйте играйте, формируйте своё мнение, и всегда помните — хост — это не игрок, он не может выбирать ответы, но вы можете запустить игру с пк, и зайти с телефона. Или с одного пк на разных браузерах.
Делал долго, мой магнум опус.

Собрал форк Backbone.js без jQuery, Underscore.
Typescript, ES module, поддержка классов
https://ostovjs.org/
https://github.com/DmitryOlkhovoi/Ostov

Гибкое управление фокусом элемента
Chrome в 145 версии добавил параметр focusVisible в метод focus:
input.focus({ focusVisible: true });
Как вы уже, наверное, догадываетесь, это позволяет самостоятельно управлять тем, будет ли элемент при ручном вызове фокуса, помимо CSS-псевдокласса :focus, соответствовать ещё и :focus-visible.
Ранее без данного параметра браузер самостоятельно решал этот вопрос.
⚙️ Поддержка браузерами широкая
🔗 Мой телеграм канал
Как я оптимизировала фронт на 40% и никто не заметил

Предыстория
Когда я помогала с поиском сотрудника и просматривала резюме на фронтенд разработчика, очень часто встречала фразу - "Оптимизировал(а) размер бандла на 30% / 40% / 50%, что увеличило ..." как под копирку от ИИ, а у меня из достижений в резюме - "делаю задачи и фикшу баги"
Ну что ж, возьмем свое приложение и оптимизируем его
О приложении
Это небольшое SPA на Vue 3 для администрирования справочников. Ничего особенного, но это приложение экономит время программистам, которые не лезут в БД, и, как мне кажется, полезно для аналитиков и QA - это позволяет лучше понять, как устроена база, и почему иногда что-то не работает как ожидается.
Начнем оптимизацию
Запускаем npx vite-bundle-visualizer и получаем вот такую красивую розовую визуализацию (прикрепила бы скрин, на то что получилось, но в пост можно одну картинку добавить)
Смотрим роутинг у приложения... Все роуты импортируются сразу. Применяем легкий фикс:
Оставляем синхронный импорт только для страниц, которые первыми открываются у пользователей
Остальные подгружаем отдельно с помощью lazy import
// Было:
import PaymentTypes from '@/views/Directories/PaymentType/PaymentTypes.vue';
import OrderTypes from '@/views/Directories/OrderType/OrderTypes.vue';
import Configurations from '@/views/Directories/Configuration/Configurations.vue';
import NewConfiguration from '@/views/Directories/Configuration/NewConfiguration.vue';
import ConfigurationPage from '@/views/Directories/Configuration/ConfigurationPage.vue';
import Source from '@/views/Directories/Source/Source.vue';
import City from '@/views/Directories/City/City.vue';
import Brand from '@/views/Directories/Brand/Brand.vue';
import CloseReason from '@/views/Directories/CloseReason/CloseReason.vue';
import ChangeReason from '@/views/Directories/ChangeReason/ChangeReason.vue';
import Restaurants from '@/views/Directories/Restaurants/Restaurants.vue';
import RestaurantPage from '@/views/Directories/Restaurants/RestaurantPage.vue';
import NewRestaurant from '@/views/Directories/Restaurants/NewRestaurant.vue';
import Discounts from '@/views/Directories/Discounts/Discounts.vue';
import PriceTypes from '@/views/Directories/PriceType/PriceTypes.vue';
// Стало:
children: [
{
path: 'brand',
name: 'Бренды',
component: () =>
import('@/views/Directories/Brand/Brand.vue'), // <--тут
meta: {
breadcrumbs: ['Справочники', 'Бренды'],
requiresAuth: true,
permissions: ['admin.admin'],
title: 'Бренды',
section: 'directories',
},
},
...
]Запускаем снова и уже получаем уже разбитый бандл. Code Splitting работает, вывод сборки теперь показывает множество маленьких JS-файлов для каждой страницы.
Итоги оптимизации:
Уменьшили основной бандл с 245 kB до 148 kB (gzip) — это минус 39%
Что получили:
✅ Оптимизировала размер бандла на 40%
✅ Улучшила First Contentful Paint
✅ Внедрила code splitting
✅ Повысила производительность
✅ Уменьшила основной JavaScript-файл почти на 40% (в gzip)
✅ Уменьшила сырой размер на 46%
✅ Теперь загружается только то, что нужно для текущей страницы
Реальность:
❌ Съэкономил ли бизнес деньги? - Нет
❌ Выросла ли конверсия? - Как? 🌝 это внутренний админ-интерфейс
❌ Применили ли чудо-технологию? - Нет, добавили lazy import из коробки фреймворка и рекомендацией из документации
❌ Кто-то это заметил? - Только я в отчете, "на глаз" даже мне не заметно
❌ Заметил ли пользователь? - Нет, потому что основное время все равно уходит на получение данных с backend
Мысли по этому поводу
И так, мы теперь можем добавить заветную строчку в резюме!
А вы встречаете эту строчку в резюме?
Какие чувства она у вас вызывает?
Красный флаг ли она для вас?
Или наоборот - показатель того, что человек думает о производительности?
Мой канал о поиске работы (ничего не продаю и не рекламирую, только себя)
Недавно общался с крупной зарубежной продуктовой компанией. Штат 500–1000 человек, вроде зрелые процессы, ЗП у разрабов 5000€ баг-репорты по ISO/IEC/IEEE 29119. И при этом:
«Не успеваем уделять время автотестам. Сфокусированы на скорости разработки и релизах.»
Что меня зацепило — каждый их аргумент против тестов я интерпретировал как аргумент за:
— «Слишком частые релизы» → А не потому ли они такие частые, что баги проскакивают на прод?
— «Требования постоянно меняются» → Тем более — как вы контролируете, что старое не ломается?
— «И так работают наизнос если еще и тесты заставить писать — выгорят» → А не от бесконечного ли футбола с багами они выгорают?
А как у вас? Есть автотесты на проекте? Или тоже «не до них»?
Я написал целую статью на эту тему, если все выше вам откликается рекомендую к прочтению: Нет времени на тесты — через неделю релиз
Выбор вакансии: как я кинулась во всё — и это не дало результата.
Есть разработчики, у которых развитие идёт линейно и предсказуемо: верстальшик → джун фронтендер → мидл → мидл в сильной компании → сеньор/лид/уход в бэкенд
Красиво. Понятно. Логично.
Но у меня кривая черта развития сначала бэк на Java в закрытом предприятии. Потом фулстек в фудтехе: в основном Vue, но ещё и Go (и все сопутствующее), и CUBA Platform (lowcode на java, он же «Тезис»), и n8n.
Широко. Разнообразно. Интересно.

Как я начала откликаться - на всё, что блестит
И сейчас Когда я вышла на рынок, то сначала я откликалась на все что близко:
Frontend - Vue / React / Angular
Ну фронт же. Есть мнение, что «не нужно учить конкретный фреймворк — важны принципы».
Go
а почему бы нет? Знаю , умею , курсы закончены, писала на нем
Fullstack (Go или JDK + фронт)
N8N, автоматизаторы особенно с ИИ
Интересно. Растущее направление.
Lowcode платформы CUBA, тезис, WebTutor - замаскированный под фронтенд Опыт есть. Почему не использовать?
И это фатал еrror
Ошибка №1. Переключение контекста
Очень сложно переключать контекст и даже синтаксис языка - на первом собесе по TS я не смогла вспомнить синтаксис (на ум приходил только java, так как он изучался более долго и в закрытой среде, ирония: хоть я на нем и не пишу, но разбуди среди ночи - код напишу)
Ошибка №2. Рынок
Рассматривать вакансии на Angular, React без опыта в продакшене - на данный момент наивно.
Рынок перегрет:
- Vue ~ 1000 откликов за неделю,
- React - 4000 ,
Неужели Арина (или тот кто читает эту статью) ты думаешь, что кто-то будет рассматривать ваше резюме со Vue? Каким бы в целом хорошим инженером вы не были. Рынок не покупает «в целом».
Ошибка №3. Fullstack со связкой Go + Vue или JDK + Vue
Фуллстеки со связкой go или jdk - это бред вакансии, это карьерный тупик.
- PHP + Vue - норм
- Node + Vue - норм,
но Go + Vue - это нонсенс, это только подработка для поддержания штанов. Чаще это небольшие команды, поддержка, нестабильные проекты.
Ошибка №4. n8n — нравится, но это уже не совсем разработка
Автоматизация, интеграции, AI — это интересно. Но это больше аналитика и orchestration, чем классическая инженерия. Если хочешь быть разработчиком — нужно понимать, куда ты смещаешь фокус.
Ошибка №5. Low-code — карьерный тупик
Проблем с окружением больше. Кода меньше. Рынок уже. Ты становишься зависимой от конкретной платформы. И выйти обратно в «чистую разработку» становится сложнее.
Мой Hotfix: Фокус
Я поняла, что на падающем рынке выживают либо "универсалы" c ИИ подбоком, либо эксперты
Моя новая стратегия:
Vue 3 + TypeScript + Nuxt (как зона роста)
n8n — как подработку и интересный дополнительный навык.
Иногда рост — это не добавить ещё стек. А убрать лишнее.

OAuth на практике: что оказалось удобным, а что отпугнуло пользователей
Мы запустили молодую платформу с двумя типами аккаунтов: обычные пользователи и разработчики (публикуют PWA и управляют приложениями).
Бренда и доверия пока нет, поэтому вопрос авторизации быстро стал не техническим, а психологическим.
С чего начали
Для обычных пользователей:
• Email / пароль
• Google
• GitHub
Для разработчиков — жёстче:
• Обязательная привязка Google
• Обязательная привязка GitHub
Логика казалась разумной:
«Разработчик = есть GitHub»
«Двойная верификация = меньше спама»
На практике это не сработало.
Первые тревожные сигналы
Регистрация разработчиков шла крайне медленно, несмотря на интерес к публикации приложений.
Сначала списывали на:
• новый продукт
• низкое доверие
• отсутствие аудитории
Но после общения с разработчиками (в том числе через Habr) картина прояснилась.
Что отпугивало разработчиков
Новый сервис → нежелание делиться данными
Даже если это «просто email», психологический барьер остаётся.
Когда с первого шага нужно:
• линковать внешние аккаунты
• проходить несколько этапов подтверждения
• подключать сторонние сервисы
это воспринимается как лишний фрикцион.
Особенно для соло-разработчиков и небольших команд.
Git ≠ GitHub
Ключевой инсайт.
Мы обнаружили, что:
• не все хотят логиниться через GitHub
• часть использует GitLab или Bitbucket
• некоторые принципиально не хотят связывать GitHub с новым сервисом
Обязательная привязка GitHub стала серьёзным барьером.
А мнение стандартных пользователей разделилось:
Часть говорила:
«Чем больше OAuth-кнопок, тем солиднее выглядит платформа».
Логика простая:
• если есть Google / Facebook / Discord — значит не ноунейм
• интеграции с крупными сервисами повышают доверие
Это не про безопасность — это про ощущение легитимности.
Другие говорили ровно противоположное:
«Слишком много кнопок — ощущение перегруженности».
И это тоже справедливый аргумент.
Что мы изменили
Упростили форму для пользователей
Оставили:
• Google
• Facebook
• Discord
Достаточно выбора для доверия, без визуального шума.
Git-провайдеры вынесли в отдельную группу
Под отдельной кнопкой:
• GitHub
• GitLab
• Bitbucket
Для разработчиков это стало понятнее и логичнее.
Убрали обязательный GitHub
Теперь для developer-аккаунта нужно подключить любой Git-аккаунт, если ни один не подключён.
Без принудительного GitHub.
Первые цифры (осторожно)
Прошла всего неделя, выборка маленькая, платформа всё ещё молодая.
Тем не менее:
• Зарегистрированные пользователи: +13%
(было 0–6% в неделю)
• Зарегистрированные разработчики: +16%
(было 0–3%)
Похоже, это те разработчики, которые знали о платформе, но их останавливало требование GitHub.
Выводы (пока не финальные)
• OAuth — это не только безопасность, но и психология доверия
• Жёсткие требования на старте почти всегда бьют по росту
• Git ≠ GitHub — и это важно
• Много провайдеров могут как повышать доверие, так и перегружать UI
Для молодой платформы даже такие ранние сигналы уже показательны.
Интересно услышать опыт коллег:
добавляли ли вы OAuth-провайдеров после запуска?
были ли случаи, когда обязательная авторизация через конкретный сервис тормозила рост?
Греческие мифы рассказывают про титана Прометея, который украл у богов огонь и поделился им с людьми. Персонажа за это приковали к скале не просто в наказание, но и в назидание остальным: знание не даётся бесплатно, за него нужно платить.
Если судить по названию, автор проекта Promethee кары богов нисколько не боится. Некто SMNX взял самый сакральный слой современного компьютера — прошивку UEFI — и добавил туда JavaScript. Как гласит readme.md, на старте загрузки Promethee подхватывает script.js с загрузочного тома и исполняет его, то есть этот скрипт и будет загрузчиком.
Понятно, что на боевую машину это ставить смысла нет, это просто эксперимент. Лабораторный характер подчёркивается сборкой и запуском в QEMU. Проект реализован автономно (freestanding), с минимальными заглушками libc. В качестве движка используется Duktape — встраиваемый JS-движок, рассчитанный на портируемость и компактность.
Для SMNX это уже не первый подобный забавный самопис. На своём сайте автор представляется как Клем и прямо говорит, что любит строить «операционные системы, компиляторы, инструменты и веб-движки». Там же перечислены другие поделки: модульная хобби-операционка SkiftOS, HTML/CSS-движок Vaev, экспериментальные инструменты для генерации документов, а также операционная система с эстетикой брутализма и идеалами UNIX семидесятых BRUTAL.
JavaScript исторически задумывался как язык, который оживляет веб-страницы и делает их интерактивными. Сегодня же он расползся по всем слоям стека, от микроконтроллеров до ультра-лёгких движков для Интернета вещей. В том числе бывают попытки писать на JavaScript то, что не следует, хоть операционные системы. Самый цитируемый пример — это NodeOS, дистрибутив Linux, где вместо привычного пользовательского мира предлагается использовать Node.js и npm как основной пакетный менеджер, и многие утилиты предполагается брать из npm-экосистемы. Другой полюс — runtime.js, библиотечная операционка, где JavaScript-рантайм на базе V8 и минимальная операционка собираются в лёгкий неизменяемый образ виртуальной машины для запуска на KVM, то есть ОС здесь становится упаковкой для единственного приложения на JS.
Promethee — не первый проект, где соседствуют JavaScript и UEFI. Беглый поиск обнаруживает порт Duktape под UEFI-приложения.
Открытый учебный проект JavaScript Mastery — Complete Learning Path — это курс для изучения языка программирования JavaScript. Энтузиасты собрали более 500 учебных материалов — репозиторий заменяет буквально 4 года учёбы в университете. Есть вся база от определения переменных до ООП, замыканий и других сложных, но функциональных концепций. Сотни упражнений для повторения материалов и закрепления знаний. Примеры кода, визуализация всех концепций, каждый учебный пример авторы разжёвывают до последней строчки. В конце есть идеи пет‑проектов, чтобы закрепить знания. В проекте есть гайд для подготовки к собеседованиям со всеми актуальными вопросами.

Selectel открыл первую часть курса по JavaScript

Привет, Хабр! Новичкам бывает трудно сделать первый шаг в программировании. В интернете много сомнительных курсов, а качественные требуют финансовых вложений и несколько месяцев на изучение.
Мы в Selectel подготовили бесплатный курс, который поможет быстро и без лишних затрат изучить основы JavaScript. В первую часть входят три модуля. Вы узнаете:
для чего разработчики используют JavaScript,
как работать с со скриптами, веб-страницами и переменными,
как создать рабочее окружение на IT-инфраструктуре Selectel.
Участники курса смогут бесплатно протестировать сервисы Selectel, а по итогам тестирования — получить сертификат о прохождении.
Макротасок не существует.
Один из самых частых вопросов на собеседованиях для frontend разработчиков: Расскажите про событийный цикл? как выполняются таски? что такое микротаски и макротаски?
В архитектуре event loop вообще нет такого слова как макротаски(macrotasks). Я вообще не смог найти ни одной спецификации, где было бы написано слово macrotask. Кроме Promises/A+. Так в чем же разница между Promise и setTimeout? Почему Promise всегда(не всегда) будут исполняться в приоритете?
Браузер имеет несколько очередей задач (task queues) для разных типов тасок. Таска - это любой javascript код, запланированный стандартными механизмами, такие как запуск программы, запуск события или коллбэки. Помимо этого вы можете создать таску с помощью API, например WindowTimers(setTimeout, setInterval). Микротаски же в свою очередь такие же конструкции javascript, которые позволяют выполнять операции не дожидаясь запуска нового цикла event loop (process.nextTick, Promises, queueMicrotask). Так вот, так как setTimeout, setInterval относятся к браузерному API, то очередь микротасок, таких как Promise и т.д. всегда будет в приоритете выполнения, перед браузерным API.
При этом стоит учитывать, что браузерные API исполняют таски в разные очереди и по разному, например MutationObserver среагировавший после того, как в очередь микротасок попал успешный промис от функции fetch, будет выполнен раньше. То есть вставка в очередь тасок может быть не только как push. Таким образом то, что называют макротасками - это таски браузерного API, которые выполняются по одной на цикл движка браузера.
Полезные материалы
W3 (https://www.w3.org/TR/2011/WD-html5-20110525/webappapis.html#task-queue)
MDN Event Loop (https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop)
Tasks, microtasks, queues and schedules (https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules)
Филипп Робертс: Что за чертовщина такая event loop? | JSConf EU 2014 (https://www.youtube.com/watch?v=8aGhZQkoFbQ)
Джейк Арчибальд. В цикле - JSConf.Asia (https://www.youtube.com/watch?v=cCOL7MC4Pl0)
Игра на джем "Rush lvl 8"
Ребята всем привет, опубликовал на джем игру простую, но довольно интересную.
Мне посоветовали её на гитхаб pages выложить, что я и сделал.
Если хотите - зацените геймплей и если хотите непосредственно попробовать то вот ссылка
https://prikalel.github.io/they-grow/
Если хотите поддержать то оставьте комментарий под постом или зайдите на страницу джема и поставьте лайк мне будет очень приятно)
Представлен открытый веб-редактор изображений DPaint.js (онлайн-версия) на JavaScript, созданный по образцу легендарного Deluxe Paint, с упором на ретро-форматы файлов Amiga. Помимо современных форматов изображений, DPaint.js может читать и записывать файлы иконок Amiga и изображения IFF ILBM.
Основные возможности проекта: слои, выделение, маскирование, инструменты трансформации, эффекты и фильтры, множественная отмена/повтор действий, копирование/вставка из любой другой программы обработки изображений или источника изображений, настраиваемые инструменты дизеринга и циклическая смена цветов.

Коллеги привет, искал себе решение как реагировать на изменения в объекте и нашел отличный сервис, который используется внутри директив таких как NgClass и NgStyle.
KeyValueDiffers позволяет создать KeyValueDiffer для сравнения изменений текущих пар ключ-значение с новыми. Если вы используете иммутабельные объекты, то можно просто обернуть все в эффект, ну а если вы наследники крутого легаси, где все объекты мутируются по ссылке, тогда проверку нужно вешать в DoCheck, чтобы реагировать на каждый тик change detection.
Накидал оба примера, чтобы поделиться с вами:
Иммутабельный с effect:
@Component({
selector: 'app-test',
template: ''
})
export class TestComponent {
public state = input.required<Record<string, string | number>>();
private differs = inject(KeyValueDiffers);
private differ: KeyValueDiffer<string, string | number> | undefined;
constructor() {
effect(() => {
const currentState = this.state();
// создаем диффер, если он еще не создан
if (!this.differ) {
this.differ = this.differs.find(currentState).create();
}
// Эффект будет перезапускаться при изменении инпут-сигнала.
const changes = this.differ.diff(currentState);
// только если есть изменения
if (changes) {
changes.forEachAddedItem((record) => {
console.log(`В объект добавлена запись: Ключ: ${record.key} | Значение: ${record.currentValue}`)
});
changes.forEachChangedItem((record) => {
console.log(`Изменено: ${record.key} | Новое значение: ${record.currentValue}`)
});
changes.forEachRemovedItem((record) => {
console.log(`Удалено: ${record.key}`)
});
// Остальные методы forEachItem и forEachPreviousItem по необходимости
}
})
}
}
Легаси подход, которого, надеюсь, ни у кого нет, но на всякий случай :)
@Component({
selector: 'app-legacy',
template: ''
})
export class LegacyComponent implements OnInit, DoCheck {
@Input({ required: true }) state!: Record<string, string | number>;
private differs = inject(KeyValueDiffers);
private differ: KeyValueDiffer<string, string | number> | undefined;
ngOnInit() {
// Создаем диффер при инициализации
this.differ = this.differs.find(this.state).create();
}
// Запускается на каждый тик change detection, так как мутации по-другому не отследим.
ngDoCheck(): void {
const changes = this.differ?.diff(this.state);
if (changes) {
changes.forEachAddedItem((record) => {
console.log(`В объект добавлена запись: Ключ: ${record.key} | Значение: ${record.currentValue}`)
});
changes.forEachChangedItem((record) => {
console.log(`Значение изменилось: ${record.key}`)
});
changes.forEachRemovedItem((record) => {
console.log(`Запись удалена: ${record.key}`)
});
// Остальные методы forEachItem и forEachPreviousItem по необходимости
}
}
}

Почему у PWA до сих пор нет полноценного «магазина приложений» — возможно ли это вообще?
Всем привет.
В течение последних месяцев, работая с PWA-приложениями, мы постоянно сталкивались с одним и тем же вопросом:
Почему в 2025 году у PWA до сих пор нет настоящего App Store?
Не просто каталога ссылок, а полноценного магазина приложений — знакомого, вызывающего доверие и понятного обычным пользователям.
При изучении существующих PWA-магазинов и каталогов обнаруживаются одни и те же повторяющиеся проблемы.
⸻
Установка остаётся непонятной для пользователей
Даже сегодня установка PWA вызывает затруднения у обычных пользователей.
Большинство из них не понимают:
• когда приложение действительно можно установить,
• почему инструкции по установке не совпадают с реальными шагами в их браузере или на устройстве.
Во многих PWA-каталогах всё ограничивается текстовой инструкцией — и на этом взаимодействие с сервисом фактически заканчивается.
⸻
Отсутствие доверия
Со стороны пользователя это проявляется в следующем:
• нет содержательных отзывов,
• отсутствует история установок,
• нет ощущения личной библиотеки приложений.
Со стороны разработчиков наблюдаются крайности:
• либо любой может опубликовать приложение без подтверждения права собственности,
• либо проверка обязательна, но сложна и ограничена одним способом (например, через DNS-записи).
В итоге доверие не формируется ни у одной из сторон.
⸻
Разработчики — второстепенные участники экосистемы
Распространённые проблемы:
• медленные и неудобные процессы публикации,
• почти полное отсутствие автоматического заполнения данных из манифеста,
• нехватка инструментов, которые были бы полезны разработчику ещё до установки приложения пользователем.
Экосистема не стимулирует разработчиков поддерживать и развивать свои PWA.
⸻
Интерфейс не воспринимается как «нативный»
Это тонкий, но важный момент.
Если магазин:
• выглядит как обычный веб-сайт,
• не вызывает ассоциаций с App Store или Google Play,
пользователи инстинктивно доверяют ему меньше — даже если сами приложения качественные.
⸻
При этом сами PWA как технология за последние годы заметно повзрослели: офлайн-режим, push-уведомления, installability, Web APIs.
Однако именно слой распространения и доверия остаётся самым слабым звеном.
⸻
Главный вопрос, к которому мы пришли
Возможно ли вообще создать PWA-магазин, который:
• пользователи будут воспринимать как настоящий магазин приложений,
• не станет источником боли для разработчиков,
• сможет устойчиво развиваться, а не быть заброшенным через несколько месяцев?
Или же сама идея магазина PWA в текущей экосистеме изначально ошибочна?
Будет интересно узнать ваш опыт.
Вы публиковали PWA-приложения в существующих магазинах или каталогах?
Что вызывало наибольшие сложности — у разработчиков или у пользователей?