Привет, фронтендеры! 👋
Мы подготовили подборку полезных статей от команды VK для разработчиков, которые хотят прокачивать архитектуру, подходы и технический бэк-офис фронтенда.
✨ Создание интерактивной доски, или Почему ресёрч важнее кода
Как команда проектировала интерактивную доску: от выбора CRDT и сравнения Yjs/Blocksuite до решения, когда использовать Canvas или SVG. В статье показываем, как ранний ресёрч экономит месяцы разработки и позволяет заранее продумать архитектуру, офлайн-режим, синхронность и масштабируемость.
✨ Внедрение зависимостей (DI) через библиотеку Tsyringe
Разбор подхода DI во фронтенде: зачем он нужен, как помогает разгружать архитектуру, улучшать тестирование и избегать жёстких связей. На примерах показываем, как внедрять Tsyringe в реальный проект, как структурировать зависимости и почему это ускоряет развитие продукта.
✨ Быстрый старт: пишем фреймворк для фронтенда
Пошаговое создание минимального фронтенд-фреймворка: виртуальное дерево, жизненные циклы, компоненты, обновления. Статья для понимания того, как работают популярные фреймворки «под капотом» и почему знание внутренних механизмов делает разработчика сильнее.
✨ О миграции с Angular на React в деталях
Практический кейс масштабной миграции: почему решили уйти с Angular, как разбивали проект на модули, какие подходы к интеграции использовали и какие подводные камни встретили. Материал для тех, кто готовится к большим рефакторингам и хочет избежать типичных ошибок при переходе на новую технологию.
#frontendvk #статьи
Мы подготовили подборку полезных статей от команды VK для разработчиков, которые хотят прокачивать архитектуру, подходы и технический бэк-офис фронтенда.
Как команда проектировала интерактивную доску: от выбора CRDT и сравнения Yjs/Blocksuite до решения, когда использовать Canvas или SVG. В статье показываем, как ранний ресёрч экономит месяцы разработки и позволяет заранее продумать архитектуру, офлайн-режим, синхронность и масштабируемость.
Разбор подхода DI во фронтенде: зачем он нужен, как помогает разгружать архитектуру, улучшать тестирование и избегать жёстких связей. На примерах показываем, как внедрять Tsyringe в реальный проект, как структурировать зависимости и почему это ускоряет развитие продукта.
Пошаговое создание минимального фронтенд-фреймворка: виртуальное дерево, жизненные циклы, компоненты, обновления. Статья для понимания того, как работают популярные фреймворки «под капотом» и почему знание внутренних механизмов делает разработчика сильнее.
Практический кейс масштабной миграции: почему решили уйти с Angular, как разбивали проект на модули, какие подходы к интеграции использовали и какие подводные камни встретили. Материал для тех, кто готовится к большим рефакторингам и хочет избежать типичных ошибок при переходе на новую технологию.
#frontendvk #статьи
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤4🔥2🤓2👀1
Bun — интересная замена Node.js. И дело не только в том, что npm в 20 раз быстрее (хотя
Node сидит на V8 и libuv, заточен под долгоживущие процессы. Каждый
Bun написан на Zig и использует JavaScriptCore, который стартует заметно быстрее V8. У него свой event loop вместо libuv, плюс куча логики вынесена в нативный код. В итоге рантайм поднимается почти мгновенно, и большинство операций вообще не упирается в overhead запуска.
TypeScript здесь работает из коробки, встроенный транспайлер на Zig, без отдельного
Совместимость с Node-API сегодня практически полная. Bun тянет
В одном бинарнике у нас:
1. runtime;
2. пакетный менеджер;
3. тест-раннер;
4. бандлер.
Бандлер умеет собирать TypeScript/JSX, tree-shaking, code splitting, sourcemaps и быстрые пересборки. Что-то вроде
Плюс есть приятные штуки для DX,
Для новых проектов Bun сейчас выглядит очень сильным кандидатом, меньше инструментов, меньше конфигов, выше скорость обратной связи при разработке. Node никуда не денется, у него огромная экосистема, но его монополия уже трескается.
А что вы думаете про Bun?
#frontendvk #bun
bun install действительно очень быстрый), а в архитектуре рантайма. Node сидит на V8 и libuv, заточен под долгоживущие процессы. Каждый
npm install, jest или просто node noscript.js — это старт процесса, парсинг модулей, прогрев JIT. Мы тратим секунды до того, как код вообще начинает делать что-то полезное.Bun написан на Zig и использует JavaScriptCore, который стартует заметно быстрее V8. У него свой event loop вместо libuv, плюс куча логики вынесена в нативный код. В итоге рантайм поднимается почти мгновенно, и большинство операций вообще не упирается в overhead запуска.
TypeScript здесь работает из коробки, встроенный транспайлер на Zig, без отдельного
ts-node/ts-jest. Тесты гоняются через bun test, Jest-совместимый раннер, который стартует и выполняет пачку тестов в разы быстрее привычного стека на Jest/Vitest и Node, потому что ему не нужно поднимать кучу отдельных процессов и обвязки.Совместимость с Node-API сегодня практически полная. Bun тянет
node:fs, node:http, Buffer, events и т.д, плюс умеет работать с миллионами npm пакетов и фреймворками, Next.js, Remix, Astro и другими. В идеале они хотят 100% Node-совместимость, и к этому регулярно подтягиваются релизами.В одном бинарнике у нас:
1. runtime;
2. пакетный менеджер;
3. тест-раннер;
4. бандлер.
Бандлер умеет собирать TypeScript/JSX, tree-shaking, code splitting, sourcemaps и быстрые пересборки. Что-то вроде
bun build ./index.tsx --outdir ./dist и получаем оптимизированный бандл с разделением кода, без конфигов на 200 строк. Плюс есть приятные штуки для DX,
bunx как аналог npx, встроенный .env лоадер, HTTP-серверы без лишней обвязки, возможность постепенно подтягивать только bun install или только bun test даже в старых Node-проектах, не переписывая всё сразу. Для новых проектов Bun сейчас выглядит очень сильным кандидатом, меньше инструментов, меньше конфигов, выше скорость обратной связи при разработке. Node никуда не денется, у него огромная экосистема, но его монополия уже трескается.
А что вы думаете про Bun?
#frontendvk #bun
👍18🔥6❤3🤗1🆒1
Привет! Это рубрика «Знакомство с командой», и сегодня с нами руководитель команды разработки направления VK WorkSpace — Ярослав Ковалев. Поговорим не только о проектах, но и о том, чем он занимается за пределами работы.
Как ты выбрал программирование и frontend?
Вообще с программированием я познакомился довольно рано — в шестом классе. В библиотеке на полке попалась маленькая книжка по BASIC. Компьютера у меня тогда не было — он появился в классе девятом, может, даже в десятом. Но меня это настолько захватило, что я начал записывать программы в тетради. А по выходным ходил к соседу: пока мама была на рынке, у меня было пару часов, чтобы попробовать свои программы у него на компьютере. Это были мои самые первые шаги в программировании.
В школе, когда наконец появился компьютер, я стал пробовать более серьёзные языки — Delphi, C++, немного Assembler. А с веб-разработкой познакомился на первом курсе: у нас был полугодовой курс HTML, CSS и JavaScript. И меня сразу зацепило то, что результат виден моментально: сохранил файл, обновил страницу — и вот оно.
Расскажи про свои проекты в компании за последнее время. Какими гордишься? Какие были самыми сложными?
За второй приход в VK я успел поработать над четырьмя проектами. Первый — Календарь. Потом вместе с командой помогали ребятам с Заметками. После этого мы запустили новый продукт — Кошелёк. Проект был запущен за 3 недели: увеличили аудиторию с нуля до четырёх с половиной миллионов ежемесячной аудитории за восемь месяцев.
После этого мне предложили перейти в VK WorkSpace — в админку — развивать продукт и его техническую часть. Сейчас я работаю над VK WorkSpace и параллельно являюсь техлидом фронтенда в направлении SaaS Growth.
Задач очень много. Если говорить про продукт — это привлечение новых пользователей, развитие функциональности, удобные инструменты для управления доменами и продуктами внутри Workspace.
Если говорить про технические задачи — продукту больше десяти лет. Кодовая база большая, разные люди с разным подходом приходили и что-то добавляли. Накопилось много технического долга. Сейчас наша цель — перевести всё на современные рельсы, ускорить, сделать стабильнее, безопаснее, уменьшить затраты на поддержку.
Что считаешь важным, чтобы быть эффективным руководителем и не выгорать?
Есть один совет, которым со мной поделился другой человек. У многих людей продуктивность идёт волнами: то несёшься как локомотив, то падаешь в яму и становишься апатичным. И в такие моменты важно найти якоря — людей, эмоции, активности, — которые помогают выбраться. Честные, хорошие люди рядом дают огромный стимул жить дальше.
Если в жизни есть что-то приятное кроме работы, и вы на это не забиваете и не откладываете, — это помогает переживать стресс и ответственность. У меня есть несколько хобби. Одно из них — пешие прогулки по Москве. Люблю ходить по дворам, переулкам, тёмным проходам — просто интересно, что там. Могу телепортировать вас по центру из точки А в точку Б так, что вы не поймёте, как мы туда пришли.
#frontendvk #команда
Как ты выбрал программирование и frontend?
Вообще с программированием я познакомился довольно рано — в шестом классе. В библиотеке на полке попалась маленькая книжка по BASIC. Компьютера у меня тогда не было — он появился в классе девятом, может, даже в десятом. Но меня это настолько захватило, что я начал записывать программы в тетради. А по выходным ходил к соседу: пока мама была на рынке, у меня было пару часов, чтобы попробовать свои программы у него на компьютере. Это были мои самые первые шаги в программировании.
В школе, когда наконец появился компьютер, я стал пробовать более серьёзные языки — Delphi, C++, немного Assembler. А с веб-разработкой познакомился на первом курсе: у нас был полугодовой курс HTML, CSS и JavaScript. И меня сразу зацепило то, что результат виден моментально: сохранил файл, обновил страницу — и вот оно.
Расскажи про свои проекты в компании за последнее время. Какими гордишься? Какие были самыми сложными?
За второй приход в VK я успел поработать над четырьмя проектами. Первый — Календарь. Потом вместе с командой помогали ребятам с Заметками. После этого мы запустили новый продукт — Кошелёк. Проект был запущен за 3 недели: увеличили аудиторию с нуля до четырёх с половиной миллионов ежемесячной аудитории за восемь месяцев.
После этого мне предложили перейти в VK WorkSpace — в админку — развивать продукт и его техническую часть. Сейчас я работаю над VK WorkSpace и параллельно являюсь техлидом фронтенда в направлении SaaS Growth.
Задач очень много. Если говорить про продукт — это привлечение новых пользователей, развитие функциональности, удобные инструменты для управления доменами и продуктами внутри Workspace.
Если говорить про технические задачи — продукту больше десяти лет. Кодовая база большая, разные люди с разным подходом приходили и что-то добавляли. Накопилось много технического долга. Сейчас наша цель — перевести всё на современные рельсы, ускорить, сделать стабильнее, безопаснее, уменьшить затраты на поддержку.
Что считаешь важным, чтобы быть эффективным руководителем и не выгорать?
Есть один совет, которым со мной поделился другой человек. У многих людей продуктивность идёт волнами: то несёшься как локомотив, то падаешь в яму и становишься апатичным. И в такие моменты важно найти якоря — людей, эмоции, активности, — которые помогают выбраться. Честные, хорошие люди рядом дают огромный стимул жить дальше.
Если в жизни есть что-то приятное кроме работы, и вы на это не забиваете и не откладываете, — это помогает переживать стресс и ответственность. У меня есть несколько хобби. Одно из них — пешие прогулки по Москве. Люблю ходить по дворам, переулкам, тёмным проходам — просто интересно, что там. Могу телепортировать вас по центру из точки А в точку Б так, что вы не поймёте, как мы туда пришли.
#frontendvk #команда
🔥7❤4👏4🤩1🍾1
TypeScript шикарен, пока он типизирует обычный код. Но как только начинаешь писать сложную библиотеку на дженериках и типах в пару экранов, все очень быстро упирается в потолок.
Первый звоночек: рекурсивные типы.
Хочешь тип безопасного доступа по пути:
На простых структурах все будет ок, но как только путь или объект становятся глубже, начинают сыпаться
Вторая проблема: type safe роутинг через template literal types.
Кейс вроде:
решается, пишем парсер на template literal types, вытаскиваем все, что после :, собираем в объект, красота. Но как только добавляем ?, опциональные сегменты, вложенные роуты, query строки и прочее, типы начинают вести себя не так, как хотелось бы, ключи внезапно становятся опциональными, в углах появляются странные
Третья история про дженерики вокруг HOC, декораторов и прочих оберток.
В сложных обертках TypeScript часто уже не может нормально вывести типы и либо просит явные аннотации, либо сдается и льет
Формально оно типизировано, по факту же мы убеждаем компилятор отстать.
Причина простая: язык типов у нас почти как мини ЯП. Чем больше логики мы туда пихаем, тем тяжелее компилятору все это переваривать. Поэтому в TypeScript есть жесткие лимиты и компромиссы, иначе проверка типов занимала бы минуты.
Здравый подход такой, публичные API типизируем строго и аккуратно, все, что внутри, без фанатизма. Не делаем Haskell из TypeScript, но и не скатываемся в
#frontendvk #typenoscript
Первый звоночек: рекурсивные типы.
Хочешь тип безопасного доступа по пути:
type Get<T, Path> = /* ... */;
type Value = Get<{ a: { b: { c: number } } }, "a.b.c">;
// ожидаем number
На простых структурах все будет ок, но как только путь или объект становятся глубже, начинают сыпаться
Type instantiation is excessively deep and possibly infinite, компилятор упирается в лимиты по глубине рекурсии в типах и отказывается раскручивать их дальше.Вторая проблема: type safe роутинг через template literal types.
Кейс вроде:
route("/user/:id/post/:postId");
// хотим тип: { id: string; postId: string }
решается, пишем парсер на template literal types, вытаскиваем все, что после :, собираем в объект, красота. Но как только добавляем ?, опциональные сегменты, вложенные роуты, query строки и прочее, типы начинают вести себя не так, как хотелось бы, ключи внезапно становятся опциональными, в углах появляются странные
never, union раздуваются. В итоге получаются типы на сотни строк, IDE показывает простыню при наведении, любое изменение в формате роута может сломать пол апп по типам, и править все это страшнее, чем сам роутер.Третья история про дженерики вокруг HOC, декораторов и прочих оберток.
В сложных обертках TypeScript часто уже не может нормально вывести типы и либо просит явные аннотации, либо сдается и льет
any. Отсюда рождаются конструкции:
return something as unknown as SomeInsaneGenericType<...>;
Формально оно типизировано, по факту же мы убеждаем компилятор отстать.
Причина простая: язык типов у нас почти как мини ЯП. Чем больше логики мы туда пихаем, тем тяжелее компилятору все это переваривать. Поэтому в TypeScript есть жесткие лимиты и компромиссы, иначе проверка типов занимала бы минуты.
Здравый подход такой, публичные API типизируем строго и аккуратно, все, что внутри, без фанатизма. Не делаем Haskell из TypeScript, но и не скатываемся в
any.#frontendvk #typenoscript
✍4❤3👍2🔥2❤🔥1
Ранняя экспериментальная возможность рендерить HTML-элементы внутри <canvas>. Фича на стадии прототипа, но перспективна для интерактивных UI и визуализаций.
Интерактивный инструмент от Брамуса, позволяющий изучить поддержку и протестировать все части View Transitions API. Удобно для проверки кросс-браузерной совместимости.
Новое свойство field-sizing делает формы адаптивными — поля автоматически подстраиваются под введённый текст. Сейчас поддерживается только в Chromium-браузерах.
Разбор инцидента, где функция isOwner() в Next.js неожиданно вернула true из-за авто-преобразования в async. Подробно объясняется влияние Promise в условиях и подходы к тестированию server functions.
Подробное сравнение семантики элементов: встроенные возможности <button> (управление фокусом, клавиатурная навигация, доступность) против ручной реализации на <div>.
Как мы улучшили качество сервиса VK Видео на SmartTV
#дайджест #frontendvk
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥4❤3🥰1👀1
Всем привет. Сегодня мы познакомимся с Павлом Франковым, который отвечает за фронтенд vk.com. Обсудим, как формировать сильную команду: от правильного подбора людей до умения вовремя помочь и не доводить до выгорания.
➡️ C чего начиналась твоя карьера?
Всё началось с того, что я получил первый заказ на вёрстку сайта. А уже спустя много лет понял, что подсел — и теперь должен всё время этим заниматься.
Из того, что можно назвать крутым: я делал промо-сайты для компании Brother (это те ребята, которые производят МФУ). Эти проекты выставлялись на разных конкурсах и получали топовые награды. Конечно, большая заслуга дизайнера, но без аккуратной вёрстки ничего бы не получилось.
Потом я поработал с заказчиками из Кремниевой долины, прокачал английский с зарубежными командами. И там я понял одну важную вещь: никакая экспертиза не перевешивает несовместимость с командой. Сейчас первое, на что я смотрю, — это вайб-чек: насколько человек подходит конкретной команде.
➡️ Какие критерии?
Это именно «вайб» — совпадение взглядов, ценностей, отношения к делу. Например, мы в команде не воспринимаем работу как просто «работу» и ищем людей, которым действительно интересна наша область.
У нас в команде люди с подходящим майндсетом, и им не нужны короткие победы. Мы инфраструктурная команда, и у нас большинство задач долгие, результаты появляются не сразу. Им нормально, если большая победа придёт в конце. Мы стараемся отлавливать таких ребят ещё на собеседованиях — задаём вопросы, моделируем ситуации.
Например: мы ускоряем открытие ВКонтакте. Но на старте исследований невозможно предсказать, насколько быстрее он станет. Мы можем полгода копать в одном направлении, а в конце понять, что улучшений нет, а стало даже хуже. И результат выбрасывается. Поэтому нам нужны люди, готовые к долгому пути.
Это как с залом: если ты пришёл в качалку, нелогично ждать результата через две тренировки. Это история на год вперёд.
➡️ Что делать, когда желание есть, но сил на работу осталось совсем мало?
У меня в телеграм-канале есть пост на эту тему, который я постоянно кидаю всем друзьям: «Терпеть не надо». Если тебе приходится терпеть — это сигнал. И если что-то не нравится, надо обсуждать, решать, менять. У нас с ребятами есть договорённость: что бы ни происходило, они приходят и говорят. И мы попробуем перестроить планы, чтобы дать человеку выдохнуть.
У нас есть примеры, когда мы ребят специально ротировали, потому что видели, что им тяжело. Человек, который находится в состоянии «всё бесполезно», страдает сам и может повлиять на рабочие процессы во всей команде. Это не потому, что он плохой — просто он не на своём месте. Наша задача — найти этому человеку подходящее место. Это как пазл: неправильных людей нет, есть неправильно подобранные позиции. А если ни ротация, ни другие варианты не работают — то нужно уходить.
➡️ Как ты сам восстанавливаешься после работы?
Тут без сюрпризов: сон, прогулки, лёгкая физическая нагрузка. Лучше — регулярная и активная, чтобы пульс поднимался. Если беспокоит ментальное состояние — медитация. Headspace отлично подходит, там учат с нуля.
У меня много увлечений, и если я за что-то берусь, я прям ухожу в глубину. Сейчас я провожу ежедневные стримы, где «вайб-кожу» свой open source. У меня несколько проектов, суммарно на тысячу звёзд GitHub. Расскажу о паре из них.
Один — плагин для Obsidian (это как Notion, только локально). Там не было ИИ-инструментов — и я их сделал. Считаю, что на данный момент это самый лучший плагин.
Второй — инструмент-суммаризатор звонков под macOS. Неважно, Zoom, Telegram, VK, Google Meet — жмёшь «Записать», получаешь транскрипт и суммаризацию с выделенными экшен-айтемами.
Хороший отдых — это не обязательно резкая смена деятельности. Удивительным образом для меня отличным отдыхом может быть и программирование, просто в другом формате. И это всё равно помогает переключиться и потом оставаться продуктивным на работе.
#frontendvk #команда
Всё началось с того, что я получил первый заказ на вёрстку сайта. А уже спустя много лет понял, что подсел — и теперь должен всё время этим заниматься.
Из того, что можно назвать крутым: я делал промо-сайты для компании Brother (это те ребята, которые производят МФУ). Эти проекты выставлялись на разных конкурсах и получали топовые награды. Конечно, большая заслуга дизайнера, но без аккуратной вёрстки ничего бы не получилось.
Потом я поработал с заказчиками из Кремниевой долины, прокачал английский с зарубежными командами. И там я понял одну важную вещь: никакая экспертиза не перевешивает несовместимость с командой. Сейчас первое, на что я смотрю, — это вайб-чек: насколько человек подходит конкретной команде.
Это именно «вайб» — совпадение взглядов, ценностей, отношения к делу. Например, мы в команде не воспринимаем работу как просто «работу» и ищем людей, которым действительно интересна наша область.
У нас в команде люди с подходящим майндсетом, и им не нужны короткие победы. Мы инфраструктурная команда, и у нас большинство задач долгие, результаты появляются не сразу. Им нормально, если большая победа придёт в конце. Мы стараемся отлавливать таких ребят ещё на собеседованиях — задаём вопросы, моделируем ситуации.
Например: мы ускоряем открытие ВКонтакте. Но на старте исследований невозможно предсказать, насколько быстрее он станет. Мы можем полгода копать в одном направлении, а в конце понять, что улучшений нет, а стало даже хуже. И результат выбрасывается. Поэтому нам нужны люди, готовые к долгому пути.
Это как с залом: если ты пришёл в качалку, нелогично ждать результата через две тренировки. Это история на год вперёд.
У меня в телеграм-канале есть пост на эту тему, который я постоянно кидаю всем друзьям: «Терпеть не надо». Если тебе приходится терпеть — это сигнал. И если что-то не нравится, надо обсуждать, решать, менять. У нас с ребятами есть договорённость: что бы ни происходило, они приходят и говорят. И мы попробуем перестроить планы, чтобы дать человеку выдохнуть.
У нас есть примеры, когда мы ребят специально ротировали, потому что видели, что им тяжело. Человек, который находится в состоянии «всё бесполезно», страдает сам и может повлиять на рабочие процессы во всей команде. Это не потому, что он плохой — просто он не на своём месте. Наша задача — найти этому человеку подходящее место. Это как пазл: неправильных людей нет, есть неправильно подобранные позиции. А если ни ротация, ни другие варианты не работают — то нужно уходить.
Тут без сюрпризов: сон, прогулки, лёгкая физическая нагрузка. Лучше — регулярная и активная, чтобы пульс поднимался. Если беспокоит ментальное состояние — медитация. Headspace отлично подходит, там учат с нуля.
У меня много увлечений, и если я за что-то берусь, я прям ухожу в глубину. Сейчас я провожу ежедневные стримы, где «вайб-кожу» свой open source. У меня несколько проектов, суммарно на тысячу звёзд GitHub. Расскажу о паре из них.
Один — плагин для Obsidian (это как Notion, только локально). Там не было ИИ-инструментов — и я их сделал. Считаю, что на данный момент это самый лучший плагин.
Второй — инструмент-суммаризатор звонков под macOS. Неважно, Zoom, Telegram, VK, Google Meet — жмёшь «Записать», получаешь транскрипт и суммаризацию с выделенными экшен-айтемами.
Хороший отдых — это не обязательно резкая смена деятельности. Удивительным образом для меня отличным отдыхом может быть и программирование, просто в другом формате. И это всё равно помогает переключиться и потом оставаться продуктивным на работе.
#frontendvk #команда
Please open Telegram to view this post
VIEW IN TELEGRAM
👏8❤6🔥4🥰1🎉1
Обычная подсветка кода в браузере устроена довольно грубо. Берем строку, режем на токены и каждое слово заворачиваем в
CSS Custom Highlight API делает то же самое, но без этого спамом по DOM. Текст остается одной текстовой нодой, вообще без оберток. Просто сообщаем браузеру, что вот тут у нас ключевые слова, вот тут строки, вот тут комментарии. В коде это обычные
Стили выглядят почти как обычный CSS, только вместо классов
А в JS логика довольно простая, берем текстовую ноду, гоняем по коду свой лексер, создаем
Идея в том, что мы перестаем собирать ёлку из
#frontendvk #range #css #javanoscript
span с классом: keyword, string, operator и т.д. На экране красиво, а вот в коде сотни и тысячи маленьких DOM-узлов. Браузеру все это нужно разобрать, разложить, покрасить, держать в памяти. На больших доках или код-ревью это прям ощутимо, особенно если таких блоков много.CSS Custom Highlight API делает то же самое, но без этого спамом по DOM. Текст остается одной текстовой нодой, вообще без оберток. Просто сообщаем браузеру, что вот тут у нас ключевые слова, вот тут строки, вот тут комментарии. В коде это обычные
Range объекты, которые ссылаются на позиции в тексте. Дальше регистрируем их через CSS.highlights, а все оформление уже описываем в CSS.Стили выглядят почти как обычный CSS, только вместо классов
::highlight:
::highlight(keyword) {
color: #0000ff;
font-weight: bold;
}
::highlight(string) {
color: #a31515;
}
А в JS логика довольно простая, берем текстовую ноду, гоняем по коду свой лексер, создаем
Range для каждого токена и группируем их по типу:
function applyHighlighting(element: HTMLElement, code: string) {
if (!CSS.highlights) return; // фоллбек для старых браузеров
const textNode = element.firstChild;
if (!textNode || textNode.nodeType !== Node.TEXT_NODE) return;
const tokens = lexTypeScript(code);
const byType = new Map<string, Range[]>();
for (const token of tokens) {
const range = new Range();
range.setStart(textNode, token.start);
range.setEnd(textNode, token.end);
const list = byType.get(token.type) ?? [];
list.push(range);
byType.set(token.type, list);
}
for (const [type, ranges] of byType) {
CSS.highlights.set(type, new Highlight(...ranges));
}
}
Идея в том, что мы перестаем собирать ёлку из
span ради подсветки. Браузеру даем только текст и информацию что где лежит, а красит он уже сам. Плюсом в проде лучше бы еще убирать хайлайты при удалении блока. Для маленького сниппета разницы почти не видно, но если куча примеров кода на странице, такой вариант заметно приятнее по ресурсам и не превращает DOM в свалку.#frontendvk #range #css #javanoscript
🔥14❤4👏3🤩1🍾1
Сегодня среднее дневное время смотрения VK Видео на Smart TV достигает 216 минут. При этом на большом экране качество видео часто портится — всё зависит от производителя и настроек. Рассказываем с помощью карточек, как мы решали эту и другие проблемы. Больше подробностей — по ссылке.
#frontendvk #vkвидео
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6🔥5👍3💯1🤝1
Когда в веб-приложении много контента, браузер тратит кучу времени на расчет стилей и лэйаута даже для тех узлов, которые сейчас вне экрана. CSS-параметр
Как применять: разбиваем длинную страницу на секции и ставим им
Есть и нюанс. При использовании
Пока секция не отрисована, браузер будет считать, что она занимает 1000px высоты (можно указать и ширину, если нужно).
#frontendvk #css #contentvisibility
content-visibility позволяет радикально ускорить начальную отрисовку за счёт пропуска рендеринга невидимых элементов. Если элемент расположен за пределами видимой области, и ему задано content-visibility: auto, браузер вообще не будет его рендерить до тех пор, пока он не появится в зоне видимости при скролле.Как применять: разбиваем длинную страницу на секции и ставим им
content-visibility: auto. В HTML всё по-прежнему присутствует, но невидимые секции практически заморожены для движка рендеринга. Как только пользователь доскроллит до секции, она автоматически рендерится. В демо от Google применение content-visibility: auto на длинной статье дало ускорение отрисовки начального экрана в ~7 раз – страница показывается мгновенно, остальное рисуется по мере прокрутки.Есть и нюанс. При использовании
content-visibility элемент ведёт себя как будто с contain: layout paint, то есть полностью изолирован. Нужно задать примерный размер невидимому элементу, иначе браузер не зарезервирует под него место и при появлении контента страница может скакнуть. Для этого есть свойство-компаньон contain-intrinsic-size. Например, если примерно знаете, что секция высотой около 1000px, можно написать:
.section {
content-visibility: auto;
contain-intrinsic-size: 1000px;
}
Пока секция не отрисована, браузер будет считать, что она занимает 1000px высоты (можно указать и ширину, если нужно).
content-visibility — относительно новая фича CSS, уже поддерживается во всех современных браузерах. Хорошо подходит для приложений с большим количеством контента: длинные списки, фиды, комментарии. Без лишних сложностей виртуализации получается ленивая отрисовка всего, что сейчас не видно, почти автоматически. Главное, не забудьте про размер контейнера.#frontendvk #css #contentvisibility
❤16🔥8👍5❤🔥1👏1
Движки JavaScript делают хитрые оптимизации, чтобы динамичный JS работал быстрее. Одна из фич V8 – это Hidden Classes, также известные как shape объекта. Когда вы создаете объект в JS, например через класс или литерал, V8 подмечает, какие свойства в нем и в каком порядке были добавлены, и присваивает ему скрытый класс, своего рода шаблон структуры. Если потом создаются другие объекты с таким же набором свойств в том же порядке, они могут использовать один скрытый класс. Это хорошо, ведь двигателю легче JIT-компилировать доступ к свойствам и прочие оптимизации.
Если объекты одной логической сущности у вас создаются с разной структурой, оптимизация рушится. Например:
В зависимости от входных данных объект
Теперь у всех объектов
Другой совет в том, чтобы инициализировать все свойства объекта в конструкторе. В классах это значит: выпишите в
Создавайте объекты предсказуемо, избегайте разнородных структур, не добавляйте свойства после создания объекта, если можно этого не делать. Тогда движок подстроится под ваш код и будет исполнять его близко к скорости языка со статической структурой объектов.
#frontendvk #javanoscript
Если объекты одной логической сущности у вас создаются с разной структурой, оптимизация рушится. Например:
// Плохо: свойства добавляются динамически
function makeUserDynamic(data) {
const user = {};
if (data.name) user.name = data.name;
if (data.age) user.age = data.age;
return user;
}
В зависимости от входных данных объект
user может получить разные наборы свойств. Для каждого варианта V8 создаст отдельный hidden class. А вот если вы заранее зададите все потенциальные поля, будет лучше:
// Хорошо: предсказуемая форма
function makeUser(data) {
return {
name: data.name || null,
age: data.age || null
};
}
Теперь у всех объектов
user одна и та же структура, и двигатель использует один скрытый класс на всех, код выполняется быстрее, память используется экономнее.Другой совет в том, чтобы инициализировать все свойства объекта в конструкторе. В классах это значит: выпишите в
constructor все поля, даже необязательные, со значением по умолчанию. Если потом добавить новое свойство на ходу объекту, это создаст новую версию скрытого класса, и доступ к такому свойству будет медленнее. Удаление свойств тоже ведёт к изменению shape и потере оптимизаций, лучше избегать delete, вместо этого присвоить undefined или null при надобности.Создавайте объекты предсказуемо, избегайте разнородных структур, не добавляйте свойства после создания объекта, если можно этого не делать. Тогда движок подстроится под ваш код и будет исполнять его близко к скорости языка со статической структурой объектов.
#frontendvk #javanoscript
👍12✍8❤2🔥1🦄1
Есть малоизвестное CSS‑свойство —
ㅤㅤ
Например, если обернуть сторонний виджет в контейнер с
ㅤㅤ
ㅤㅤ
Если включить
ㅤㅤ
ㅤㅤ
#frontendvk #CSS #contain
contain, позволяющее изолировать часть страницы, как будто она в <iframe>. Вы объявляете у родительского элемента что‑то вроде contain: strict; и браузер старается держать его содержимое независимым от остальной страницы. Изменения внутри изолированного блока не трогают внешний layout, и наоборот.ㅤㅤ
Например, если обернуть сторонний виджет в контейнер с
contain: strict, то тяжелые перестройки внутри виджета не будут заставлять перерисовывать всю страницу. Браузер ограничит перерасчёт стилей и компоновки только этой областью, что может существенно ускорить рендеринг больших приложений.ㅤㅤ
contain поддерживает несколько вариантов изоляции: layout, paint, style, size, и их комбинации, плюс шорткаты strict и content. Например, contain: layout создаёт новый локальный контекст компоновки, внешние элементы не влияют на внутреннее размещение и наоборот. contain: paint изолирует отрисовку, потомки не выходят за границы контейнера, элемент создаёт свой стек контекста наложения (задает новый контекст для z‑index и позиции fixed внутри него). contain: size вовсе отрывает размеры контейнера от содержимого, внешняя разметка не знает насколько большой внутри элемент.ㅤㅤ
Если включить
size, у контейнера должны быть заданы размеры явно. Иначе содержимое может вылезти или контейнер схлопнется, ведь браузер не будет учитывать дочерние элементы при расчёте размеров. Кроме того, изолированный блок всегда создаёт новый стек контекста. Это может повлиять на поведение всплывающих элементов или модалок внутри него — имейте в виду.ㅤㅤ
contain — мощный инструмент оптимизации, просто применяйте осознанно: изолируйте сложные виджеты, оффскрин‑элементы, но не злоупотребляйте там, где это не требуется.ㅤㅤ
#frontendvk #CSS #contain
👍12❤7🍾3💯1👾1
Классический кейс: вы удалили узел из DOM, но где‑то осталась ссылка на него в JS. В результате элемент становится «detached», но не сборяется сборщиком мусора, потому что на него по‑прежнему есть живая ссылка. Например:
let div = document.createElement('div');
document.body.appendChild(div);
document.body.removeChild(div);
// Элемент удалён из DOM, но div всё ещё в памяти,
// так как переменная div ссылается на него
Если открыть Chrome DevTools и сделать Heap Snapshot памяти, подобные утечки видно как объекты «Detached HTMLDivElement». Они занимают память и могут накапливаться, если вы, скажем, кэшируете DOM‑элементы в структурах данных и не очищаете, или подписались на событие и забыли отписаться — элемент уже удалён из документа, а колбэк всё ещё ссылается на него. Еще часто ловят утечки из‑за неудалённых обработчиков событий, навесили listener на элемент, удалили элемент, а обработчик забыли снять. Он сохраняет в замыкании кучу данных, и всё это продолжает висеть в памяти.
Как бороться
Во‑первых, следите за обработчиками — используйте
{ once: true } где нужно одноразово, или вручную removeEventListener при очистке UI.Во‑вторых, избегайте глобальных переменных, хранящих DOM‑элементы или большие объекты — ограничьте их область жизни. Для кэшей используйте WeakMap/WeakRef, тогда сборщик мусора сможет прибирать за вами неиспользуемые объекты.
В‑третьих, периодически профилируйте память приложения. DevTools умеет показывать ретейнеры — кто держит ссылку на утёкший объект. Так вы выясните, откуда «торчат» лишние ссылки. Иногда помогает паттерн: после удаления DOM‑узла занулить все ссылки на него (например, присвоить переменной
div = null). Это подскажет GC, что объект больше не нужен.В React, Vue и так далее утечки тоже возможны, например, если вручную манипулировать DOM вне их контроля или хранить состояние вне реактивности. В целом, профилактика утечек — часть культуры грамотной разработки.
#frontendvk #javanoscript #domузлы
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18❤3⚡2🤔2🤗1