Defront — про фронтенд-разработку и не только – Telegram
Defront — про фронтенд-разработку и не только
13.5K subscribers
21 photos
1.09K links
Ламповый канал про фронтенд и не только. Всё самое полезное для опытных web-разработчиков

Обсуждение постов @defrontchat

Также советую канал @webnya
Download Telegram
Автор CSS-фреймворка Codyhouse Себастьяно Гирейро опубликовал пост о том, почему они используют CSS-переменные вместо переменных SASS — "Why we prefer CSS Custom Properties to SASS variables".

Себастьяно пишет про несколько случаев, где CSS-переменные полезны. Например, можно определить переменные, которые задают цвета для разных тем и затем использовать их для фона и цвета текста. В отличие от SASS в CSS-переменных значения могут перекрываться, таким образом одна и та же переменная может использоваться для разных тем. Это помогает избавиться от дублирования деклараций, которые возникают при использовании SASS-переменных. Ещё понравился пример использования CSS-переменных для типографики, с помощью которых задаются степень масштабирования и базовый размер шрифта.

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

#css #customproperties

https://codyhouse.co/blog/post/css-custom-properties-vs-sass-variables
Брэд Ву написал на CSS Tricks статью про блокирование прокрутки основного контента при открытии модального окна — "Prevent Page Scrolling When a Modal is Open".

Прокрутка контента при открытом модальном окне ведёт к плохому пользовательскому опыту, так как после закрытия окна пользователь может оказаться в другом месте страницы. Бред рассматривает несколько вариантов решения этой проблемы. Пример с overflow-y: hidden очень простой, но не работает с мобильной версией iOS. Для блокирования скролла в iOS в статье описывается другой подход с использованием position: fixed и смещением, которое задаётся с помощью JavaScript.

В комментариях к статье пишут, что overflow: hidden для блокирования прокрутки документа работает в iOS 13. Мне стало интересно — нашёл тикет в трекере WebKit. Действительно, баг починили месяц назад. Остаётся подождать, когда большинство пользователей перейдёт на новую версию iOS, и о хаке с fixed можно будет забыть.

#ios #scrolling #ux

https://css-tricks.com/prevent-page-scrolling-when-a-modal-is-open/
Мартин Турнойж написал небольшую статью про то, почему он до сих пор использует jQuery — "Why I'm still using jQuery in 2019".

В статье основной аргумент такой: зачем изобретать колесо, делая свои хелперы, которые не реализованы в браузере, когда уже есть готовая библиотека с удобным API. Ещё в защиту jQuery приводится факт, что минимальная сборка весит всего 17kb. Ещё приводится пример с Bootstrap, когда разработчики решили выпилить jQuery. Им пришлось заново реализовывать некоторые функции. Мартин пишет про то, что была проделана пустая работа в течение полутора лет. Я с ним не согласен, так как выпиливание библиотеки (насколько мне известно) шла в фоновом режиме, и от сокращения объёма загружаемого трафика выиграли все пользователи Bootstrap.

C некоторыми моментами из статьи я не согласен, но всё-таки она заставляет немного задуматься. С чем я согласен, это то, что методы для работы с DOM API иногда очень нелогичны. Но с этим уже ничего нельзя сделать... Вот так вот и живём.

#jquery #musings

https://arp242.net/jquery.html
Пару дней назад Матиас Байненс из команды v8 твитнул о том, что новые методы массивов flat и flatMap доступны во всех стабильных версиях браузеров и Node.js. Этот твит напомнил мне старую трагедию, которая развернулась из-за проблемы с flatten (предыдущее название `flat`).

Если говорить кратко, то добавление реализации flatten сломало как минимум один популярный сайт в Firefox Nightly. Причиной поломки была библиотека MooTools, которая содержала свою реализацию этого метода. Один из участников комитета TC39 завёл тикет про переименование flatten в smoosh. Это вызвало сильные волнения в js-сообществе — очень много разработчиков негодовало из-за нелогичного названия. Оказалось, что это была внутренняя шутка TC39, которую плохо донесли до сообщества. Как результат Матиас написал пост "#SmooshGate FAQ", в котором постарался объяснить, почему бы это название не прошло в стандарт, даже если бы это была не шутка. Спустя некоторое время, участники комитета TC39 переименовали flatten во flat.

Если интересуетесь историей развития web'а или хотите узнать немного больше о том, как принимаются решения в TC39, обязательно почитайте статью.

