Будни разработчика
14.6K subscribers
1.19K photos
347 videos
7 files
2.04K links
Блог Lead JS-разработчика из Хельсинки
Автор: @bekharsky

По рекламе: https://telega.in/channels/htmlshit/card?r=GLOiHluU или https://t.iss.one/it_adv

Чат: https://t.iss.one/htmlshitchat

№5001017849, https://www.gosuslugi.ru/snet/679b74f8dad2d930d2eaa978
Download Telegram
#автор дня

Итак, я не так давно, буквально пару месяцев назад, выкладывал репозиторий Сергея Ufocoder'а, посвящённый утечкам памяти в JavaScript. Ну, вот же, положила: https://t.iss.one/htmlshit/2668

Думаю, сегодня можно выложить кое-что ещё :)

Некоторое время Сергей занимается разработкой простого FPS. И пришло время показать первые результаты!

Собственно, перед нами однопользовательская игра в стиле Wolfenstein 3D.

Использует подход к отрисовке графике из 1990-х, в частности алгоритм raycasting (все графические вычисления происходят на CPU).

Написана с нуля, то есть без использования сторонних библиотек.

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

Если появится желание улучшить игру, то ее исходники находятся в открытом виде и автор приветствует любые улучшения и исправления.

Репозиторий: https://github.com/ufocoder/fps
Играть: https://ufocoder.github.io/fps/

Если вы, котаны, задались целью понять, как работают 3D-движки на базовом уровне — это вот самое то :)

P. S. а 15 июня у него будет стрим про разработку этой самой игры

#game #fps
👍184
This media is not supported in your browser
VIEW IN TELEGRAM
#инструмент дня

React Compiler, говорите...

А что если я скажу вам, что есть инструмент, конвертирующий ваши JSX-компоненты во... во все остальные?

Буквально: JSX/Svelte в: React, Svelte, Vue, Angular, Qwik, Lit, Solid, Preact...

Давайте просто сразу дам ссылку на песочницу: https://mitosis.builder.io/playground/

Если уж и не для практического применения, но если вдруг надо срочно пересесть на другой фреймворк — то понять принципы можно с лёгкостью.

Знаешь JSX или Svelte — пишешь на всех :)

#framework #tool
👍12🤩4
#такое дня

Я знаю, вы любите стыдный контент.

После трёх релизов подряд, в которых не было ничего, кроме исправления z-index (не спрашивайте), проверяющий мои PRы бакендщик (остальные в отпуске), заметил:

— Я-то хотя бы жисоны перекладываю...

Давайте ваши свежие стыдные истории, котаны.
🤩14👍64👎1
#статья дня

Я много раз начинал и забрасывал статью о том, как справляться с рутиной. Но писать статью — это не в чате «деда» включать. Всё-таки важная штука — аудитория.

Впрочем, здесь мне помогут Александр Беспоясов, Вадим Юмадилов и Андрей Романов. Фамилия Беспоясова должна быть вам знакома – он отметился в Солидбуке.

Итак, какие вопросы разбираются в их лонгриде Фронтенд — это не больно:
— Как решать задачи, а не писать код
— Как не умереть в пиксель-перфекте
— Как вести диалог с дизайнерами

Можно, конечно, просто посоветовать перестать ныть и начать вникать, но это будет слишком грубым описанием этой прекрасной работы.

И обязательно обратите внимание на прикреплённые к статье материалы. В них есть всё.

#work #frontend #psychology #бородач
👍12
#фишка дня

Иногда встаёт задача не просто проиллюстрировать статью, но обрезать (кропнуть) исходное изображение. И желательно так, чтобы результат был адаптивен и адекватно реагировал на масштабирование.

Джейк Арчибальд предлагает решение на SVG и foreignObject: https://codepen.io/alinaki/pen/KKLXvwz

Вообще, весьма красиво. Да, можно генерировать кропы на сервере, но это, как минимум, лишние телодвижения. А тут – одна картинка, чистый и понятный код.

