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

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

Также советую канал @webnya
Download Telegram
Сегодня вышла новая версия Firefox 73. Крис Миллс рассказал про нововведения в браузере — "Firefox 73 is upon us".

Больших фич в новом релиз нет, но есть обновления web-платформы. Были добавлены CSS-свойства overscroll-behavior-block и overscroll-behavior-inline, которые являются логическими маппингами для overscroll-behavior-x и overscroll-behavior-y. Благодаря этому свойству упрощается настройка прокручиваемых элементов внутри других прокручиваемых элементов для языков с вертикальным письмом. Появились новые поля yearName в relatedYear в DateTimeFormat.prototype.formatToParts(), которые могут использоваться для форматирования CJK (Chinese, Japanese, Korean) календарей. У форм появился новый метод requestSubmit, который имитирует клик по кнопке отправки (type="submit") — отправляется событие submit и происходит валидация формы до отправки данных.

В инструментах разработчика ускорили работу панели "Network". Оптимизировали работу со скриптами, содержащими большой объём соурс мапов, теперь такие скрипты загружаются гораздо быстрее. Инспектор веб-сокетов стал поддерживать ещё один формат — WAMP.

#firefox #release

https://hacks.mozilla.org/2020/02/firefox-73-is-upon-us/
В конце января Аксель Раушмайер написал статью про типизацию объектов в TypeScript — "Typing objects in TypeScript".

В статье подробно описывается разница между типами Object и object. Объекты типа Object (с заглавной буквы "О") — это все инстансы класса Object. Объекты типы object (со строчной буквы "o") — представляют собой все непримитивные значения. При этом тип Object включает примитивные значения:
function f(x: Object) { }
f('abc'); // OK


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

Хорошая статья. Рекомендую почитать, если работаете с TypeScript.

#typenoscript

https://2ality.com/2020/01/typing-objects-typenoscript.html
Инженеры Plaid рассказали про свой опыт распаралеливания Node.js-приложения — "How we 30x'd our Node parallelism".

В инфраструктуре проекта было 4000 контейнеров с Node.js-приложением. Запросы не обрабатывались параллельно — каждый контейнер в один момент времени мог обрабатывать только один запрос. Попытка параллелизации выявила проблему с очень сильным потреблением памяти. Она была вызвана кодом, собирающим данные для отладки. Проблему успешно решили. По ходу дела заменили непроизводительную библиотеку для поточной обработки JSON-данных с bfj на JSONStream, нашли некорректную настройку в клиенте s3 и тонко настроили работу сборщика мусора.

После всех оптимизаций каждый воркер без проблем стал обрабатывать 30 запросов. Это позволило снизить количество контейнеров с 4000 до 130 и уменьшить затраты на инфраструктуру.

Статья большая и очень хорошая. Довольно редко встречаются статьи про опыт оптимизации больших проектов. Очень рекомендую почитать, если у вас крутятся сервисы на Node.js.

#nodejs #performance

https://blog.plaid.com/how-we-parallelized-our-node-service-by-30x/
https://habr.com/ru/company/ruvds/blog/483688/ (перевод)
Омар Алшакер написал статью про свои эксперименты со временем в web'е — "4 Creative Ways to JavaScript Timing in Browsers".

Самое интересное в статье — идея реализации подобия таймера с микросекундным разрешением. Его можно создать с помощью веб-воркера и вызовом метода performance.now() в бесконечном цикле. Другие советы по сути бесполезные, но интересные с точки зрения изобретательности. Например, можно сделать подобие setInterval запустив бесконечную анимацию на DOM-элементе и подписавшись на событие animationiteration. Что-то похожее можно сделать с SVG-элементом, используя SMIL-анимацию, но подписываться надо на событие repeat. Для реализации своей версии setTimeout можно использовать KeyframeEffect из Web Animation API (экспериментальное api).

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

#js #experimental #fun

https://blog.omaralshaker.com/creative-ways-to-javanoscript-timing/
Кристофер Хиллер из IBM рассказал как эффективно работать с Diagnostic Repots в Node.js — "Debugging NodeJS in Production with Diagnostic Reports".

Diagnostic Reports был добавлен в Node.js 11.8. С помощью этой фичи можно получить много полезной информации, которая может помочь при поиске проблем. Diagnostic Reports генерирует большой отчёт — JSON-файл, в котором есть данные про окружение, используемые разделяемые библиотеки, текущее состояние event loop и т.п. Кристофер представил утилиту report-toolkit, которая облегчает работу с отчётом. Эта утилита может быть полезна при поиск причин зависаний, анализ моргающих процессов (работает в одном окружении, падает в другом).

