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

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

Также советую канал @webnya
Download Telegram
Пару недель назад я публиковал пост про видео, в котором описываются тонкости работы цикла 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
Реактивное программирование очень мощная штука. Томас Бурлесон (ex-Google) написал хорошую статью о том, как оно помогает в разработке приложений — "Push-based Architectures with RxJS" .

В статье рассматривается одно приложение, написанное с использованием двух подходов — pull-based и push-based. Pull-based — это традиционный подход, в котором view инициирует обращение к внешним API. В push-based подходе view реагирует на изменение данных в некотором источнике-стриме. Pull-based приложение без дополнительного тюнинга получилось очень топорным и не очень интуитивным. С push-based — приложение стало интуитивным и приятным в использовании. Код тоже стал более организован.

Томас ничего не написал про недостатки. По-моему опыту работа со стримами требует большего планирования, чем при обычном императивном программировании. Также rxjs требует время, чтобы в него погрузиться (но это того стоит).

Как бы то ни было очень советую посмотреть статью. Хотя примеры там и используют Angular, push-based подход можно применить в React, во Vue и в других фреймворках/библиотеках.

#angular #rxjs #architecture

https://medium.com/@thomasburlesonIA/push-based-architectures-with-rxjs-81b327d7c32d
Proxy появился в ES2015, но до сих пор остаётся эзотерической фичей JavaScript. Про то чем он может быть полезен, рассказывает Томас Баррассо в статье "A practical guide to Javanoscript Proxy".

Proxy можно использовать для задания дефолтного значения, отличного от undefined, при обращении к несуществующему свойству объекта. С помощью него можно сделать python-like обращение к последнему элементу массива — arr[-1], скрытие свойств и инавалидирование свойств объекта, что может быть полезно при кешировании. Но больше всего мне понравился пример с перегрузкой оператора in, который позволяет реализовать проверку вхождения числа в заданный диапазон как в python 2 in range(1, 100) // true:
const range = (min, max) => new Proxy(Object.create(null), {
has: (_, prop) => (+prop >= min && +prop <= max)
})


Это, конечно, не всё, на что способен Proxy. В статье упоминается, что он лежит в основе новой системы реактивности Vue 3. Ещё там есть ссылки на другие способы использования. В общем, статья хорошая, почитать стоит.

#es2015 #js

https://blog.bitsrc.io/a-practical-guide-to-es6-proxy-229079c3c2f0
Эрик Кори — создатель библиотеки Irregexp, которая используется в Chrome, node.js и Firefox — написал статью про возможные оптимизации в движке регулярных выражений "Regexp backtracking in loops, and how we can optimize it away".

Эрик в начале статьи описывает то, как можно реализовать бэктрекинг (backtracking) с использованием стека. Он рассказывает, что это ведёт к большому потреблению памяти на длинных строках и что все движки регулярных выражений содержат обработчики специальных случаев, которые позволяют избавиться от этой проблемы. Эрик выдвигает предположение, что если бы движок мог распознавать naturally possessive квантификаторы, это бы позволило ещё больше сократить размер памяти необходимой для бэктрекинга.

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

#v8 #regexp #performance

https://medium.com/@erik_68861/regexp-backtracking-in-loops-and-how-we-can-optimize-it-away-ef3b2590f87e
Уже несколько недель лежала в закладках статья про то, как инженеры Google внедрили на страницу поиска сервис воркеры — "Bringing service workers to Google Search".

Сервис воркеры используются для того, чтобы кешировать результаты ответа на запрос в течение небольшого количества времени. Ещё они используются для offline-режима, в котором пользователь может ввести запрос и получить ответ как только появится соединение. Но наиболее интересным мне показался кейс с анализом запросов за бандлами js-кода. Код, работающий в сервис воркере, определяет состав бандла, который должен быть загружен с сервера. После этапа анализа создаётся бандл из локально закешированных модулей. Это позволяет увеличить отзывчивость сайта и уменьшить объём потребляемого трафика у клиента.

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

#serviceworker #performance #google

https://web.dev/google-search-sw/
Прочитал статью Мириам Сьюзан про изобретательные способы использования кастомных свойств — "CSS Custom Properties In The Cascade".