#svg #img #foreignObject #crop
👍11
#такое дня

Не, не могу молчать. Андрей Ситник снова пошёл священной претензией на сообщество фронтенда.

И снова с Линуксом.

Итак, суть подачи: «Во фронтенде бесит, что люди так много говорят про diversity и адаптивность к разным системам, а все сидят на Маках».

Начнём с того, что не все сидят на маках, но все, кто выступает на конференциях 🙂 Ошибка выжившего как она есть.

А дальше... давайте сначала ваше мнение, котаны. Выше — опрос про вашу ОС для работы.

Если вам будет интересно — напишу свой путь и выбор инструментов.
👍3🤩1
#ретро дня

В комментариях к предыдущему посту встал вопрос: "А как тестировать Safari в Windows и Linux?"

Что ж, на этот вопрос есть частичный ответ. И пару лет назад я делал серию постов, посвящённую этой проблеме.

TL;DR: Safari не единственный браузер на WebKit, есть ещё Epiphany aka GNOME Web. И если на Linux он вполне себе нативно запускается, то на Windows нужно немного плясок.

Собственно, посты из серии:

Краткая история Safari: https://t.iss.one/htmlshit/704
Установка GNOME Web на Windows WSL2: https://t.iss.one/htmlshit/709
Использование WebKit Demo Browser через Playwright: https://t.iss.one/htmlshit/714
Просто готовая сборка WebKit: https://t.iss.one/htmlshit/715

Если кто попробует и дополнит инструкцию — я буду очень рад 🥺

P. S. там же есть инфа, как получить бесплатный доступ к сервису Browserstack: https://t.iss.one/htmlshit/718
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
#такое дня

Теперь, когда вас попросят на собеседовании написать код, который выводит сам себя — вы знаете, что делать:

($=_=>`($=${$})()`)()


Послать нафиг, конечно же

#js #бородач
🤡11👍8🤩4
#заметка дня

Тут Иван Акулов из Framer поделился, как они доставляют AVIF-изображения, добиваясь ещё большей, чем WEBP, экономии трафика.

Да, я в курсе, что многие генерируют картинки при сборке, кто-то использует сервисы и так далее, но давайте не забывать, что:
1. Есть пользовательский контент
2. Облака могут встать дорого

Итак, в чём же проблема? А в том что AVIF ну очень долго кодируется, что не есть хорошо. Там, где на генерацию WEBP уйдёт 100-300 мс, на AVIF — 1-3 секунды.

В итоге, если генерировать изображения по запросу и сохранять на CDN (тем же nginx, например), будет не очень вежливо заставлять посетителя ждать.

Поэтому было решено применять подход, знакомый нам как stale-while-revalidate.

1. С первым запросом генерируем WEBP-картинку, но устанавливаем кеширующие заголовки как Cache-Control to max-age=0, stale-while-revalidate=31536000.
2. Поскольку max-age выставлен в 0, картинка моментально "протухнет", CDN с этим не согласится и отправит второй запрос, чтобы, собственно, закешировать.
3. И вот тут уже начинаем генерировать AVIF.
4. И отправляем его с max-age=31536000, ну, почти навсегда.

Ну и общая статья на тему: https://www.framer.com/help/articles/how-are-images-optimized-in-framer/

Я тут пока готовил этот обзор, хотел найти свой конфиг nginx для генерации и кропа картинок на лету, но... потерял. Кажется, пришло время потренироваться и написать обновлённый, по мотивам.

А как вы доставляете картинки, котаны?

#image #optimization
👍106
#такое дня

Олды тут?

Волновало ли вас мнение разработчиков-зумеров о вашем подходе к работе?

Спойлер: нет.

А вот Gergely Orosz (я боюсь это транслитерировать) решил собрать мнение обеих сторон, и людей старшего поколения о молодом, и наоборот.

И выпустил две огромные статьи:

GenZ глазами миллениалов и GenX
https://newsletter.pragmaticengineer.com/p/genz

Миллениалы и GenX глазами GenZ:
https://newsletter.pragmaticengineer.com/p/genz-part-2

Поскольку мне аж 36 лет, и я смотрел доклад 36 два раза, иллюстрацией к этому посту я выбрал именно выводы из второй части.

Поиграем в бинго, олды? У меня пять из шести.

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

Впрочем, гораздо большую роль, на мой взгляд, играет культурный бэкграунд.

#life
👍4
#статья дня

Давай сегодня тему пошире. Если ты работаешь с проектами крупнее одного лендинга за раз, или более того — с продуктами, резко встаёт вопрос целесообразности внедрения той или иной фишки.

Просто «потому что хочется» работает на самых первых этапах, ведь проекты создаются для того, чтоб решить какую-то конкретную боль клиента. Иногда клиент — основатель стартапа.

А вот потом начинается производственный ад. Виной которому менеджеры продукта.

Ну конечно же не они, но именно они будут отвечать за ведение проекта и внедрение результатов. И за аналитику на первом этапе, конечно же. Так как же с ними договариваться и как они будут принимать это решение? Ну или, как минимум, приоритизировать задачи?

в один пост не вместилось, далее…
А формула проста, и имя ей RICE-фреймворк.

Берём коэффициенты:

Reach: сколько людей будет затронуто, число
Impact: насколько сильно,0.25, 0.5, 1, 2, 3
Confidence: степень уверенности в этом, в процентах
Effort: сколько сил потребуется, любое положительное число, сторипоинты, человеко-месяцы, часы; что угодно используемое в конторе

И считаем: (R*I*C)/E. Больше число — больше уверенности в успехе. Или как минимум в целесообразности начала разработки.

А вот что такое готовность и успех можно поговорить позже.

Правда это всё не включает Developer’s Enjoyment
🥲

Подробнее тут: https://hello.ducalis.io/knowledge-base/rice-scoring-prioritization-framework
👍4
#ссылка дня

Когда-то мы обсуждали новость о том, что ESLint хочет перейти на новый, плоский формат конфига в своей 9 версии.

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

Это, казалось бы, удобное нововведение вызвало бурю негодования. Кто-то решил остаться на восьмой версии, кто-то нашёл это идеальным поводом чтобы уйти на какой-нибудь Biome.

Но... ESLint нас услышал! И они выкатили инструмент для миграции конфигов: https://eslint.org/blog/2024/05/eslint-configuration-migrator/

Естественно, не без ограничений (основное — поддерживается только корневая директория), но всё же.

Буду пробовать и сообщу. Я тут осознал, что вообще до сих пор на седьмом...

#eslint #tool
👍12
#такое дня

Продолбал вечер пятницы из-за одного довольно тупого решения почти годичной давности.

Итак, на проекте используются react-hook-form и кастомный селект на базе Downshift (useSelect). К react-hook-form, по причине контролируемой реализации виджета, он подключается через Controller.

В октябре прошлого года по причине, которую никто уже не помнит, мы закрепили react-hook-form на версии 7.47.0.

Ну и всё шло гладко, пока мне не потребовалось прокидывать disabled-состояние на те самые селекты. Казалось бы, однозначный код:


<Controller
name={name}
control={control}
disabled={disabled}
defaultValue={options[0].value}
shouldUnregister={true}
render={({ field: { onChange, value } }) => (
<Select
options={options}
defaultValue={value}
onChange={({ value }) => {
onChange(value);
}}
/>
)}
/>


...но вот при изменении состояния disabled, значение контроллера по-умолчанию точно так же никуда не передавалось.

И... это поведение было исправлено буквально через 3 месяца от момента, как мы закрепили версию.

Не то чтобы закрепление версии само по себе плохая практика, скорее, наоборот, но такие решения надо документировать. Я бы не потерял столько времени, пытаясь понять, что же я делаю не так 🙁