Полезный доклад. Рекомендую посмотреть, если работаете с нодой.

#talk #nodejs #debug

https://www.youtube.com/watch?v=PLiar_Aj9gs
Сергей Мелюков (контрибьютор Webpack) написал статью про новую экспериментальную фичу Webpack 5 Beta — Asset Modules.

Традиционный подход работы с ассетами (noscript, png, woff, etc.) подразумевает установку и настройку дополнительных загрузчиков: file-loader, url-loader, raw-loader. Asset Modules — это новая фича, благодаря которой Webpack может работать с ассетами "из коробки" без установки дополнительных загрузчиков.

Asset Modules добавляет несколько типов ассетов:
asset (копирование файла в dist при превышении лимита на размер файла и инлайн файла, если его объём меньше лимита)
asset/inline (аналог url-loader — файлы, попадающие под этот тип, инлайнятся всегда)
asset/resource (аналог file-loader — файлы, попадающие под этот тип, всегда копируются в dist)
asset/source (аналог raw-loader — инлайн файла в бандл в неизменном виде)

Asset Modules — это экспериментальная фича. Разработчики ждут от пользователей обратную связь.

#webpack #bundler #experimental

https://habr.com/ru/post/488464/ (на русском языке)
https://dev.to/smelukov/webpack-5-asset-modules-2o3h
Недавно Иван Акулов в своём блоге рассказал про все современные подходы добавления полифиллов для JS — "How to load polyfills only when needed".

На данный момент есть три актуальных подхода:
1) С помощью Polyfill.io. Это сторонний сервис, который определяет браузер по UA string и возвращает скрипт только с теми полифиллами, которые, действительно, нужны. Есть недостаток — добавляет 50-300мс к TTI.
2) Используя паттерн "module/nomodule". Если скрипт содержит type="module", он не будет выполняться в тех браузерах, которые не поддерживают ECMAScript Modules, то есть в старых браузерах. Если скрипт содержит аттрибут nomodule, то этот скрипт не будет выполняться в новых браузерах. Благодаря этим атрибутам новые и старые браузеры могут загружать необходимый набор полифиллов. Этот паттерн нельзя использовать, если требуется определение фич выше ES2015.
3) Используя опцию useBuiltins в @babel/preset-env, babel может подключать полфиллы только для тех браузеров, которые были указаны в конфиге. useBuiltins не самое лучшее решение, если необходима поддержка старых браузеров.

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

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

#perfromance #polyfill

https://3perf.com/blog/polyfills/
Том МакРайт — разработчик Mapbox и OpenStreetMap — недавно опубликовал статью про отличия реализаций математических функций в JavaScript-движках — "Math keeps changing".

Однажды Том столкнулся с падающими тестами в своей библиотеке для работы со статистическими функциями. Тесты падали в 12-ой версии Node, в 10-ой всё было ок. Его это заинтересовало, и он пошёл смотреть реализации движков и читать спецификацию.

В спецификации ECMAScript сказано, что в ней нет точного описания поведения математических функций (sin, cos, exp, pow, random, sqrt и т,п,). Разработчики стандарта пошли на такой шаг, чтобы в JavaScript-движках можно было использовать все преимущества нижележащей платформы, например, специфичные команды CPU для работы с тригонометрией. Именно из-за этого падали тесты Тома. Исторически V8 использовал свою собственную библиотеку для математических функций, затем использовал JavaScript-порт fdblibm, сейчас там используется C-версия fdblibm.

Для того чтобы предотвратить подобные ошибки, результат вычислений сравнивают относительно малой величины "эпсилон" — Math.abs(result - expected) < epsilon. Можно также использовать функции из библиотеки stdlib-js, но они работают не так быстро как их соседи из библиотек, скомилированных в нативный код.

В общем, мне статья очень понравилась. Рекомендую почитать.

P.S. Спасибо за ссылку на статью улетает Олегу Ковалёву (@oleg_log)

#js #math

https://macwright.org/2020/02/14/math-keeps-changing.html
Сегодняшний пост будет про софт сикллы. Николас Закас — лид eslint и автор книг про JavaScript — позавчера опубликовал пост про свой подход к решению проблем в программировании, в менеджменте, в быту, — "How I think about solving problems".

