Hacknote.js
600 subscribers
24 photos
5 videos
1 file
36 links
Заметки о веб-разработке и около неё

https://newesters.github.io/hacknote-js/
Download Telegram
Media is too big
VIEW IN TELEGRAM
Пришлось покостылить даже тут)
В бете Safari 18 заявлена долгожданная (по крайней мере мной) поддержка View Transitions API, который уже довольно давно поддерживается в Chromium-based бразуерах и по такому поводу я решил сделать небольшой редизайн главной страницы своего блога.

На мой взгляд эта фича вносит огромный вклад в то, чтобы Web-приложения ощущались как нативные и при этом не требует особых вложений с точки зрения разработки (особенно при использовании Astro).

Если у вас есть классные примеры использования этого API, кидайте в комментарии)
Please open Telegram to view this post
VIEW IN TELEGRAM
Сказ о внедрении View Transitions

В предвкушении внедрения поддержки View Transitions в Safari я обновил Mac OS и iPad OS до последних версий и... я был крайне разочарован.

Анимации переходов работали совсем не так, как в Chromium-based браузерах — они заметно тормозили, а в некоторых случаях и вовсе перестали работать.

Сперва я подумал "как же Apple могли выкатить в продакшен такую кривую реализацию API?", но, тщательно погуглив, я не обнаружил ни одной подобной жалобы. Это могло значить одно из двух: либо никто кроме меня не ждал внедрения View Transitions в Safari, либо я сделал что-то не так.

И вот опытным путём я выяснил, что огромное влияние на производительность анимации оказывает размер анимируемого элемента. Я пытался создать эффект раскрытия карточки со статьёй в полноценную статью, которая очевидно имеет довольно большую высоту, с которой Chromium-based браузеры справляются без труда, а вот для Safari это непосильная тяжесть — возможно это как-то связано с древней проблемой ограничения на размеры текстур в Open GL, которая приводит к различным артефактам при использовании CSS анимаций.

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

(На видео в посте можно увидеть анимации переходов до/после исправления)
This media is not supported in your browser
VIEW IN TELEGRAM
Для полноты картины упомяну ещё одну проблему, которая мешает полноценному использованию View Transitions — задваивание анимаций перехода при свайпе в Safari на iOs.

С этой проблемой пытались бороться решениями разной степени костыльности ещё во времена актуальности React Transition Group, но с приходом View Transitions эта проблема заиграла новыми красками и я очень надеюсь, что в ближайших релизах Safari с ней что-нибудь сделают.
Дивный новый Vite

В своём докладе про то, как мы с CRA съезжали я уже упомянал о планах Vite по переезду на Rust и вот на недавнем ViteConf Эван Ю более подробно рассказал об этих планах.

Напомню, что основная идея заключается в замене связки Rollup (эффективный и гибкий, но медленный) и ESBuild (ничего не умеет, но быстрый) на Rolldown (эффективный, гибкий и быстрый) с целью избавиться от неконсистентности между дев и прод сборками.

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

Замена Rollup на Rolldown, как я понимаю, вдохновлена опытом Rspack, который призван заменить собой Webpack.

При этом Эван Ю спешит похвастаться сравнительными замерами скорости Rolldown и Rsbuild, которые, разумеется, демонстрируют, что их инструмент самый быстрый и классный.

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

На недавнем Frontend Conf я рассказывал о текущем состоянии микрофронтов. Постарался рассказать максимально доступным языком, при этом не теряя важных концептуальных деталей, и проиллюстрировать наглядными схемами, поэтому на мой взгляд доклад будет полезен даже тем, кто уже посмотрел множество других докладов про микрофронты.
Системы эффектов

Недавно послушал выпуск Подлодки про "Системы эффектов в языках программирования" и решил поделиться некоторыми рандомными рассуждениями на эту тему.

"Окраска" функций

"Окраской" функций называется некоторая декларация эффектов, содержащихся в функции.

В JavaScript есть 2 варианта "окраски" функций:

- async — обозначает, что функция асинхронная и позволяет использовать внутри неё оператор await
- * — обозначает, что функция является генератором и позволяет использовать внутри неё оператор yield

Fun fact: эти 2 варианта можно скомбинировать, чтобы получить AsyncIterator, который можно перебирать оператором for await...of.

В языке Nim система эффектов позволяет окрашивать функции любыми эффектами, что выглядит весьма любопытно (на самом деле существует ещё множество языков с такой возможностью, но почему-то мне сразу вспомнился именно Nim).

Обработка исключений

В Java есть оператор throws, позволяющий "окрасить" функцию эффектом выброса определённого типа исключения и на этапе сборки удостовериться, что эти исключения обработаны.

JavaScript/TypeScript не позволяет типизировать исключения (разве что задокументировать их с помощью JSDoc или TSDoc), но теоретически эту проблему можно решить знаменитой монадой Either.

Чистота функций

Бандлеры используют аннотацию /*#__PURE__*/, которая обозначает отсутствие побочных эффектов в функции, для более эффективного тришейкинга (упомянал об этом в своём докладе).

В самом JavaScript нет языкового средства для выражения чистоты функции — то есть отсутствия в ней эффектов, хотя было бы классно использовать это знание, например, для исполнения кода во время сборки (как, например, c babel-plugin-macros).
Пранк, который вышел из под контроля

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

В процессе исследования проблемы выяснилось, что @vitejs/plugin-legacy инлайнит CSS в JS-бандл с легаси сборкой, что приводит к тому, что шрифты гарантированно будут загружены после JS и скачок неизбежен.

Отказываться от plugin-legacy или возиться со сборкой было лень, поэтому я начал раздумывать над каким-то надёжным решением кроме инлайна шрифтов в base64 (чтобы они загружались синхронно).

По дороге из офиса домой я по традиции решил послушать выпуск веб-стандартов. Мне сразу показался подозрительным состав ведущих в этом выпуске, но я не придал этому особого значения. По счастливой случайности одной из обсуждаемых тем была загрузка шрифтов: обсуждали тот самый вариант с инлайном в base64, а так же некий новый Font Face API (почему-то я самостоятельно не догадался загуглить его), который ещё мало где поддерживается.

Придя домой, я наконец обратил внимание на дату публикации выпуска: он был датирован 1 апреля...

Это был выпуск веб-стандартов 10-лентней давности, а значит тот самый Font Face API уже давным давно "Baseline Widely Awailable" и ничто не мешает мне его использовать, чтобы управлять последовательностью загрузки ресурсов приложения:


const font = new FontFace(
"my-font", "url(my-font.woff)",
{
style: "normal",
weight: "400",
stretch: "condensed",
}
);

Promise.all([
import("./app.js"),
font.load(),
]).then(([app]) => {
document.fonts.add(font);
app.init();
});


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

Таким образом выпуск веб-стандартов прошёл проверку временем и внезапно оказался полезен даже спустя 10 лет после выхода.