Обновить
256K+

JavaScript *

Прототипно-ориентированный язык программирования

269,09
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Offline‑first PWA на примере фитнес‑трекера

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели1.1K

Привет, меня зовут Сергей Цибульченко, я fullstack‑разработчик. На хабре уже есть несколько статей про PWA, но они не раскрывают всех подводных камней данной технологии, я с этим лично столкнулся когда делал пет‑проект по этим статьям.

Для начала, что такое PWA? Это веб‑страница которая выглядит и ведёт себя как приложение, но при этом имеет технические ограничения веб‑страницы.

Читать далее

Новости

Сложные сайты на вайбкоде: четыре лендинга, два пути к «дорогим» эффектам и 3D-логотип из спрайтов

Время на прочтение22 мин
Охват и читатели8.1K

TL;DR

За последний год я собрал вайбкодингом не один десяток лендингов — для программ МФТИ, для своих проектов и на заказ. Разберу четыре самых показательных: Школу Техпреда, конференцию «Точка сборки», курс «ИИ Продакт-менеджмент» (aimipt.ru) и один свой, личный — на нём эффекты раскачаны сильнее всего.

У всех четырёх есть слой «дорогих» визуальных эффектов: интерактивная вода на WebGL-шейдере с освещением, 3D-логотип Физтеха из тысяч частиц-спрайтов, живая 3D-башня из кубов, облако частиц, которое морфит форму по скроллу.

К этому слою я пришёл двумя разными путями. На «Точке сборки» эффекты написаны руками на чистом WebGL — ноль анимационных библиотек. На остальных работает свой движок на Three.js: вынесен отдельными файлами, переиспользуется между сайтами и откатывается на 2D-canvas, если CDN не ответит.

Ниже — оба пути на реальном коде, цепочка инструментов от дизайн-системы до прода и грабли, на которые я наступил.

Читать далее

Фронтенд умер? Нет, но AI уже держит лопату

Уровень сложностиПростой
Время на прочтение7 мин
Охват и читатели7K

Привет, на связи Рома Миронов из Авито. Я бывший — хотя бывших не бывает — фронтендер, а сейчас тим- и техлид. Ковыряю AI и больше ничем не занимаюсь — кроме команды, конечно :) В этой статье расскажу, почему фронтенд пока не умер, какие задачи уже можно отдавать агентам, где они красиво ошибаются и почему сначала от AI становится больнее, а не легче.

Читать далее

Картинка грузится, а fetch к тому же хосту — нет: как CSP тихо сломала три интеграции

Уровень сложностиСредний
Время на прочтение4 мин
Охват и читатели7.1K

Полгода назад я закрыл замечание аудита «на сайте нет CSP» — прописал
Content‑Security‑Policy с белым списком хостов, проверил, что ничего не
отвалилось, и забыл. За три дня на прошлой неделе я нашёл три интеграции,
которые эта политика убила молча. Ни одна из них не оставила следа на сервере.

Страница, которая называет себя «в реальном времени», показывала одно и то же
число десять секунд подряд — и показывала так всем, с того самого дня, как я
включил CSP.

Это заметка про то, почему такие поломки не видно, и про скрипт, который
находит их все сразу.

Читать далее

AAA Движок для GTA San Andreas в браузере и переписывание ThreeJS

Уровень сложностиПростой
Время на прочтение6 мин
Охват и читатели8.2K

Данная статья - это продолжение повествования о том, как я делаю AAA-движок для запуска старых игр, а именно GTA San Andreas и её модов, в браузере. В ней речь пойдет о том, как я уперся в производительность Three.js и перевел движок на свой фреймверк под WebGPU.

Читать далее

Мой опыт онбординга разраба с амнезией

Уровень сложностиСредний
Время на прочтение6 мин
Охват и читатели9.6K

Давай признаем, ты чуть ли не 90% кода пишешь с помощью клода, кодекса или еще какого агента. Ты выпускаешь несколько мр-ов в день, пушишь несколько тысяч строк кода, и быстро просматриваешь псевдо код на ревью, чтобы доказать самому себе, что это действительно ты напряг мозг и сделал задачу. Ты делаешь ровно то, что и всегда, думая, что агент просто ускоряет цикл разработки, который ты проводил ежедневно.

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

Читать далее

Статичный сайт с Vite + Caddy + Docker: пошаговое руководство

Уровень сложностиПростой
Время на прочтение4 мин
Охват и читатели6.6K

В данной статье будет подробно рассмотрен полный цикл деплоя сайта, используюшего Vite в качестве инструмента сборки. Мы напишем многоступенчатый Dockerfile, чтобы собрать образ с готовой статикой, и поднимем контейнер с сервером Caddy, который автоматически выдаст и будет обновлять сертификаты Let's Encrypt.

Читать далее

Хакатон — соло игра за 2 дня на Fable 5 и Nano Banana 2