При решении любой проблемы Николас задаёт себе пять вопросов:
1) Действительно ли это проблема?
2) Эта проблема должна быть решена?
3) Эта проблема должна быть решена сейчас?
4) Эту проблему должен решать я?
5) Есть ли более простая проблема, которую можно решить вместо этой?

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

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

Статья хорошая, рекомендую почитать.

#productivity #list #musings

https://humanwhocodes.com/blog/2020/02/how-i-think-about-solving-problems
Тим Кадлек — автор нескольких книг про web-производительность — написал статью про поиск проблем производительности с помощью Feature-Policies — "In-Browser Performance Linting With Feature Policies".

Feature-Policies — это http-заголовок, предоставляющий механизм для разрешения или блокирования определённых функций браузера. Например, с помощью него можно запретить доступ к данным геолокации, переход страницы в полноэкранный режим и т.п.

Для поиска проблем производительности Feature-Policies предоставляет несколько директив, с помощью которых можно быстро найти неоптимизированные изображения, изображения без атрибутов height / width, негативно влияющие на пользовательский опыт, синхронные xhr-запросы и т.п. Включить эти политики можно локально во время разработки с помощью браузерных расширений для работы с http-заголовками. Все нарушения политик будут логироваться в консоль, а изображения, превысившие лимит, дополнительно будут заменены на плейсхолдеры, показывающие их текущий объём.

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

#performance #web

https://timkadlec.com/remembers/2020-02-20-in-browser-performance-linting-with-feature-policies/
Недавно вышла новая версия TypeScript. Дениэл Розенвассер рассказал про новые фичи релиза — "Announcing TypeScript 3.8".

С версии 3.8 можно явно указывать, что импортируется/экспортируется тип, а не значение: import type { SomeThing } from "./some-module.js";. Если импортируется только тип, то на этапе транспиляции import удаляется. Иногда из-за этого возникают ошибки в рантайме, например, в Angular.js (1.x) ломалась регистрация сервисов. С появлением более тонкой декларации импортов и новой опции importsNotUsedAsValues теперь можно предотвратить подобные ошибки.

Была добавлена поддержка Private Fields из предложения Class field declarations, с помощью которой можно создавать приватные поля класса #foo = 'bar'. В TypeScript была возможность создания приватных полей с помощью модификатора private, но Private Fields дают настоящую приватность (hard privacy) на уровне цели транспиляции. Также благодаря им решается проблема с перекрытием полей.

Добавили поддержку пропозала top-level await. Эта фича избавляет от необходимости заворачивать в async-функцию код с await. Она работает только для модулей, поэтому, если ваш файл ничего экспортиует/импортирует, для того чтобы заработал top-level await надо будет добавить формальный экспорт export {}.

Реализовали поддержку ещё одного пропозала будущего стандарта export * as ns. Добавили поддержку модификаторов @public, @private, @protected в JSDoc. Очень много изменений было сделано для улучшения вотчинга файлов — теперь в tsconfig.json есть новая группа опций watchOptions. Реализовали "неточную и быструю" инкрементальную сборку, которая позволяет ускорить скорость пересборки проекта за счёт снижения строгости проверок. В редакторах появятся новые пункты меню для конвертации конкатенации строк в шаблонные строки и для визуализации иерархии вызовов функций.

#typenoscript #release #announcement

https://devblogs.microsoft.com/typenoscript/announcing-typenoscript-3-8/
Сегодня столкнулся с циклическими зависимостями в своём проекте. Захотелось посмотреть, как эту проблему решают другие. Нашёл статью Мишеля Вестстрате (автор mobx) — "How to fix nasty circular dependency issues once and for all in JavaScript & TypeScript".

Суть подхода заключается в использовании двух файлов internal.js и index.js. Файл internal.js реэкспортит все локальные модули. Файл index.js (входная точка в библиотеку) реэкспортит содержимое internal.jsexport * from "./internal.js";. Локальные зависимости должны импортировать нужные сущности только из internal.js. В internal.js все реэкспорты размещаются в таком порядке, в котором все зависимости будут корректно разрешены. Благодаря такому подходу можно управлять порядком загрузки модулей.

В итоге пофиксил циклические зависимости по-другому, но взял на заметку подход Мишеля.

#js #esm #trick