P.S. Ладно, самое тупое в том, что мне в итоге не понадобился disabled. Вообще.

Я решил просто не показывать контролируемые селекты, если нужная секция не отмечена. Таким образом, поле ввода снимается с регистрации в React Hook Form и значения не приходится фильтровать.

#form #react
👍13
#статья дня

Прекрасный материал от Ван Дамма. Брамуса. Того самого, который нам много рассказывает про CSS Scroll Timeline API.

Те, кто в вёрстке давно, могут помнить баталии на тему что же такое календарь: список или таблица? Я был приверженцем второго варианта, потому что привычный календарь – он ходит как таблица, ест как таблица и крякает как таблица (надеюсь, отсылку вы поймёте 🧐)

Так вот, Брамус заявляет: “Календарь – это сетка!”.

Семантически календарь это список дней, но для представления максимально логично использовать возможности CSS Grid.

https://www.bram.us/2020/12/08/a-calendar-in-three-lines-of-css/

На всё про всё буквально три значащих строчки. Хочется, чтобы неделя начиналась с воскресенья? Нет проблем, сдвигаем начало сетки!

В общем, на этом войне календарей должен быть положен конец.

#css #grid #calendar
👍122
#ссылка дня

Мы тут немного повеселились с XSS в разных продуктах и сайтах, результаты удивили. Распространяться я не буду, неприлично, но парочкой полезных ссылок поделюсь.

1. Расширение для Chrome, позволяющее быстро выбрать и вставить XSS-строку в нужное вам текстовое поле: https://chrome.google.com/webstore/detail/bug-magnet/efhedldbjahpgjcneebmbolkalbhckfi?hl=en

2. Постоянно обновляемый репозиторий на ту же тему: https://github.com/minimaxir/big-list-of-naughty-strings

Впрочем, там не только XSS. Помните, например, в чатах люди свои ники пишут с “грязью”? Красиво поломать интерфейс — это туда. Вставить эмодзи, смайлы, управляющие символы.

Ломайте свои интерфейсы сами и избегайте XSS, котаны.

#xss #naughty #injection #бородач
2022-12-19_18-39-04.jpg
2.8 MB
#vscode дня

Если вы умеете пользоваться поиском — вы уже миддл. Если поиском с заменой — смело называйте себя сеньором.

Я щас не шучу, know your tools!

Огромное количество разработчиков вообще с трудом понимает, что код — это просто текст, без подсказок IDE не справляются. Но не будем о наболевшем.

Сейчас я вам покажу нечто, что выведет поиск кода на новый уровень: расширение CodeQue!

Ссылка: https://marketplace.visualstudio.com/items?itemName=CodeQue.codeque

Я иллюстрацию файлом приложу, ибо иначе мелко. Но в чём соль: вы можете искать код, который напоминает тот, что написан в области поиска!

Например, в примере — ищем div, внутри которого есть ещё div с атрибутом className, установленным через clsx. Или ещё, можнот найти все формы, внутри которых есть select (необязательно, HTML-тег или компонент).

Я честно говоря сразу вообще не понял, нафига это надо — есть же RegExp.

Но потом ка-а-ак понял!

#search #extension #бородач
👍123
This media is not supported in your browser
VIEW IN TELEGRAM
#codepen дня

На WWDC24 Apple похвастались тем, что на SwiftUI теперь можно создавать параллакс-галереи буквально несколькими строчками кода.

Но мы же с вами все знаем, что Web намного круче, как платформа. Мы тоже так умеем!

Правда, только в Chrome...

Ведь у нас есть CSS-переменные и Scroll Timeline API, который мы рассматривали вот тут, даже с полифиллом: https://t.iss.one/htmlshit/621

Итак, вашему вниманию конфигурируемая параллакс-галерея от Джея: https://codepen.io/jh3y/pen/XWwzYZo

Весь JS там — это часть универсальной панели управления, чтобы задавать параметры.