Время на прочтение7 мин
Охват и читатели13K

Поучаствовал в хакатоне от работы. Интересно было испытать себя и проверить свой тулсет для разработки игр. Смогу ли я один сделать игру под ключ - код, арт, звуки?

Штош, игру сделал! Правда лег спать около шести утра 😖 Но это было интересно!

Внутри ссылка на игру и немного технических подробностей как генерил арт, код и собирал игру

Читать далее

История о том, как я написал компилятор Svelte на Rust

Уровень сложностиСредний
Время на прочтение14 мин
Охват и читатели12K

У нас тормозило всё: сборка, дев-сервер, svelte-check, LSP. Я пошёл писать свой компилятор Svelte на Rust. Пять с половиной месяцев ковырял руками и бросил. Через год вернулся с ИИ-агентом и доделал за 106 вечеров и $700.

Как это было

ИграКОД: Генератор судоку на TypeScript: почему найти решение проще, чем доказать единственность

Уровень сложностиСредний
Время на прочтение8 мин
Охват и читатели9.2K

Главная ошибка наивного генератора судоку — проверять, что решение существует, но не проверять, что оно единственное.

Вот почти заполненное поле:

534..8912 672195348 198342567 859..1423 426853791 713924856 961537284 287419635 345286179

solve() быстро заполнит четыре пропуска. Только завершений здесь два: цифры 6 и 7 можно переставить, не нарушив ни строку, ни столбец, ни блок.

countSolutions(puzzle, 2) останавливается после второго решения и возвращает 2.

Это не демонстрационная картинка. Та же строка из 81 символа лежит в solver.spec.ts, тест так и называется: «контрпример из лида действительно имеет два решения».

Я реализовал три стратегии поиска, а MRV и propagation дополнительно сравнил на наборах задач. Ещё измерил две операции: получение первого решения и доказательство того, что второго решения нет. Вторая вызывается после каждой попытки убрать подсказку, поэтому она в основном определяет цену генерации. React, Web Worker и тесты появятся дальше как обвязка этого поиска, а не как отдельные темы.

Это первый выпуск рубрики «ИграКОД» — про алгоритмы через запускаемые мини-игры. Ранее в цикле выходили материалы про useEffect, any, перенос TypeScript на Go, варианты архитектуры React-магазина и мы собирали и разбирали комбайн.

Читать далее

Как мы несколько дней искали проблему с перемоткой WebM

Уровень сложностиПростой
Время на прочтение8 мин
Охват и читатели10K

В одном из наших проектов бот записывает видеовстречи из Яндекс Телемоста, сохраняет их в WebM и передаёт на backend. После обработки запись становится доступна пользователю и воспроизводится через Video.js.

Заметили что при перемотке длинных файлов видеоплеер надолго задумывается. Браузер продолжает загружать данные, буфер визуально заполняется, но воспроизведение не начиналось.

Сначала мы исправили MIME-тип. Затем изменили настройки плеера. Потом ограничили ответы бека чанками по 50 МБ. Ничего из этого не помогло.

Настоящая причина находилась не на фронте и не на беке, а в самом WebM.

Читать далее

<usermedia> — новый HTML элемент

Уровень сложностиПростой
Время на прочтение7 мин
Охват и читатели13K

Вместо запросов, которые вызываются из JavaScript, <usermedia> предлагает декларативный подход, при котором действие инициирует сам пользователь. Это позволяет сократить объём шаблонного кода, повысить безопасность и упростить повторный запрос доступа для пользователей, которые ранее его запретили. Тем самым элемент решает давнюю проблему, связанную с восстановлением отклонённых разрешений.

Читать далее

Как я написал собственный Event Bus на JavaScript

Уровень сложностиПростой
Время на прочтение6 мин
Охват и читатели6.8K

Эта статья не претендует на создание полноценной замены Node.js EventEmitter или других готовых библиотек. Цель — разобраться, как устроен Event Bus и написать собственную минимальную реализацию.

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

И решил я написать свою систему коммуникации модулей.

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

const Emitter = () => {}

Начало положено. Именно эта функция будет представлять всю систему.

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

Например, у нас есть приложение todo list. У него есть кнопка "Добавить задачу". Нам нужно сделать так, чтобы при клике на неё:

Читать далее

Ближайшие события

Memorization vs Generalization: что действительно умеет языковая модель (TLM) на 2 160 параметров (v1.1.0)

Уровень сложностиСредний
Время на прочтение2 мин
Охват и читатели6.8K

Продолжая тему Крошечной Языковой Модели на Nodejs мы поймем где проходит граница ее возможностей. На примере Крошечной Языковой Модели (TLM) из 2 160 параметров мы проведём воспроизводимый эксперимент и увидим в цифрах: знакомый шаблон - 99,93%, перестановка токенов - 81,69%, неизвестная структура -?%.