https://medium.com/visual-development/how-to-fix-nasty-circular-dependency-issues-once-and-for-all-in-javanoscript-typenoscript-a04c987cf0de
Пару недель назад Мэйсон Фрид из команды разработки 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
Тим Кадлек в статье "When CSS Blocks" рассказал, как паттерн оптимизации загрузки CSS нарушает оптимальный порядок загрузки ресурсов и блокирует парсинг HTML.

Когда браузер парсит страницу и видит, что нужно загрузить css, он останавливает процесс рендеринга страницы и ждёт загрузки CSS. Для загрузки некритичного CSS такое поведение нежелательно, поэтому появился паттерн "preload/polyfill", в котором CSS загружается с помощью <link rel="preload" ...> в неблокирующем режиме. Если preload не поддерживается браузером то в работу вступает небольшой полифилл.

Тут возникает две проблемы: 1) использование preload откладывает загрузку важных ресурсов и некритичный CSS загружается в первую очередь, 2) когда полифилл инициирует загрузку CSS, парсинг html останавливается полностью, таким образом сайт рендерится с задержкой. Тим пишет, что авторы паттерна "preload/polyfill" больше не рекомендуют его использовать, а предлагают использовать трюк с медиа:
<link rel="stylesheet" href="/path/to/my.css" media="print" onload="this.media='all'">


Но устаревший паттерн продолжают использовать по инерции, создавая проблемы с производительностью.

Тим написал ещё одну очень хорошую статью. Рекомендую почитать.

#perfromance #browser #css

https://timkadlec.com/remembers/2020-02-13-when-css-blocks/
Сегодня на youtube-канале Honeypot вышел документальный фильм, посвящённый Vue.js.

В фильме рассказывается про историю появления фреймворка и про людей, стоящих за его разработкой. Vue.js разработал Эван Ю в 2013 году. Сначала проект назывался seed.js, но когда наступил момент публикации пакета в npm, оказалось, что это имя уже было занято. Эван пошёл в Google Translate и посмотрел перевод слова "view" на разные языки, в итоге он выбрал французский вариант — "vue".

Сначала проект разрабатывался для души, когда Эван работал в Google. Работа над Vue открыла новые возможности — Эвана пригласили работать в команду Meteor. В этот период он параллельно занимался разработкой и Vue, и Meteor. Он не был доволен темпами развития Meteor, поэтому решил рискнуть и полностью переключился на разработку Vue. Риск того стоил. Сейчас у Vue большое сообщество, фреймворк используют по всему миру, а в Китае Эван стал практически национальным героем среди разработчиков.

Ламповый и вдохновляющий фильм. Очень рекомендую посмотреть.

#vue #history

https://www.youtube.com/watch?v=OrxmtDw4pVI
На сайте Mozilla Hacks появилась интересная статья Натана Фройда про новый механизма сандбоксинга кода — "Securing Firefox with WebAssembly".

Для предотвращения выполнения вредоносного кода в Firefox используется два подхода: сандбоксинг на уровне процессов и переписывание критичных частей на Rust. Первый подход хороший, но требует много системных ресурсов, переписывание на Rust не всегда самый оптимальный вариант.

Исследователи из Стенфорда, UC и других университетов представили новый инструментарий для более простого сандбоксинга библиотек — RLBox, который сейчас внедряется в Firefox. Его идея состоит в компилировании потенциально небезопасного кода в wasm. Скомпилированный wasm-модуль затем компилируется в нативный код, который может использоваться из любой подсистемы браузера. Данные, которые обрабатываются скомпилированным модулем считаются "испорченными" (tainted), их корректность использования проверяется на этапе компиляции. Если сторонняя библиотека была скомпроментирована, то благодаря дополнительному набору проверок небезопасный код не сможет попасть в браузер. Этот подход уже внедряется в Firefox 74 (Linux) для сандбоксинга библиотеки рендеринга шрифтов Graphite.

WebAssembly давно используется для разработки сложных web-приложений, идёт работа над системным интерфейсом для wasm (WASI), который уже поддерживается в Node.js, и вот сейчас его начинают использовать для изоляции библиотек. WebAssembly становится по-настоящему мощным инструментом.

#security #webassembly #internals

https://hacks.mozilla.org/2020/02/securing-firefox-with-webassembly/
Сегодня вышла новая версия React v16.13.0. Санил Пай рассказал про все изменения в релизе.

Продолжается работа над чисткой кода от устаревших API. Теперь при использовании String Refs в консоль будет лететь deprecated-предупреждение. Также устаревшим методом тперь считается React.createFactory, который использовался для создания компонентов без JSX. Устаревшим методом объявлен unstable_createPortal, вместо него нужно использовать createPortal (достаточно переименовать метод).