#history #tc39

https://developers.google.com/web/updates/2018/03/smooshgate
Эли Штайнбок написал статью "How We Write Full Stack JavaScript Apps" про то, каким принципам следует его команда и какие вспомогательные инструменты использует.

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

Давненько я не читал чего-то такого похожего. Лично мне всегда очень интересно узнать про подходы в работе других команд. Кстати, в статье есть неплохая подборка сниппетов кода. Можно забрать и творчески переработать.

#react #graphq #devexperience

https://medium.com/@eliezer/how-writing-simple-javanoscript-got-us-6200-github-stars-in-a-single-day-420b17b4cff4
Дайон Алмаэр опубликовал небольшой пост на тему противопоставления фреймворков и Web-компонентов — "The Truth about Web Components and Frameworks".

Дайон пишет про то, что причиной всех споров вокруг фреймворков и Web-компонентов является желание поделить всё на чёрно-белую абстракцию. То есть в данном случае найти наилучший инструмент для написания web-приложений. Но все желания спорящих разбиваются о суровую реальность "серого" мира: не все приложения можно легко разделить на "чёрные" и "белые". Например, использование Web-компонентов может очень сильно облегчить жизнь при переиспользовании кода в разных проектах, но если компоненты не переиспользуется, тогда использование Web-компонентов может быть избыточным. При этом могут существовать разные подходы к переиспользованию кода, и это нормально. Если компания покупает другую компанию, возникает проблема интеграции разных приложений, которые могут написаны на разных фреймворках и т.п.

Недавно я где-то увидел шутку про Теорию Великого Объединения JavaScript-фреймворков. В общем, неизвестно, сколько ещё пройдёт времени, когда кто-то придумает инструмент, который решит все проблемы с web-приложениями.

#musings #webcomponents #jsframeworks

https://blog.almaer.com/the-truth-about-web-components-and-frameworks/
Андрэ Стальц поделился своими мыслями по поводу экономики открытого программного обеспечения — "Software Below the Poverty Line".

Он провёл анализ открытых данных по пожертвованиям, которые получают популярные проекты. В итоге, если бы разработчики работали фул-тайм над своими проектами и жили на пожертвования, за чертой бедности оказалось бы больше половины мейнтейнеров. Ещё в статье разбирается тема популярности и справедливости. Не удивительно, что больше всего пожертвований получают проекты, которые у всех на слуху. Например, Babel, который используется в 350000 проектах, получает в 5 раз больше Core.js, который используется более чем в 2 миллионах проектах. В статье есть несколько предложений, что надо делать, чтобы над открытыми проектами могло работать фул-тайм большее количество разработчиков: регулярно делать пожертвования, работать только в тех компаниях, которые вносят значимый вклад в open source, использовать альтернативные лицензии и т.п.

Я считаю, что в статье затрагивается очень важная тема для развития нашей индустрии. На ум приходит история про OpenSSL, который лежит в основе функционирования очень большого количества сайтов, у него 5 лет назад было всего два ключевых разработчика, которые работали бесплатно. В общем, есть повод задуматься, что мы можем сделать в сложившейся ситуации.

#opensource #musings

https://staltz.com/software-below-the-poverty-line.html
Как-то я пропустил это небольшое событие. В январе появилось предложение Матиаса Байненса о добавлении в стандарт JavaScript нового метода промисов any().

Promise.any() сигнализирует о том, что один из обрабатываемых промисов был успешно разрешён. Этот метод похож на метод Promise.race(), но отличается тем, что не завершает работу, если был отклонён один из промисов. Отклонение Promise.any() происходит только тогда, когда все обрабатываемые промисы были отклонены. Вот небольшой пример, как работает этот метод:
const promises = [
fetch('/endpoint-a').then(() => 'a'),
fetch('/endpoint-b').then(() => 'b'),
fetch('/endpoint-c').then(() => 'c'),
];
try {
const first = await Promise.any(promises);
// Один из промисов был успешно разрешён, например 'b'
// При этом и 'a', и 'c' могли быть отклонены
console.log(first);
} catch (error) {
// Все промисы были отклонены
console.log(error);
}


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

UPD: Только что обнаружил, что соавтор предложения Сергей Рубанов — ведущий канала @juliarderity (спецификации и другие горячие новости из мира web).

#js #proposal #async

https://github.com/tc39/proposal-promise-any
Рич Снапп написал статью с объяснением того, почему лучше отказаться от использования reduce вместе со spread объектов — "The reduce ({...spread}) anti-pattern".