Читать далее

Next.js, localStorage в App Router без hydration-ошибок

Время на прочтение7 мин
Охват и читатели7.2K

localStorage существует только в браузере. App Router может подготовить HTML на сервере и для Client Component. Код с директивой use client получает состояние, эффекты и обработчики событий, но первый рендер всё ещё может пройти без window и localStorage. И возникают два сбоя. Прямое чтение localStorage падает на сервере. Проверка через typeof window возвращает разные данные на сервере и в браузере. Сервер строит пустое избранное, браузер видит сохранённые id, React получает разные деревья при hydration.

Читать далее

Реальная и мнимая многопоточность в JS

Уровень сложностиСредний
Время на прочтение8 мин
Охват и читатели8.1K

JS — однопоточный язык, но асинхронный код нередко описывают как «выполняющийся параллельно» — и это не совсем так. В статье разберёмся, что на самом деле происходит, когда вы вызываете fetch или setTimeout, и почему настоящая многопоточность в браузере — это отдельная история про Web Workers, а не про промисы.

Читать далее

Как получить пожизненный бан на VC.ru за open-source проект на Node.js без рекламы. Кейс CMTT

Уровень сложностиПростой
Время на прочтение2 мин
Охват и читатели13K

Всем привет. На днях моя техническая статья с open source кодом про написание нейросети с нуля на Node.js вышла из песочницы Хабра благодаря НЛО, набрала 8K+ просмотров и получила крутой фидбек. Но за 2 дня до этого я решил провести эксперимент и выложить этот же материал на VC.ru. Итог — моментальный пожизненный бан без объяснения причин в первые 15 минут…

Читать далее

Широкий вход, узкий выход: Vue 3 внутри jQuery‑формы без бесконечных циклов

Уровень сложностиСредний
Время на прочтение14 мин
Охват и читатели8.5K

Добавить на страницу новые функции, не трогая саму страницу, звучит как противоречие. Но альтернативу мы посчитали командой: полное переписывание заняло бы год, в течение которого страница не получила бы ни одной новой функции. Мост между старым кодом и новым занял два месяца, и строил его уже я один. Расскажу, как этот мост устроен, почему получился несимметричным, где чуть не зациклился и что в нём так и осталось кривым.

Читать далее

Чат на сайте стоит дороже, чем кажется: как я замерил его цену и переписал виджет под результат

Уровень сложностиСредний
Время на прочтение12 мин
Охват и читатели6.2K

Полгода назад я закрывал технический долг по производительности на клиентском проекте. Обычная история: интернет‑магазин, мобильный Performance в PageSpeed — 29, владелец каждую неделю спрашивает, когда будет зелёная зона. Мы сделали всё, что делают в таких случаях. Перегнали изображения в WebP и AVIF, вынесли критический CSS в инлайн, убрали три подключения Google Fonts на self‑host, порезали неиспользуемый JavaScript, настроили кэширование на уровне Nginx, подключили CDN. Работы на два месяца.

Мобильный Performance стал 31.

Я открыл трейс в DevTools, развернул Main thread и минут пять просто смотрел. Больше половины длинных задач на главном потоке не имели никакого отношения к сайту. Это был чат.

Дальше начинается то, ради чего написана статья. Я задал себе вопрос, который до этого не задавал ни разу за десять лет работы: а сколько вообще стоит чат на сайте? Не в рублях в месяц — в миллисекундах. И обнаружил, что честного ответа нет ни у кого. Вендоры публикуют вес загрузочного скрипта, обычно 8–15 КБ, и это правда ровно настолько, насколько правдива фраза «билет на самолёт стоит 40 долларов» без учёта багажа, сборов и трансфера. Lighthouse показывает общий счёт по странице и не выставляет его отдельным подрядчикам. Владелец сайта видит красную цифру и не знает, чья она.

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

Читать далее

Модель исполнения JavaScript по спецификации ECMAScript: call stack, контексты, окружения и замыкания

Уровень сложностиСложный
Время на прочтение23 мин
Охват и читатели7K

Я довольно долго был уверен, что понимаю, как работает call stack.

Ну а что там понимать? Положил кадр, снял кадр, LIFO.

Потом открыл спецификацию. Оказалось, за «стеком вызовов» стоит каркас из пяти сущностей, а половина привычных объяснений просто не совпадает с текстом стандарта.

Замыкание — не фича языка, а побочный эффект того, что окружение живёт отдельно от кадра. «Область видимости» — вообще не сущность: такого термина там нет. А слов event loop, microtask и task queue в ECMA-262 ровно ноль. Проверяется грепом за минуту.

Разбираю модель исполнения по первоисточнику: агент, контекст, окружения, джобы. Каждое утверждение сверено с текстом стандарта, номера параграфов проставлены — можно перепроверять за мной.

Разобрать по спецификации
1
23 ...