Были улучшены сообщения о проблемах. При ошибках гидрации в новой версии отображается стек компонентов, в котором была обнаружена проблема. Теперь отображается предупреждение при смешивании коротких и длинных версий CSS-свойств в style. Делегация вызова setState другому компоненту теперь не поощряется, при таком использовании setState в фазе рендера будет возникать предупреждение (Warning: Cannot update a component from inside the function body of a different component.).

Было сделано несколько улучшений. Добавлена забытая проверка двойного вызова shouldComponentUpdate в React Strict Mode для обнаружения нежелательных сайд-эффектов. onMouseEnter больше не вызывается на неактивном <button>.

#react #release #announcement

https://reactjs.org/blog/2020/02/26/react-v16.13.0.html
Пару недель назад инженеры из Netflix рассказали про новый открытый формат изображений — "AVIF for Next-Generation Image Coding".

Вопрос качества и объёма передаваемых изображений для Netflix стоит особенно остро, поэтому они присоединились к разработке нового формата изображений AVIF на базе кодека AV1, который в свою очередь используется для кодирования видео. На данный момент это один из самых лучших форматов, который превосходит по качеству webp, который был разработан на базе кодека предыдущего поколения VP8. AVIF поддерживает High Dynamic Range (HDR), Wide Color Gamut (WCG) и Standard Dynamic Range (SDR). Для сравнения качества сжатия разных кодеков был разработан специальный фреймворк. Результаты сравнения показали преимущество AVIF.

В ближайшем будущем стоит ожидать появления поддержки AVIF в браузерах — работа над добавлением AVIF в Chrome уже началась. Также The Alliance for Open Media разрабатывает свободную библиотеку для работы с новым форматом. В мае прошлого года поддержка AVIF была добавлена в Windows 10.

#image #codec #optimization

https://netflixtechblog.com/avif-for-next-generation-image-coding-b1d75675fe4
Forwarded from Веб-стандарты (Веб-стандарты)
Прямая трансляция конференции Я ︎ Фронтенд 2020 с докладами про глазные интерфейсы, семантику, ApolloClient, роутеры, картинки, BFCache, пет-проджекты и менторство. Начало в 11:00 (GMT+3) — https://youtu.be/eLlULhNNthI, программа — https://ilovefrontend.ru
Пару дней назад Себастьян Маккензи — отец Babel и Yarn — представил новый проект Rome. Джейсон Миллер сделал небольшой обзор нового инструмента — "Rome, a new JavaScript Toolchain".

Rome включает в себя траспилятор, линтер, сборщик, тест-раннер и инструмент для форматирования кода. Можно сказать, что это швейцарский нож для работы с JavaScript-экосистемой. Его главное отличие от подобных инструментов заключается в том, что все этапы обработки кода обслуживаются единым ядром. В теории это может ускорить сборку, линтинг и прогон тестов, так как на каждом этапе не надо будет анализировать и преобразовывать один и тот же код повторно — результат преобразования кода берётся из общего кэша.

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

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

#js #experimental #tool

https://jasonformat.com/rome-javanoscript-toolchain/
https://github.com/facebookexperimental/rome
Нашёл интересную статью Яна Моншке из Soundcloud про оптимизацию потребления памяти в Redux-приложении — "Garbage Collection in Redux Applications".

При портировании Soundcloud на Xbox One разработчики столкнулись с тем, что операционная система закрывала работающее в фоне приложение, когда потребляемая память превышала 128Мб. Проблема оказалась в Redux-сторе — данные треков, которые уже были не нужны, продолжали лежать в памяти.

Для решения проблемы удаления устаревших данных разработчики реализовали подобие алгоритма сборки мусора mark-and-sweep. В их случае фаза "mark" работает с помощью кастомного коннектора стора, который отслеживает данные, которые нужны для отображения примонтированных компонентов. Фаза "sweep" реализована как обычный редюсер, который начинает работать при получении экшена, который сигнализирует о запросе начать повторное формирование стора на основе информации собранных на этапе "mark". В конце процесса получается новый стор, в котором лежат только актуальные объекты.

Рекомендую посмотреть статью, если столкнулись с проблемой потребления памяти в Redux-приложении.

#statemanagement #performance #react

https://developers.soundcloud.com/blog/garbage-collection-in-redux-applications?ref=mdbootstrap.com