В современном JavaScript код для создания объекта из массива объектов с одинаковыми свойствами можно написать так:
let result = items.reduce((acc, item) => ({
...acc, [item.name]: item.value
}), {})


Как оказывается в v8 такой код будет выполняться с квадратичной сложностью. Рич доказывает существование этой проблемы, разбирая байткод, который генерирует движок. В качестве альтернативы он предлагает использовать reduce с мутированием, или for...of, которые справляются с этой задачей за линейное время.

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

#v8 #performance #algorithm

https://www.richsnapp.com/blog/2019/06-09-reduce-spread-anti-pattern
Людмила Мжачих написала статью "Нужны ли препроцессоры в 2019 году" с объяснением, почему CSS-препроцессоры больше не актуальны.

Когда появились препроцессоры, это был прорыв — разработчикам для написания CSS стали доступны переменные, вложенность, математические функции и т.п. Но время не стояло на месте, и в стандарте CSS появилось очень много фич, которые стали причиной появления препроцессоров. На данный момент они пока ещё не поддерживаются во всех браузерах, а некоторые только совсем недавно были приняты в стандарт, например, вложенность, но если подключить плагин postcss-preset-env, то можно писать на CSS будущего уже сегодня. Преимущество этого подхода в том, что не надо изучать синтаксис препроцессоров, и по мере появления поддержки в браузерах можно просто отключать транспиляцию фич, не модифицируя исходный код.

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

#css #musings

https://medium.com/@lucyhackwrench/нужны-ли-препроцессоры-в-2019-году-727a856d1443
Прочитал хорошую статью про работу с часовыми поясами в JavaScript — "Handling Time Zone in JavaScript".

В ней мне очень понравилась историческая часть. Есть такой забавный факт: до принятия UTC как официального стандарта, англичане хотели назвать его CUT (Coordinated Universal Time), а французы TUC (Temps Universal Coordonn), но потом пришли к компромиссу, который устроил всех — UTC. В практической части видно, какая же это боль — работа с часовыми поясами на чистом JavaScript. Автор предлагает не мучиться и использовать библиотеку moment-timezone. В комментариях к посту предлагают очень хорошую альтернативу — luxon.

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

#js #datetime

https://medium.com/@toastui/handling-time-zone-in-javanoscript-547e67aa842d
Надо уже написать что-нибудь про свои проекты. Недавно доделал бенчмарк скорости загрузки нативных JavaScript-модулей в браузерах — esmtest.

В бенчмарке измеряется скорость загрузки 100 модулей через HTTP/1.1 и HTTP/2. В каждом модуле находится код, который добавляет на страницу одну букву из первых предложений "Преступления и наказания" Ф.М. Достоевского. Скорость загрузки модулей через HTTP/2 в моих тестах в четыре-пять раз быстрее HTTP/1.1. Возникает резонный вопрос, достаточно ли этой разницы, для того чтобы полностью отказаться от бандлинга приложений? Всё зависит от ситуации. Если у вас Electron-приложение или приложение не очень большое, то от бандлинга можно отказаться. С другой стороны, если нужна максимальная скорость загрузки большого приложения, то тут надо действовать по обстоятельствам и делать эксперименты. В любом случае бандлинг можно оставить только для production-сборки и использовать нативную загрузку во время разработки, таким образом от source maps, с которыми иногда бывают проблемы, можно будет отказаться.

По каким-то причинам при троттлинге сети Chrome в пять раз уступает Firefox. Возможно, что на это влияют какие-то оптимизации в Firefox, или просто есть баг в одном из браузеров. В общем, всё это очень интересно, и пока непонятно из-за чего возникает проблема.

P.S. Сайт бенчмарка попал под ковровые бомбардировки Роскомнадзора, поэтому он может быть недоступен у некоторых российских интернет-провайдеров...

#js #modules #esm #performance

https://twitter.com/myshov/status/1139611892652105730
Пару недель назад я публиковал пост про видео, в котором описываются тонкости работы цикла for. Пётр Мязин — ведущий подкаста Пятиминутка React — вдохновился этим видео и сделал свою версию на русском языке. Видосик получился интересным, код в нём разбирается гораздо подробнее чем в оригинале. Очень рекомендую посмотреть, если англоязычный материал показался сложным для понимания.

#js #quirks