Мириам на очень показательных примерах показывает, как кастомные свойства позволяют сэмулировать функцию, миксин или компонент. "Функцию", например, можно представить с помощью кастомного свойства, которое в свою очередь использует другое кастомное свойство:
.stripes {
--stripes: linear-gradient(
var(--stripes-angle),
pink 50%,
powderblue 50%
);
}

.vertical {
--stripes-angle: 0deg;
background-image: var(--stripes);
}


Мириам в статье идёт дальше и рассказывает как можно задавать дефолтные значения, как использовать пресеты и как возможно было бы параметризировать "функцию", если бы браузеры поддерживали функцию attr() из стандарта CSS3.

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

#css #customproperties

https://www.smashingmagazine.com/2019/07/css-custom-properties-cascade/
Евгений Обрезков написал небольшую статью, в которой он разрушает самые популярные мифы, связанные с WebAssembly — "Three myths about WebAssembly". Вот небольшой пересказ, разбавленный моими мыслями.

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

Второй миф. "WebAssembly — замена JavaScript". WebAssembly был разработан для того, чтобы работать в тандеме с JavaScript, а не заменить его. При этом WebAssembly поможет нативным языкам более эффективно работать с Web API, но это можно считать сайд-эффектом, а не целью создания WebAssembly. Как бы то ни было JavaScript сейчас слишком распространён, чтобы его можно было заменить в мгновение ока.

Третий миф. "WebAssembly быстрее JavaScript". Здесь нельзя однозначно заявить, правда это или нет, так как на скорость работы WebAssembly-кода будут влиять используемые оптимизации во время компиляции. В свою очередь JS-движки могут оптимизировать JavaScript-код настолько качественно, что в некоторых случаях он может быть производительнее, чем скомпилированный C++ код.

Статья небольшая, но в ней всё написано по делу. К слову, ссылку на неё я увидел в твите официального аккаунта WebAssembly.

#webassembly #list

https://blog.ghaiklor.com/2019/06/18/three-myths-about-webassembly/
Пару дней назад я писал про статью Эрика Кори об оптимизации регулярных выражений. Там есть ссылка, объясняющая почему JS обогнал C++ в бенчмарке regex-dna — "How did JavaScript beat C++ at the regex-dna benchmark?"

Regex-dna — это небольшая часть бенчмарка Sunspider, на который ориентируются разработчики JavaScript-движков на протяжении уже многих лет. В ходе соревнования друг с другом, реализации движков regex-выражений стали очень продвинуты. На данный момент Chrome и Firefox используют форк движка iiregexp. Его особенность состоит в том, что он компилирует регулярные выражения на лету в оптимизированный машинный код.

Хочу добавить, что сам по себе iiregexp написан на C++. В бенчмарке из вопроса сравнивали V8 и С++ код, использующий другой движок — re2. Интересно, какой бы был результат, если бы в C++ коде использовался iiregexp...

#regexp #performance #benchmark

https://www.quora.com/How-did-JavaScript-beat-C++-at-the-regex-dna-benchmark
Аксель Раушмайер написал первую статью из серии про Class Fields — "ES proposal: public class fields". Эта серия статей заменит его прошлую статью про поля классов, которую он написал в 2017 году.

Публичные поля классов предназначены для задания свойств экземпляра объекта и статических свойств изнутри тела класса. В статье есть пара ярких примеров, которые показывают насколько короче может получиться код при использовании публичных полей:
// classic instance property
class MyClass {
constructor() {
this.counter = 0;
}
}
// public field
class MyClass {
counter = 0;
}


Если в React-компонентах вы используете объявление метода через doSomething = () => {}, то на самом деле вы используете синтаксис пропозала class fields, который транспилируется babel'ем в стандартный синтаксис.

Пропозал "Class Fields" находится на третей стадии добавления в стандарт. На данный момент поддержка нового синтаксиса уже есть в Chrome (72+) и Node.js v12, в Firefox и Safari на стадии разработки.

#js #proposal