#css #scroll #animation
🤩71👍1
This media is not supported in your browser
VIEW IN TELEGRAM
#заметка дня

Элемент marquee, который когда-то давно долгое время использовался для создания бесконечной бегущей строки, давно объявлен устаревшим. При этом, желание создавать бегущие строки у дизайнеров и заказчиков никуда не исчезло.

Давайте сразу определимся: хоть он и устаревший, он всё ещё прекрасно работает... в Chrome. Кому-то из разработчиков было весьма интересно переделать его на Shadow DOM и оптимизировать. В Safari и Firefox всё довольно плохо, тормозит безбожно. Поэтому, если ваша задача сделать киоск или использовать в приложении на Electron — не мучайте себя, берите его.

Поэтому долгое время бегущие сроки создавали, используя translate на контейнер и дублирование содержимого. Например, так: https://codepen.io/studiojvla/pen/qVbQqW

Но мы же с вами ровные, зачем нам такие технологии? Можно же жить в 2024 году и не дублировать контент почём зря!

А сделать это можно просто: через CSS-переменные и анимацию индивидуальных элементов! Для этого прямо в разметке указываем порядковый номер элемента и передаём его в определение анимации: https://codepen.io/thebabydino/pen/BaMqgPO?editors=1100

Пример выше — от Аны Тюдор. Вот то же самое, но без Pug, чтобы легче было понять принцип: https://codepen.io/alinaki/pen/poYyaMJ?editors=1100

В чём плюс такого подхода?

1. Никакого дублирования
2. Короткий код
3. Можно применить любые трансформации к каждому элементу, помимо сдвига
4. Фон принадлежит контейнеру и никуда не сдвигается. Можно прозрачность наложить, можно маски, можно глассморфизм... далее — везде.

Не нужны даже псевдоэлементы чтобы затухание сделать (собственно, маска).

Крутота же, котаны? Крутота.

#marquee #бородач
👍183
#заметка дня

Посмотрите внимательно на картинки, ничего необычного не замечаете?

А тут происходит ого-го какая драма!

Если вы хоть раз пробовали проанализировать запросы и понять метрику "водопад", то становится понятно: запросы на картинке слева идут параллельно, а справа — последовательно.

Итого, 2.5 секунды против 3.5.

— Да что ты сказать-то хочешь?

Я хочу сказать, что изменение это произошло не просто так. Это — график ухудшения производительности некоего приложения после обновления React до 19 Beta. Вот подробнее: https://github.com/facebook/react/issues/29898

Итак, мякотка-то в чём. Раньше компонент React Suspense пререндерил всех своих детей вне зависимости от статуса основной загрузки. Люди прекрасно этим пользовались, загружая разные сопутствующие файлы: картинки, конфигурацию, модели. И все были счастливы.

Но ребята из React решили, что нынче ветер дует в сторону серверного рендеринга, что все используют Next.js и хотят, чтобы потомки асинхронного компонента были отрендерены вместе с родителем, ведь это так удобно в SSR/SSG.

Ага, хер там плавал!

Ну то есть вы понимаете, они буквально забили на всех людей, кому нужны SPA-приложения, кого они устраивают, кому серверный рендеринг не нужен или невозможен к реализации. Ну, вот буквально PR: https://github.com/facebook/react/pull/26380

И очень хорошо, что это решение моментально подняло бурю негодования от разработчиков по всему миру. К слову, о том, как важно общаться. Желательно, вербально, иначе вас не услышат.

И мой горячий привет всем инфлюенсерам, которым лишь бы было на чём хайповать. Больше, больше нового!

В общем, ребята из React думают, как откатить изменения и принесли свои извинения с буквальной формулировкой: «Мы недооценили, сколько людей используют SPA и такой паттерн».

Вот: https://x.com/sophiebits/status/1801663976973209620

А, ну и да. Релиз React 19 из-за этого немного задерживается :)

#react #suspense
19👍11🤬5🤡4