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

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

Также советую канал @webnya
Download Telegram
Аксель Раушмайер написал первую статью из серии про 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
Недавно в блоге V8 появилась статья, посвящённая новому пропозалу WeakRef (Stage 3) — "Weak references and finalizers".

Попробую объяснить своими словами его суть на примере. Представьте, что у вас в браузере происходит какая-то обработка изображений, например, на них накладывается водяной знак (согласен, пример не очень реалистичный), а затем эти изображения как-то используются. Водяной знак накладывается функцией, которая интенсивно потребляет CPU. Изображения могут повторяться, поэтому, чтобы лишний раз не загружать процессор, мы создаём кеш изображений с водяным знаком в Map, ключом пусть выступает название файла изображения. Но тут возникает проблема, если какое-то изображение не будет нами использоваться, оно всё равно будет находиться в памяти, так как Map по ключу будет на него ссылаться (strong reference). Поэтому, чтобы наш Map не отжирал лишнюю память, необходимо как-то определять такие ситуации и руками чистить кеш. Это не очень удобно.

Именно здесь на помощь приходит WeakRef. С помощью WeakRef можно создать слабую ссылку на изображение и записывать её по ключу вместо самого изображения:
const wr = new WeakRef(image);
cache.set(name, wr);
// для получения изображения
const ref = cache.get(name);
const image = ref.deref();


В этом случае сборщик мусора сможет самостоятельно определять ситуации, когда изображение в кеше уже не нужно и очищать память. Для очистки ключей из Map в пропозале предлагается использовать дополнительное API FinalizationGroup.

Интересный факт. В самом начале статьи даётся небольшой обзор уже входящих в стандарт WeakMap и WeakSet. Оказывается, что наиболее формальное название для отношения, которое используется в WeakMap — Ephemeron.

#js #proposal #gc

https://v8.dev/features/weak-references
Хочу ещё разок написать про блог Акселя. Совсем недавно он опубликовал там статью про globalThis — "ES proposal: globalThis".

В прошлом посте рассказывалось о том, что в JS сейчас есть два вида глобальных переменных, один из которых определяется с помощью global object. В браузерах исторически для доступа к глобальному объекту использовался window. В веб воркерах для доступа к global object используют self, потому что window там недоступен. В node.js в свою очередь вместо window используется global. Для того чтобы унифицировать доступ к глобальному объекту в разных окружениях, в стандарт языка планируется добавить globalThis.

Предполагается, что новый идентификатор будет полезен при написании полифиллов и для определения наличия фич в JS-окружении. С помощью него также можно создавать "классические" глобальные переменные, но это не приветствуется, так как само по себе наличие global object считается ошибкой дизайна языка, от которого нельзя избавиться из-за обратной совместимости.

На данный момент globalThis находится на третьей стадии добавления в стандарт. Его поддержка уже есть в Firefox, Chrome и Safari.

#js #proposal

https://2ality.com/2019/08/global-this.html
Лин Кларк на Mozilla Hacks опубликовала большую статью, посвящённую новому пропозалу в WebAssembly — "WebAssembly Interface Types: Interoperate with All the Things!"

На данный момент WebAssembly без использования glue-кода может общаться с внешним миром только числами (значения, смещения, адреса). Пропозал "WebAssembly Interface Types" позволит работать со сложными типами напрямую (строки, объекты, структуры и т.п.) Это открывает двери таким возможностям как работа с Web API непосредственно из WebAssembly без привлечения JavaScript, общение wasm-модулей, скомпилированных из разных языков, между собой, использование одного и того же модуля без перекомпиляции в совершенно разных окружениях, например, Node.js, Python, WASI-рантаймах и т.п.

В статье очень детально разбирается, как это всё работает. От описания высокоуровневой проблемы до примеров реализации того, как будут представлены интерфейсные типы в коде wasm-модулей. Экспериментальная поддержка предложения есть в рантайме Wasmtime, Rust-тулчейне и wasm-bindgen.

Что сказать... очень крутая новость. Пойду ещё разок задоначу в Mozilla Foundation.

#webassembly #proposal

https://hacks.mozilla.org/2019/08/webassembly-interface-types/
Фараз Келини написал хорошую статью про BigInt — предложение добавления в стандарт JavaScript — "The Essential Guide To JavaScript’s Newest Data Type: BigInt".

BigInt — новый тип в языке. Его планируют добавить в стандарт из-за того, что размерности Number недостаточно, если необходимо работать с большими числами. Если Number выходит за пределы Number.MAX_SAFE_INTEGER и Number.MIN_SAFE_INTEGER, то число округляется, приводя к багам в программе. Например, 9007199254740992 === 9007199254740993 будет true.