https://www.youtube.com/watch?v=gAPh2W8qcUY
Лиз Пэроди написала хорошую вводную статью про Worker Threads в Node.js — "Understanding Worker Threads in Node.js".

Worker Threads — это экспериментальная фича, с помощью которой можно легко распараллеливать вычисления. Воркеры работают в рамках одного процесса. Каждый воркер включает в себя отдельный инстанс JS-движка. Для обмена данными между воркерами можно использовать ArrayBuffer и SharedArrayBuffer. Для предсказуемой работы с разделяемыми данными — Atomics. При этом создание воркеров — это небесплатная операция, поэтому для production-приложений рекомендуется использовать пул Worker Threads.

Статью стоит почитать, если вы работаете с Node.js и думали о том, как лучше всего распараллелить долгие вычисления. Worker Threads в этом случае могут решить вашу проблему. Да, если вы уже использовали воркеры, и вам есть что сказать, разработчики ждут ваш фидбек в этом issue.

#nodejs #performance #experimental

https://nodesource.com/blog/worker-threads-nodejs
Кристоф Гуттандин рассказал про то, как он тестирует свою библиотеку на утечки памяти с помощью Puppeteer — "Automatically detect memory leaks with Puppeteer".

Для получения информации о потребляемой памяти в Puppeteer можно использовать метод metrics(). Кристофу этот способ не подошёл. Проблема в том, что для получения воспроизводимых результатов, надо перед запуском теста вызывать сборку мусора, что не всегда получается сделать. Плюс, когда начинает работать оптимизатор v8, потребляемая память может непредсказуемо измениться и тесты будут моргать.

В итоге, автор остановился на варианте с queryObjects(). С помощью него можно подсчитать количество всех объектов в heap, у которых в цепочке прототипов, содержится переданный в качестве аргумента объект (`queryObjects()` также доступен из консоли chrome dev tools).

На ум пришёл ещё такой способ использования queryObjects(). Если есть подозрение, что текут объекты с определённым прототипом, запрашиваем количество объектов с помощью queryObjects() в консоли браузера до и после проблемного кода и сравниваем. В общем, статья полезная. Советую почитать.

#testing #internals #puppeteer

https://media-codings.com/articles/automatically-detect-memory-leaks-with-puppeteer
Эван Ю — автор Vue — пару недель назад опубликовал предложение о включении в Vue 3.0 нового подхода создания компонентов, который был вдохновлён React Hooks.

Большая часть сообщества отреагировала положительно на эту новость, но была и жёсткая критика. Vue стали обвинять в том, что API не будет обратно совместим с предыдущими версиями, что разработчикам придётся выкинуть свои старые знания о Vue, что Vue превращается в React и т.п. В общем, было очень горячо. В итоге, Эван добавил в предложение FAQ, в котором говорится о том, что кардинально ничего не поменяется — будет добавлен ещё один подход для создания компонентов. От уже привычного описания логики поведения компонентов с помощью объекта проект отказываться не будет.

Про новое API и его преимущества относительно старого подхода очень хорошо написал Дэниэл Элкингтон в статье — "Vue's Darkest Day" (есть перевод на хабре). От себя хочу добавить, что если React и Vue будут немного больше похожи друг на друга, то от этого выиграют все. Make love, not war.

#vue #hooks

https://github.com/vuejs/rfcs/pull/42
Эдди Османи написал новую статью про актуальные способы ускорения загрузки JavaScript и сокращения времени его инициализации — "The cost of JavaScript in 2019".

Вот, что мне показалось наиболее интересным. В Chrome 41 появился асинхронный парсинг и исполнение скриптов во время их загрузки (noscript streaming). На реальной практике это приводит к тому, что V8 парсит код быстрее его загрузки — парсинг с компиляцией завершается через несколько миллисекунд после того как заканчивается скачивание кода. В Chrome 71 был сделан ещё один шаг к ускорению — произошёл переход на task-based подход, с помощью которого async/deferred скрипты теперь парсятся параллельно.

Последние два года команда V8 очень много занималась оптимизацией парсера, он больше не является бутылочным горлышком. На сегодняшний день при оптимизации сайтов стоит прикладывать усилия к снижению времени исполнения кода в главном потоке. В качестве примера приводится Facebook. Благодаря комбинации code splitting (около 300 бандлов по ~30KB) и HTTP/2 на основном сайте социальной сети всего 30% кода выполняется в главном потоке, остальные 70% в так называемых Worker Threads, что приводит к снижению Time To Interactive (TTI).