https://2ality.com/2019/07/public-class-fields.html
Forwarded from Вебня (Ҫѐҏӗѫӑ Ҹҋ 🤖)
⚡️ 26го июня Генеральная Ассаблея Ecma одобрила новые редакции спецификаций, разрабатываемых под эгидой Ecma International. Нас с вами интересуют две из них:
- ECMA-262 10th edition, ECMAScript® 2019, Language Specification
- ECMA-402 6th edition, ECMAScript 2019 Internationalization API Specification

Иначе говоря, официально вышла спека ES2019 и обновленная Intl API.

Среди фич, попавших в ES2019:
- Optional catch binding
- JSON superset
- Symbol.prototype.denoscription
- Function.prototype.toString revision
- Object.fromEntries
- Well-formed JSON.stringify
- String.prototype.{trimStart,trimEnd}
- Array.prototype.{flat,flatMap}
Наткнулся на статью Стейси Тей "How we made Carousell’s mobile web experience 3x faster". В статье Стейси делится опытом оптимизации web-приложения Carousell.

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

Они ввели бюджет на производительность: 120KB для ресурсов критического пути рендеринга, 2 секунды для First Contentful Paint и 5 секунд Time-to-Interactive. Частично реализовали паттерн PRPL, заинлайнили критический CSS, стали лениво грузить изображения, стали использовать сервис воркеры для кеширования запросов, включили сжатие изображений у своего CDN-провайдера. В итоге их сайт стал грузиться в 3 раза быстрее, в 3 раза увеличился CTR и на 63% увеличился органический траффик из Индонезии.

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

#web #performance #pwa

https://medium.com/carousell-insider/how-we-made-carousells-mobile-web-experience-3x-faster-bbb3be93e006
Недавно был выпущен Firefox 68. По традиции на Mozilla Hacks разработчики опубликовали статью про новые фичи браузера — "Firefox 68: BigInts, Contrast Checks, and the QuantumBar".

В новой версии появилась поддержка пропозала BigInt, который позволяет работать с большими целыми числами в JavaScript, не теряя в точности. Была добавлена поддержка последнего синтаксиса для scroll snapping. В рамках работ над web-совместимостью были добавлены проприетарные методы из IE для работы с CSS-правилами: addRule() и removeRule(), и была добавлена поддержка -webkit-line-clamp (ура!). Доступ к медиаустройствам теперь разрешён только тем сайтам, которые работают по HTTPS. Теперь можно передавать опцию noreferrer в методе window.open().

В инструментах разработчика на панели доступности можно включить предупреждения для неконтрастного текста. Информацию по web-совместимости можно получить через about:compat. Новый многопоточный WebRender, написанный на Rust, теперь включён у пользователей на Windows 10 с видеокартами AMD. Продолжается работа над удалением легаси-кода, использующего XUL/XBL — адресная строка браузера была переписана с использованием стандартных web-технологий: HTML, CSS, JS.

#release #firefox

https://hacks.mozilla.org/2019/07/firefox-68-bigints-contrast-checks-and-the-quantumbar/
Хочу продолжить тему про Firefox. В посте выше было написано, что в новой версии браузера была добавлена поддержка последнего синтаксиса для scroll snapping. Рейчел Эндрю месяц назад написала пост про эту фичу — "CSS Scroll Snap Updated in Firefox 68".

Scroll Snap — это эффект прилипания контента при прокрутке содержимого контейнера. Он очень полезен при реализации каруселей, слайдеров и подобных элементов. Прилипание можно реализовать, используя JavaScript, но это может привести к плохому пользовательскому опыту, именно поэтому CSS Working Group разработала спецификацию "CSS Scroll Snap".

Работает Sroll Snap так: у контейнера задаётся свойство scroll-snap-type, а у вложенных элементов, которые должны прилипать, — scroll-snap-align. До Firefox 68 был реализован черновой стандарт Scroll Snap, в новой версии его поддержка была прекращена.

На данный момент поддержка актуальной спецификации Scroll Snap есть во всех основных браузерах: Firefox, Chrome, Safari.

#firefox #css

https://hacks.mozilla.org/2019/06/css-scroll-snap-updated-in-firefox-68/