Самое время смотреть и задавать вопросы спикерам в чате митапа!
Митап посвящен главным вызовам и проблемам в сложных интерфейсах. Спикеры расскажут о самых разных аспектах фротенда в 2025 году: от айтрекинга и других методов исследований до реактивного программирования и СSS-спецификаций.
Сам митап разделен на две категории: JavaScript и UX. В каждой из них, помимо наших специалистов, есть ребята и из других компаний: Лаборатория Касперского, Контур, Alpha Research Center. Всего на встрече будет семь докладов – их расписание можно посмотреть здесь.
Как студенты с айтрекером изучали наш текстовый редактор
Июнь стал месяцем айтрекинга в UX-команде МойОфис. Сначала у нас прошло совместное исследование со студентами ВШЭ, а в ближайшие дни мы проведем крупный митап, где поговорим о создании и анализе сложных интерфейсов, в том числе с помощью технологий отслеживания взгляда.
Важный анонс: 26 июня пройдет онлайн-митап МойОфис Frontend&UX Talks, на котором JS-еры, дизайнеры, продакты и аналитики соберутся, чтобы обсудить все насущные проблемы и нюансы современного фронтенда. Кроме наших экспертов, на митапе будут ребята из Лаборатории Касперского, Контура и Alfa Research Center!
Регистрируемся и читаем темы выступлений здесь – и вступаем в чат, чтобы не пропустить важные обновления (и просто поболтать с коллегами по фронтендерскому цеху).
Еще немного о совместном исследовании со студентами:
4 июня в нашем петербургском офисе прошла презентация результатов совместного исследования с лабораторией социальной и когнитивной информатики ВШЭ в рамках учебного сотрудничества. Студенты курса «Айтрекинг в UX-аналитике» провели глубокое тестирование текстового редактора МойОфис 3.4 с обновлённым интерфейсом.
Методология:
Определили самые востребованные задачи у студентов и на их основе составили задания.
Использовали носимый open-source айтрекер PupilLabs.
Провели психологические опросы до и после заданий (спойлер: уровень стресса участников не изменился) и когнитивное интервью после.
Ключевые результаты:
Проявилась часть проблем, о которых мы уже знали и исправили в версии редактора 3.5. Например, более удобное выделение ячеек таблицы без лишнего клика.
Получили оценки пользователей: лёгкость и чёткость интерфейса.
Подтвердилась необходимость в новом поиске по функциям, к которому прибегали участники, когда что-то не получалось найти, или они не знали, как выполнить задачу.
Выявлены новые точки роста для развития продукта
P.S. Большая благодарность Елене Артёменко из лаборатории социальной и когнитивной информатики ВШЭ за эту коллаборацию! А если хотите узнать больше о фронтенде и UX-исследованиях — ждем вас 26 июня на Frontend&UXTalks!
В Angular 20 afterRender был переименован в afterEveryRender, и это очень логично, так как теперь он более четко отражает суть (нейминг решает). Сам afterRender (далее afterEveryRender) и его брат afterNextRender появились в версии 17. Рассмотрим, почему эти два мощных инструмента управления рендерингом — не просто альтернативы ngAfterViewInit, а полноценные хуки жизненного цикла с бесшовной поддержкой SSR!
Это хуки? Да! Это хуки нового типа, которые выполняются после рендеринга компонента:
Они не заменяют ngAfterViewInit/ngAfterContentInit, а дополняют их
Включают гранулярные реакции на рендеры, включая обновления
Почему идеально подходит для SSR? Главное преимущество: обратные вызовы выполняются только на клиенте! ✅ После гидратации (в SSR) ✅ После первоначального рендеринга (в CSR) ✅ Больше никаких ошибок «документ не определен»
Использование: constructor() { // 🚫 Не запускается на сервере // ✅ Запускается только один раз после загрузки браузера! // 📊 Идеально подходит для однократной инициализации afterNextRender(() => { console.log('Next'); });
// 🚫 Не запускается на сервере // 🔄 Запускается после каждого цикла обнаружения изменений // ✨ Отлично подходит для обновлений, зависящих от DOM afterEveryRender(() => { console.log('Every'); }); }
Когда использовать?
afterNextRender
Одноразовые операции (инициализация библиотеки, загрузка данных)
Безопасная замена ngAfterViewInit для SSR
afterEveryRender
Отслеживание изменений DOM (измерения элементов, позиции)
⚠️ Внимание: может повлиять на производительность
Основные выводы
Интегрировано в систему жизненного цикла Angular
Автоматический пропуск на стороне сервера - больше никаких хаков isPlatformBrowser!
afterNextRender - "один раз после рендеринга"
afterEveryRender - "после каждого обновления"
"Я пока не использовал afterEveryRender в своих проектах - есть ли у вас практические примеры использования? Поделитесь в комментариях!"
JavaScript, дизайн-системы и рок-н-ролл — что такое фронтенд в 2025 году?
Что происходит, когда в одном месте собираются JS-еры, UX-дизайнеры и исследователи? Получается Frontend&UX Talks!
Без сложных интерфейсов в фронтенде сегодня никуда: продукты становятся все масштабнее, а требования – все выше. Для всего этого нужны свежие и эффективные решения, которые ускорят разработку, и помогут провести релевантные UX-исследования.
Чтобы обсудить эти темы, мы в МойОфис пригласили ребят из разных компаний: Alfa Research Center, Лаборатория Касперского и Контур.
Всего на митапе будет 7 докладов, где расскажем:
как реактивное программирование и RxJS меняет разработку – и какие у него есть нюансы;
какие свежие css-спецификации могут упростить ежедневный кодинг;
как «редизайнить» сложные интерфейсы: рассказ на личном опыте переосмысления визуала настольных редакторов практически с нуля;
что за методы UX-исследований использует финтех сегодня – и какие из них можете перенять и вы :)
и многое другое, что поможет в работе со сложными интерфейсами!
Если тебе близки эти темы — приходи 26 июня в 15:00. Регистрация и подробности по ссылке.
Манипуляций довольно много, но мы все к этому привыкли и это кажется нормальным.
Но с withComponentInputBinding() все стало намного проще: 1. Создаем сигнальный инпут... и... Вот и все!
Никаких дополнительных манипуляций, и значение «у вас в кармане». Все, что вам нужно, чтобы это работало, — это передать withComponentInputBinding() в качестве аргумента в provideRouter().
Функция не новая (кажется, появилась в Angular 16), но я редко ее видел в проектах.
Немного технической информации из документации:
🔍Маршрутизатор передает данные в input() из:
Параметров запроса (?page=1&sort=asc)
Параметров пути и матрицы (/users/123;details=true)
Статических данных маршрута (data: { role: 'admin' })
Результатов резолвера (resolve: { user: userResolver })
🔍 Приоритеты: Если есть дублирующиеся ключи, данные переопределяются в порядке выше — резолверы имеют наивысший приоритет и перезапишут остальные.
🚩 Важный нюанс Если в маршруте нет данных для input(), он получит undefined (например, если параметр запроса удален из URL).
ℹ️ Как задать значения по умолчанию?
✔ Через resolver (чтобы данные всегда были в маршруте) ✔ Через transform в input() (если нужно обрабатывать undefined)
Спасибо разработчикам Angular за эту функциональность 🙏.
Сначала любая программа подвергается лексическому анализу, который выполняет компонент V8 под названием Scanner. И он разбивает исходный код на поток отдельных токенов в соответствии с лексической грамматикой, описанной в спецификации ECMAScript.
Интересно, что невалидные программы, вроде...
const = = ;
...ещё не выдадут ошибку на данном этапе. Сканер спокойно разобьет нашу программу на токены и отдаст дальше, ведь проверка синтаксической корректности не его зона ответственности. Это зона ответственности Parser, который способен выявить все синтаксические ошибки.
Кстати, одна из ключевых особенностей Parser — генерация Abstract Syntax Tree, которое затем используется для создания байт-кода внутри Ignition. На основе полученных токенов из Scanner генерируется дерево, в котором каждый узел отражает языковую конструкцию: идентификатор, оператор, выражение или функцию.
Например, для кода...
const sum = (a, b) => a + b;
...мы получим следующее дерево:
VariableDeclaration (const)└── VariableDeclarator ├── Identifier: sum └── ArrowFunctionExpression ├── Params │ ├── Identifier: a │ └── Identifier: b └── BinaryExpression (+) ├── Identifier: a └── Identifier: b
Я много и часто просматриваю JSON-файлы: от конфигураций сервисов до API ответов и логов. Каждый раз, открывая очередной файл, я форматирую содержимое, чтобы было удобнее читать (ведь JSON не только machine-readable, но и human-readable). И каждый раз я грущу, что все сервисы (онлайн, встроенные средства IDE и даже плагины) предоставляют лишь две крайности: форматировать всё или ничего (минифицировать в одну строку).
Но что, если я хочу отформатировать JSON лишь до определённого уровня? Что, если у меня есть огромный список словарей (возможно, даже глубоких), который при форматировании выглядит как-то так:
Да, многие текстовые редакторы вроде Sublime Text или VS Code дают возможность свернуть контент до определённого уровня. Но что, если я хочу оставить файл в этом промежуточном виде и просматривать его прямо в терминале, подключившись по ssh? Или я хочу посмотреть файл на гитхабе с телефона? Да, возможно, мои вкусы весьма специфичны, но в существующих реалиях я вынужден грустно довольствоваться лишь полностью развёрнутым вариантом (или делать это вручную). Встроенные средства форматирования JSON в JS или Python также не предоставляют простой возможности ограничить глубину (либо я так и не научился их готовить).
Поэтому я собрался с силами и написал свой форматтер с возможностью ограничить глубину. Помимо базового функционала вроде валидации, минификации и настройки количества отступов, в нём есть настройка максимальной глубины (по умолчанию она равна нулю, что соответствует привычному форматированию без ограничений).
Да, он вряд ли подойдёт, чтобы редактировать на лету гигантские JSON файлы. И он уж точно не пытается стать убийцей какого-либо из существующих онлайн сервисов. В первую очередь он призван решить мою проблему: сделать форматирование JSON чуточку более управляемым. А если и вы сталкивались с подобной проблемой, буду рад, если сервис поможет и вам!
Иногда нужно отобразить несколько одинаковых элементов чисто для ui-целей: скелетоны загрузки, звёзды рейтинга, пустые таблицы и т.д., но без реальных данных для итерации.
Вот мой способ (по крайней мере, я нигде такого не видел):
@for (_ of [].constructor(10); track $index) { <div class="item"></div> }
Используется Array.constructor, чтобы создать пустую массив фиксированной длины, который @for может перебрать по индексам.
Плюсы ✅
Чудо-код (удивит коллег)
Минимум кода (не нужно объявлять массив в компоненте)
Минусы ⚠️
Чудо-код (может ненадолго ввести в ступор чающего код человека)
Конечно, можно просто использовать Array.from({length: 10})... но так все делают, не интересно)
Приглашаем вас на бесплатный вебинар «TypeScript за час: основы, плюсы и практика». Познакомим вас с TypeScript. Расскажем, зачем он появился, в чём его преимущества и как он помогает писать понятный и надёжный код. Подойдёт и новичкам, и практикам.
⁉️ На вебинаре вы сможете задать вопросы спикеру.
📅 Дата: 13.05.2025
⏰ Время: 17:00-18:00 (Мск)
На вебинаре:
✔️ История возникновения TypeScript
✔️ Преимущества использования TypeScript
✔️ Пример написания кода на TypeScript
👨🎓 Спикер: Кучин Евгений — разработчик на Java и JavaScript.
Возможно, вам будет интересен курс «Язык программирования TypeScript». Вы освоите TypeScript, изучив типизацию, интерфейсы и классы. Узнаете, как использовать статическую типизацию, интегрировать TypeScript с существующим JavaScript и настраивать окружение разработки. Это поможет сделать ваш код более безопасным и структурированным.
Экосистема JavaScript — обширная, гибкая и насыщенная готовыми решениями. Она позволяет без особых усилий подключать сторонние пакеты — как в браузере, так и на сервере. Но у этой открытости есть и обратная сторона: сторонний код может вмешиваться в ваш собственный. Хорошо, если это происходит явно. Но бывает иначе: кто-то оборачивает ваши функции, переопределяет методы, расширяет прототипы — и тихо выполняет свою «чёрную работу».
В такой среде доверие к собственному коду становится условным. Разработчик ещё способен более-менее контролировать точку входа — HTML-страницу или Node.js-скрипт. Он может доверять тому, что написал сам и вызывает сам. До тех пор, пока не подключит стороннюю библиотеку. А дальше — возможны любые сценарии.
Чтобы можно было доверять своему коду хоть немного больше, я пошёл на эксперимент и по умолчанию встроил "заморозку" всех объектов, создаваемых моим DI-контейнером:
let res = await _composer.create(key, module, stack, this);
if (canBeFrozen(res)) Object.freeze(res);
При запуске node-приложения (или при загрузке кода на веб-страницу) я создаю контейнер и через него получаю нужный объект со всеми зависимостями:
Поскольку все объекты, получаемые из контейнера, автоматически замораживаются, сторонний код не может изменить поведение уже созданной зависимости — даже если получит к ней доступ.
Разумеется, такой подход не делает JS-среду абсолютно безопасной. Но он позволяет немного повысить уровень доверия к тому, что происходит внутри.
Эта идея родилась после прений с коллегой @nin-jin — так что спасибо ему за подброшенную мысль ;) Я реализовал её в коде, опробовал на своих приложениях и вот теперь делюсь результатом.
Опубликовано исследование о том что индексирование сайтов поисковиком (Google) не зависит от того, SPA ли это или же он SSR. Также пару лет назад делал аналогичное расследование и пришел к тому же выводу.
Вообще, мы пришли к идеалу достаточно давно - когда сервер занимается своими делами, а клиент статический, минифицирован, и раздается из CDN для быстроты и без траты ресурсов сервера.
ИИ-ассистенты (промпты) - это тоже low-code. Бизнес-аналитики сами разрабатывают ИТ-продукты. Сайт какой сложности можно разработать без знания JavaScript? Кейс app.2lead.ru
Возможности low-code растут. Бизнес-аналитики сами разрабатывают ИТ-продукты, фактически добавляя к своим обязанностям часть функций программистов. При этом эксперты не прогнозируют, что low-code полностью заменит традиционное программирование в ближайшие годы.
ИИ-помощники (промпты) - это тоже low-code
Чаще всего low-code определяют как создание ПО с помощью графических интерфейсов и настроек, а не через традиционное программирование. Мне ближе более широкое определение: low-code – это системы и платформы, которые предполагают изменение, дополнение кода пользователем, в том числе с применением ИИ-помощников (промптов).
ИИ-ассистенты значительно ускорили разработку сервисов app.2lead.ru, созданных мной на JavaScript - без опыта программирования на этом языке. Это подтверждает возможность разработки ПО силами бизнес-аналитиков, продуктовых менеджеров и так далее. Ранее это была прерогатива только профессиональных программистов.
Сервисы app.2lead.ru разработаны в конце 2024 года – начале 2025 года. Вошли в топ-5 Яндекса по запросу «калькулятор инфляции». Уже увеличили органический трафик сайта 2lead.ruболее чемв 5 раз, без расходов на рекламу. // См. также «Нерекламные методы продвижения» https://habr.com/ru/articles/686736/
Что дальше? Массовое применение таких методов разработки ПО, более совершенные low-code системы и программирование голосом? Считаю, что практику low-code нужно расширять, разрабатывать учебные материалы по этому направлению и т.д. В этих инструментах есть большое пространство для развития.
На картинке — код на JavaScript с ошибкой, который написал специально для Хабра руководитель группы разработки интерфейсов компании «Криптонит» Василий Беляев.
Кто увидел, где ошибка и как её можно решить — пишите в комментариях! А решение этой ошибки оставили под картинкой.
Где здесь ошибка?
Если запустим этот код, то получим ошибку
Uncaught TypeError: this.clearHistory is not a function
Проблема находится на строчках 11-13 (на картинке)
Регулярно на Хабре выходят статьи с рекомендацией использовать moment.js. В комментариях обязательно начинают советовать какой-нибудь dayjs или js-joda, но не потому, что они чем-то сильно лучше, а потому, что первый задепрекейчен авторами.. в пользу luxon.
Что за мания такая у JS-еров использовать раздутые тормозные библиотеки? Есть же быстрый и миниатюрный $mol_time с гораздо более удобным и функциональным API, почти полностью поддерживающим ISO8601, в отличие от всех остальных библиотек.
Бенчмарки говорят сами за себя
Что мотивирует людей довольствоваться не самым лучшим решением в индустрии? Я, наверно, странный, но я не могу этого понять.
Полезные ресурсы для начинающего JavaScript-разработчика
Делимся полезными материалами, которые помогут разобраться в основах и сделать первые шаги в программировании на JavaScript.
«Зачем учить JavaScript» — объясняем на примерах, почему без JavaScript не будет современных сайтов и что делает этот язык программирования таким востребованным. Расскажем о преимуществах JS и его перспективах.
«Всё про JavaScript» — большая подборка статей про основы JavaScript, возможности его использования и типичные ошибки новичков. Также в подборке можно найти задачи для собеседований и туториалы разных проектов.
Теория — это хорошо, а для практики подойдёт бесплатная часть курса «Фронтенд-разработчик». В ней вы изучите базовый синтаксис HTML и CSS, попробуете размещать блоки на веб-странице, менять шрифт и цвета, а также напишете с нуля простую программу на JavaScript.
— Да, фронтенд перенасыщен. Фреймворков много, технологии постоянно меняются. Все говорят об одном, но пишут по-разному. Но именно это и держит в тонусе — приходится регулярно обновлять знания. Сожалею ли я о своем выборе? Нет. Всегда любил погружаться в математические задачи, а фронтенд затягивает. Можно сутки биться над багом, ненавидеть его, плеваться… А потом решить — и словить кайф. В такие моменты код полностью поглощает, заставляя забыть о сне и еде.
Стоит ли идти во фронтенд сейчас?
— Никогда не поздно. Да, путь у каждого свой, и рынок сейчас нестабилен. Но при глубоком погружении за год можно набрать нужные скиллы и попасть на коммерческий проект.
🔥 Открыт набор на новый марафон!
Сейчас в Clevertec проходит марафон для начинающих фронтенд‑разработчиков. Это возможность погрузиться в профессию, получить реальный опыт и, возможно, стать частью команды. Участие бесплатное. Успей зарегистрироваться!
Запускаем бесплатный онлайн-марафон по фронтенд-разработке. Будет как в «Рокки»
Спринты, дедлайны и финальный тест-бой. Кто пройдет с нами три месяца подготовки — получит шанс на титул. Без метафор — мы реально ищем таланты и готовы взять их на стажировку.
Как записаться?
Заполни анкету по ссылке в профиле и скинь другу. Заявки принимаем до 26 марта.
Что будет?
Интенсивный 3-месячный тренинг. Это бесплатно. По сути, ты будешь поэтапно с дедлайнами писать приложение. Каждый спринт проверяем с помощью автотестов. Плюс будет поддержка менторов, наших крепких разработчиков. Это реальная прокачка твоих навыков и готовый проект в резюме.
Это уже четвертый марафон — после каждого наша команда фронтенд-разработчиков растет.
Кого ждём?
Начинающих веб-разработчиков (JS, React), которые уже изучали теорию и хотят прокачаться на практике в условиях, максимально близких к реальному проекту. Главное — желание кодить. Подойдут:
- студенты профильных вузов
- выпускники курсов
- самоучки
Важное условие: приглашаем участников из Беларуси и России.
Что дальше?
После 26 марта отправим на почту инструкции и первые задания. Старт марафона 1 апреля (это не шутка). До связи, Рокки.
Интерактивный стримкаст со зрителями 9 марта в 19:00
Максим будет писать веб интерфейс для вики (с выделением текста и возможностью отставлять инлайн комментарии) с помощью последней версии Copilot agent. А все мы (включая вас) — токсично (и не очень) комментировать.
Если вы только начинаете (или хотите начать) изучать JavaScript, то для вас есть подборка обучающих материалов. Все они доступны бесплатно. Регистрироваться, оставлять контактные данные или оформлять подписку тоже не нужно.
Если долго использовать какой-то инструмент, мозг вырабатывает паттерны: мы повторяем одни и те же решения, не всегда задумываясь, что появились новые, более удобные способы. Так происходит и с JavaScript.
JS развивается каждый год, но многие продолжают писать код, как привыкли, не используя свежие возможности языка. Я стараюсь бороться с этим и внедрять новшества в свою повседневную работу и недавно пошел посмотреть что там нового подвезли в ECMAScript 2024 (ES15). А там оказалось довольно много интересного.
Например, новые методы массивов. Раньше методы вроде .sort() и .reverse() изменяли исходный массив, что могло привести к неожиданным багам.
Точно так же работают новые методы .toSorted() и .toSpliced(). Они делают код более предсказуемым и чистым.
Также, я с огромным восхищением прочитал про Temporal - новый объект для работы с датами и временем. Например, меня всегда поражало , что в Date месяцы индексируются с 0 (январь – это 0), а вот дни месяца начинаются с 1. Temporal фиксит эти проблемы и теперь можно: ✅ Создавать объекты только с датой или только со временем ✅ Удобно складывать и вычитать даты ✅ Работать с часовыми поясами без боли В общем делать все, для чего мы раньше тащили в проекты всякие moment и day.js.
К огромному сожалению Temporal пока не поддерживается в браузерах, но когда выйдет – работа с датами в JS станет в разы удобнее.
Если вам интересны такие обновления подписывайтесь на мой Telegram-канал!