BigInt-числа выглядят как обычные, но с суффиксом n в конце — 10000n. В арифметических выражениях BigInt и Number, нельзя смешивать между собой (будет TypeError ), так как возникает дихотомия в интерпретации результата. Если хочется использовать разные типы в одном выражении, то их надо привести явно к одному типу: 1000n + BigInt(1). При сравнении чисел BigInt и Number нельзя использовать строгое сравнение, так как это разные типы ( 10n === 10 // false ), но можно использовать нестрогое.

На данный момент пропозал BigInt находится на stage 3. Его поддержка есть в Chrome, Firefox и последней версии Edge. Создать полноценный полифилл для BigInt невозможно, поэтому в статье предлагается использовать библиотеку JSBI для поддержки старых версий браузеров.

В общем, рекомендую почитать статью. Скорее всего BigInt попадёт в следующую версию стандарта.

#js #proposal

https://www.smashingmagazine.com/2019/07/essential-guide-javascript-newest-data-type-bigint/
Сегодня увидел в твиттере новость — в V8 v7.9 появилась реализация пропозала "RegExp Match Indices" (пока спрятана за экспериментальным флагом). Майа Лекова из команды разработки движка написала статью с объяснением, где он может быть полезен.

Методы Regexp#exec(), String#match() и String#matchAll() ищут заданный шаблон в строке и в случае успеха возвращают "match object". В нём находится индекс первого символа строки, который совпал с шаблоном. Этой информации недостаточно, если в выражении есть скобочные группы (capturing group), и если мы хотим получить позицию каждой сматченной группы. Именно эту проблему решает "Match Indicies" — он расширяет возвращаемый match object новым свойством indicies, в котором находятся позиции всех найденных групп. В статье есть пример того, как это свойство может быть использовано для понятного отображения ошибок парсинга кода.

На данный момент "RegExp Match Indices" находится на третьем этапе добавления в стандарт. Вполне возможно, что он попадёт в грядущий стандарт ECMAScript 2020 (ох... красивая цифра).

#js #regexp #proposal #v8

https://v8.dev/features/regexp-match-indices
Пару недель назад Мэйсон Фрид из команды разработки Chrome представил предложение о добавлении декларативного способа создания Shadow DOM.

Shadow DOM — часть спецификации веб компонентов, инкапсулирующая представление компонентов (стили и элементы) вне DOM-дерева. Shadow DOM на данный момент может быть создан с помощью императивного API, то есть используя JavaScript. Проблема в том, что страницы, содержащие веб компоненты, не могут быть корректно интерпретированы поисковиками, которые не поддерживают JS, также такие страницы могут быть бесполезны для пользователей, которые используют браузерные плагины, отключающие работу JS.

Предложение "Declarative Shadow DOM" решает эти проблемы. Декларативная разметка с Shadow DOM может быть отрендерена браузерами без использования JS. Также поисковикам не надо исполнять JS, достаточно модифицировать парсер, чтобы уметь понимать новый атрибут shadowroot в <template>.

Мейсон сделал экспериментальную реализацию декларативного Shadow DOM, которая показала значительный прирост производительности относительно императивного API, так как из этапа рендеринга веб компонентов отпал шаг выполнения JavaScript-кода.

Очень многообещающее предложение. Также радует сам факт того, что разработчики Chrome наконец-то признали, что основной камень преткновения в адаптации веб компонентов — сервер-сайд рендеринг.

#proposal #experimental #webcomponents

https://github.com/mfreed7/declarative-shadow-dom
Аксель Раушмайер опубликовал статью про новый пропозал — "A first look at records and tuples in JavaScript".

Records и Tuples (записи и кортежи) — это новые иммутабельные и сравниваемые по значению примитивные типы данных. Record — это аналог объекта, tuple — массива. Для их создания используются похожие на массив и объект литералы с префиксом "#": #[1, 2], #{a: 1}.

Благодаря иммутабельности записи и кортежи можно безопасно использовать по всей программе без необходимости в клонировании (как в случае с обычными массивами и объектами). Также их можно использовать в тех ситуациях, где не имеет особого смысла использовать обычные литералы массивов и объектов, например, при сравнении в условиях #[1, 2, 3] === #[1, 2, 3] и в качестве ключа Set и Map.

На данный момент пропозал находится на первой стадии добавления в стандарт. Есть полифилл (использует экспериментальные WeakRef и FinalizationRegistry ).

#js #proposal

https://2ality.com/2020/05/records-tuples-first-look.html
https://habr.com/ru/post/504092/ (перевод на русский язык)
Аксель Раушмайер написал статью про логические операторы присваивания — "ECMAScript proposal: Logical assignment operators".

Пропозал добавляет в стандарт новые составные операторы присваивания: a ||= b, a &&= b и a ??= b. Благодаря этим операторам можно компактно комбинировать присваивание с коротким циклом вычислений логических операций (short-circuit). Например, запись a ??= b эквивалентна выражению a ?? (a = b). В нём присваивание происходит только в том случае, когда в a находится null или undefined. Пример использования:

const books = [{
isbn: '123',
}, {
title: 'ECMAScript Language Specification',
isbn: '456',
}];

// Добавление дефолтного заголовка там, где его нет
for (const book of books) {
book.title ??= '(Untitled)';
}

assert.deepEqual(books, [{
isbn: '123',
title: '(Untitled)',
}, {
title: 'ECMAScript Language Specification',
isbn: '456',
}]);


Логические операторы присваивания находятся на третьем этапе добавления в стандарт. Его поддержка появилась в Firefox 77 Nightly, Safari Technology Preview 107, и в V8 v8.4 (Chrome 85).

#js #proposal

https://2ality.com/2020/06/logical-assignment-operators.html
Команда разработки компиляторов из Igalia представила полифилл для пропозала Temporal — "Dates and Times in JavaScript".

Для работы с датами в JavaScript используется объект Date. Он был сделан по образу и подобию Date из Java образца 1995 года. В 1997 году разработчики Java объявили этот API устаревшим. В JS его уже нельзя было поменять, потому что кардинальное изменение API сломало бы web. В результате сообщество создало много библиотек для более удобной работы с датами; Temporal может быть использован вместо них.

Основные особенности Temporal: удобный API для работы с датами и временем, иммутабельность, поддержка разных форматов представления дат, поддержка календарей, отличных от григорианского, полноценная возможность работы с часовыми поясами. В статье есть ссылки на подробное описание API и cookbook с примерами использования Temporal: подсчёт времени перелёта, планирование встречи с участниками в разных часовых поясах и т.п.

Команда Igalia призывает сообщество протестировать полифилл и поделиться критикой и мыслями, пока пропозал находится на Stage 2.

#proposal #polyfill #announcement

https://blogs.igalia.com/compilers/2020/06/23/dates-and-times-in-javascript/
Пару дней назад в канале @juliarderity увидел сообщение, что на последней встрече TC39 на stage 2 продвинулся метод item. Ти-Джей Краудер написал статью про это новое предложение — "The item Method for Indexables".

Пропозал добавляет новый метод для индексируемых типов (строки, массивы, типизированные массивы). С помощью него можно получить элемент по переданному индексу, но в отличие от [] в item можно передавать отрицательные индексы для получения элементов с конца (как в Python). Использование нового метода помогает сократить работу, которая требуется для доступа к последним элементам массива, возвращаемого из функции:

// эти две строки кода:
const result = theFunction();
const last = result[result.length - 1];

// можно заменить одной:
const last = theFunction().item(-1);


Выбор названия метода (item) связан с наличием этого метода в DOM-коллекциях NodeList и HTMLCollection. Это было важно учесть, так как на данный момент идёт работа над тем, чтобы сделать из этих коллекций полноценные массивы.

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

#js #proposal

https://thenewtoys.dev/blog/2020/07/25/the-item-method-for-indexables/
https://github.com/tc39-transfer/proposal-item-method
Гари Чу — devrel из Google — опубликовал статью про проблемы использования транспилированного кода в современных браузерах — "Bringing Modern JavaScript to Libraries".

На данный момент многие библиотеки из npm транспилируются в ES5. Это проблема, так как даже если проект не поддерживает legacy-браузеры, он должен "заплатить налог" в виде размера бандла. Этот налог для разных библиотек может быть как 7%, так и 40%.

В январе 2020 года в Node.js 13.7.0 появилась поддержка условных экспортов, с помощью которых можно указать разные сборки для разных типов окружений. Гари предлагает добавить новый тип окружения в условный экспорт для бандлов, которые транспилируются в ES2017 (один из возможных вариантов — browser2017 ). Предполагается, что бандлеры могут использовать это окружение для создания облегчённой версии бандла приложения. Также рассматривается вариант публикации кода без транспиляции, но в этом случае увеличится время сборки.

Очень полезное предложение. Думаю, что бандлеры адаптируют предлагаемый подход или как минимум придут к какому-нибудь другому альтернативному решению

#proposal #perfomance #npm

https://dev.to/garylchew/bringing-modern-javascript-to-libraries-432c
Себастиен Лорбер из Facebook написал статью про то, какие преимущества даёт пропозал Records & Tuples для React-приложений — "Records & Tuples for React".

Предложение Records & Tuples добавляет новые иммутабельные структуры данных в JS. Записи и кортежи особенно полезны для React, так как много проблем с производительностью и поведением библиотеки связано с устойчивостью ссылок на объекты (object identities). Некорректное использование литералов объектов в пропсах может привести не только к проблемам с производительностью, но и в некоторых случаях к бесконечным загрузкам данных.

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

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

#react #proposal #performance

https://sebastienlorber.com/records-and-tuples-for-react
Дэниэл Эренберг — участник TC39 — на конференции NodeTLV рассказал про предложение о добавлении в JavaScript нового типа для работы с десятичными числами — "BigDecimal: Avoid rounding errors on decimals in JavaScript".

Не все действительные числа в JavaScript могут быть представлены точно. Это связано с внутренним представлением чисел с плавающей запятой в соответствии со стандартом IEEE 754, который используется в большинстве языков (JavaScript, C, C++, Java и т.п.) Такое представление может приводить к проблемам с операциями над числами, которые должны быть быть представлены точно: деньги, расстояния, размеры и т.п.

В пропозале Decimal описывается новый тип для работы с десятичными числами. Такие числа будут задаваться с помощью суффикса m ( 0.1m + 0.2m === 0.3m ). На данный момент ещё не принято окончательное решение о внутреннем представлении таких чисел. Выбор стоит между BigDecimal и Decimal128.

Предложение находится на первом этапе добавления в стандарт, его поддержки пока нет ни в одном движке.

#js #proposal #talk

https://www.youtube.com/watch?v=G3Q4vWf8Peo
Майкл Бутнер и Кенджи Багу из команды разработки Google Chrome рассказали про новый пропозал, который поможет улучшить скорость загрузки сайтов за счёт префетчинга ресурсов с учётом приватности — "Continuing our journey to bring instant experiences to the whole web".

Прочитал статью несколько раз, чтобы полностью разобраться в этом пропозале. Имхо, его лучше всего объяснить на примере. Представьте, что вы Google и хотите, чтобы у пользователей браузера улучшилась скорость загрузки сайтов. Можно делать разные трюки, например, предсказывать, с какой вероятностью пользователь будет кликать по ссылкам, и в зависимости от этого заранее загружать ресурсы нужных сайтов. Проблема в том, что пользователь на самом деле не выразил своё желание перейти по этой ссылке, но его IP-адрес, куки и другая информация будет передана третьей стороне с отправленными запросами за ресурсами, что очень плохо для приватности.

Предложение описывает подход, с помощью которого можно обеспечить предзагрузку ресурсов, не раскрывая информацию о пользователе. Предполагается, что этот механизм будет работать с помощью HTTP-туннелей с внешним прокси (CONNECT proxy). То есть между браузером и сайтом будет находится прокси, который не позволит утечь пользовательским данным.

Ребята из Google провели успешный эксперимент в Chrome для Android, который показал, что использование префетча с помощью CONNECT proxy ускорило первоначальное отображение сайтов на 40%.

Команда разработчиков призывает всех желающих поучаствовать в обсуждении и разработке полноценной спецификации использования CONNECT proxy с префетчем.

#performance #proposal #chromium

https://blog.chromium.org/2020/12/continuing-our-journey-to-bring-instant.html
Apple вместе с W3C Privacy Community Group представили приватный механизм для отслеживания кликов, который в первую очередь предназначен для измерения эффективности рекламы — "Introducing Private Click Measurement, PCM".

Для отслеживания эффективности рекламы сейчас используют куки. С точки зрения приватности, это не очень хорошее решение, так как пользователи, кликнувшие по рекламе, могут быть затреканы. Apple вместе с W3C Privacy Community Group разрабатывают другой подход с отложенным отправлением данных о кликах.

Принцип работы PCM. При клике по ссылке со специальными атрибутами во внутреннем хранилище браузера на семь дней сохраняется информация о клике. Сайт, на котором был произведен переход, для регистрации клика должен сделать GET-запрос к рекламной платформе по URL https://social.example/.well-known/private-click-measurement/trigger-attribution/<data>/<priority> (ведётся работа над тем, чтобы можно было отказаться от GET-запросов). Браузер при обращении к такому URL сравнивает данные из URL с сохранёнными данными клика в хранилище и, если они совпадают, через 24-48 часов отправляет анонимный отчет о клике рекламной платформе. Также есть возможность отслеживать переходы по рекламным баннерам из нативных приложений.

Экспериментальная поддержка PCM уже есть в бете iOS и iPadOS 14.5.

#apple #proposal #privacy

https://webkit.org/blog/11529/introducing-private-click-measurement-pcm/