В статье есть ссылка на видео с докладом Эдди, на основе которого была написана статья. В этом видео есть примеры более агрессивных оптимизаций. Например, Netflix чтобы ускорить свою приветственную страницу оторвал React и другие библиотеки, заменив их ванильным JavaScript. Индонезийский e-commerce сайт Tokopedia заменил React на Svelte для своих посадочных страниц. Размер бандла уменьшился с 320KB до 73KB. При этом и Netflix, и Tokopedia в фоне загружают бандлы с React, которые необходимы для других страниц.

Статья крутая. Советую почитать, если вам интересно узнать про современные подходы оптимизации JavaScript.

#js #performance #v8 #chrome

https://v8.dev/blog/cost-of-javanoscript-2019
Джеймс Лонг написал интересную статью — "The Secret of Good Electron Apps".

Приложения, построенные на базе Electron, заработали себе дурную репутацию. Если c большим размером исполняемого файла и долгим временем запуска ничего не сделать, то с проблемой большого количества потребляемой памяти можно побороться. Джеймс предлагает использовать фоновый сервер для управления данными. Например, он может загружать в память только те данные, которые нужны в данный момент, используя SQLite. Для коммуникации между фоновым процессом и client renderer предлагает использовать node-ipc.

В качестве жизнеспособности данного подхода автор сравнивает своё приложение Actual (213MB потребляемой памяти) c Notion и Airtable (400-600MB). Для разработки приложений с подобной архитектурой Джеймс предлагает использовать свой starter kit.

Статью стоит почитать, если вы пишите Electron-приложения и упираетесь в проблему с памятью.

#electron #performance

https://jlongster.com/secret-of-good-electron-apps
Никита Прокопов поделился своим опытом участия в ICFPC — международном соревновании команд программистов.

Соревнование шло три дня. Задание состояло в том, чтобы реализовать наиболее эффективный обход лабиринта с заданными ограничениями. Автор пишет, что Clojure не очень хорошо подходит для решения подобных задач, потому что итоговая оценка зависит от производительности написанного решения. Это подтверждается результатами соревнований. За несколько последних лет всё больше призовых мест берут команды, использующие C++, Java, JavaScript и т.п. Ирония в том, что соревнование приурочено к конференции по функциональному программированию.

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

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

#contest #algorithm

https://tonsky.livejournal.com/322258.html
Honeypot выложил на youtube новый документальный фильм, посвящённый GraphQL — "GraphQL: The Documentary".

Вот краткий пересказ. В 2011 году Facebook решил переписать своё мобильное приложение с HTML5 на нативные технологии — web на тот момент не позволял сделать качественное мобильное приложение. При переписывании самой сложной частью, которая не ложилась на традиционные API, была лента новостей (news feed). В феврале 2012 года Ник Шрок разработал прототип нового API, с помощью которого можно было получать произвольные наборы данных из бэкенда. Разработка прототипа заняла несколько дней. В начале он назывался SuperGraph. Ли Байрон и Дэн Шейфер вдохновились идеей и присоединились к Нику, чтобы довести прототип до production-решения.

Ребята с успехом справились с задачей. Лента была переписана на новом API за несколько месяцев. Спустя полтора года уже практически весь мобильный Facebook работал на GraphQL. Затем разработчики решили открыть исходный код своего решения. В ходе обсуждения Ли предложил переписать реализацию: "Если бы мы знали, что делаем, что мы бы сделали по-другому?". В 2015 году GraphQL был представлен публично и получил широкое распространение, его стали использовать в других компаниях: Github, Airbnb, Twitter и т.д.

Honeypot снял хороший фильм. Советую посмотреть, если интересуетесь историей развития технологий.

#graphql #history #facebook

https://www.youtube.com/watch?v=783ccP__No8
Это, наверное, уже не новость, но вдруг вы не знали. В блоге v8, есть специальный раздел с описанием новых фич JavaScript и WebAssembly, которые планируется добавить в будущие версии языка и платформы.

С начала года там появилось шесть новых статей:
- String.prototype.matchAll
- Numeric separators
- Array.prototype.flat and Array.prototype.flatMap
- Promise combinators
- Object.fromEntries
- Symbol.prototype.denoscription

Во всех статьях есть краткое объяснение работы новых фич и много примеров. По WebAssembly пока нет ни одной статьи, но это не снижает ценность ресурса.

#js #v8 #list

https://v8.dev/features