Сегодня меня занесло в 2015-ый год. Прочитал статью Джека Арчибальда про старые баги браузеров с планированием микрозадач — "Tasks, microtasks, queues and schedules".
Если выполнить такой код:
то в консоль будет выведено: "noscript start", "noscript end", "promise", "setTimeout". Такой порядок объясняется тем, что очередь микрозадач (куда попадают выполнение коллбеков MutationObserver и коллбеки промисов) опустошается до выполнения следующей задачи, которая в данном случае создаётся с помощью setTimeout.
В статье описываются ситуации, когда обработка микрозадач обрабатывалась браузерами по-разному. Например, при обработке коллбеков MutationObserver и Promise в рамках одной задачи.
Проверил примеры — браузеры уже пофиксили описанные проблемы. Но всё равно рекомендую почитать статью, если она прошла мимо вас.
#async #history
https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/
Если выполнить такой код:
console.log('noscript start');
setTimeout(() => console.log('setTimeout'), 0);
Promise.resolve().then(() => console.log('promise'));
console.log('noscript end');то в консоль будет выведено: "noscript start", "noscript end", "promise", "setTimeout". Такой порядок объясняется тем, что очередь микрозадач (куда попадают выполнение коллбеков MutationObserver и коллбеки промисов) опустошается до выполнения следующей задачи, которая в данном случае создаётся с помощью setTimeout.
В статье описываются ситуации, когда обработка микрозадач обрабатывалась браузерами по-разному. Например, при обработке коллбеков MutationObserver и Promise в рамках одной задачи.
Проверил примеры — браузеры уже пофиксили описанные проблемы. Но всё равно рекомендую почитать статью, если она прошла мимо вас.
#async #history
https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/
Jakearchibald
Tasks, microtasks, queues and schedules
When I told my colleague Matt Gaunt I was thinking of writing a piece on microtask queueing and execution within the browser's event loop, he said "I'll be honest with you Jake, I'm not going to read that". Well, I've written it anyway, so we're all going…
Филип Уолтон написал про свою идею использования нативных модулей в качестве выходного формата бандла — "Using Native JavaScript Modules in Production Today".
На данный момент самый популярный бандлер Webpack не поддерживает нативные модули в качестве выходного формата. Если вы посмотрите внутрь бандла, то увидите вместе с кодом модуля бойлерплейт-код для его инициализации. У менее популярного бандлера Rollup есть поддержка esm в качестве выходного формата. Использование нативных модулей даёт несколько преимуществ: выходной бандл получается меньше в объёме и нативные модули можно эффективно загружать с помощью хинта
В статье подробно разбирается, как реализовать описанный подход на практике. Статью стоит почитать и взвесить все за и против использования описанного подхода в своём проекте.
#performance #rollup #esm
https://philipwalton.com/articles/using-native-javanoscript-modules-in-production-today/
На данный момент самый популярный бандлер Webpack не поддерживает нативные модули в качестве выходного формата. Если вы посмотрите внутрь бандла, то увидите вместе с кодом модуля бойлерплейт-код для его инициализации. У менее популярного бандлера Rollup есть поддержка esm в качестве выходного формата. Использование нативных модулей даёт несколько преимуществ: выходной бандл получается меньше в объёме и нативные модули можно эффективно загружать с помощью хинта
modulepreload (только в Chrome).В статье подробно разбирается, как реализовать описанный подход на практике. Статью стоит почитать и взвесить все за и против использования описанного подхода в своём проекте.
#performance #rollup #esm
https://philipwalton.com/articles/using-native-javanoscript-modules-in-production-today/
Philipwalton
Using Native JavaScript Modules in Production Today
Thoughts on web development, open source, software architecture, and the future.
Фараз Келини написал хорошую статью про BigInt — предложение добавления в стандарт JavaScript — "The Essential Guide To JavaScript’s Newest Data Type: BigInt".
BigInt-числа выглядят как обычные, но с суффиксом
На данный момент пропозал BigInt находится на stage 3. Его поддержка есть в Chrome, Firefox и последней версии Edge. Создать полноценный полифилл для BigInt невозможно, поэтому в статье предлагается использовать библиотеку JSBI для поддержки старых версий браузеров.
В общем, рекомендую почитать статью. Скорее всего
#js #proposal
https://www.smashingmagazine.com/2019/07/essential-guide-javanoscript-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-javanoscript-newest-data-type-bigint/
Smashing Magazine
The Essential Guide To JavaScript’s Newest Data Type: BigInt — Smashing Magazine
In JavaScript, the Number type cannot safely represent integer values larger than 2⁵³. This limitation has forced developers to use inefficient workarounds and third-party libraries. BigInt is a new data type intended to fix that.
Упоминание iframe часто вызывает негативные ассоциации с рекламой и отслеживанием пользователей. И это плохо, потому что те возможности, которые они предоставляют, могут быть полезны при разработке web-приложений. Дениэл Брайн из PayPal написал статью с мыслями о том, как разработчики браузеров могут улучшить iframe — "Iframes are just terrible. Here’s how they could be better".
PayPal для обхода ограничений iframe создал библиотеку zoid, с помощью которой можно облегчить работу при создании кросс-доменных компонентов. Но эта библиотека не решает и не решит всех проблем. Например, угон кликов (clickjacking), может быть предотвращён только на уровне браузеров, если в них будет реализована проверка прозрачности iframe и обнаружение перекрытых элементов. Также сейчас невозможно без использования инструментов разработчика определить ресурс, который отображается внутри в iframe. С точки зрения безопасности пользователей это большая проблема. Ещё в статье затрагивается сложность получения ссылки на объект window, проблемы при работе с cookie и низкий приоритет загрузки содержимого.
Статью прочитать стоит, если вам интересно узнать про ограничения использования iframe в современном web'е.
#musgins #web
https://medium.com/@bluepnume/iframes-are-just-terrible-heres-how-they-could-be-better-974b731f0fb4
PayPal для обхода ограничений iframe создал библиотеку zoid, с помощью которой можно облегчить работу при создании кросс-доменных компонентов. Но эта библиотека не решает и не решит всех проблем. Например, угон кликов (clickjacking), может быть предотвращён только на уровне браузеров, если в них будет реализована проверка прозрачности iframe и обнаружение перекрытых элементов. Также сейчас невозможно без использования инструментов разработчика определить ресурс, который отображается внутри в iframe. С точки зрения безопасности пользователей это большая проблема. Ещё в статье затрагивается сложность получения ссылки на объект window, проблемы при работе с cookie и низкий приоритет загрузки содержимого.
Статью прочитать стоит, если вам интересно узнать про ограничения использования iframe в современном web'е.
#musgins #web
https://medium.com/@bluepnume/iframes-are-just-terrible-heres-how-they-could-be-better-974b731f0fb4
Medium
Iframes are just terrible. Here’s how they could be better.
Earlier this year I gave a talk at FullStack conference in London about making iFrames cool again (sorry, you have to log in to see the…
Вчера вышла новая версия TypeScript. Команда разработчиков рассказала о том, что появилось нового в этом релизе — "Announcing TypeScript 3.6".
Были переработаны типы
Появилась поддержка хелпера
Улучшили тулинг. Теперь TS понимает тип модульной системы при автоматическом импорте. Не вставляет точки с запятыми в тех файлах, где они не используются. Было добавлено новое API для инкрементальной сборки, что позволит сборщикам и таск-раннерам использовать результаты предыдущей сборки, ускоряя сборку проекта. Был переделан playground — теперь на сайте используется форк популярного плейграунда Артёма Тюрина.
#typenoscript #release
https://devblogs.microsoft.com/typenoscript/announcing-typenoscript-3-6/
Были переработаны типы
Iterator и IteratorResult. Улучшена типизация генераторов. Теперь для них есть выделенный тип Generator. Его появление позволяет статически определять возвращаемый тип, yield-тип, и тип, который может принимать next.Появилась поддержка хелпера
__spreadArrays для более корректного представления результата преобразования spread-оператора. Улучшили подсказки при работе с промисами: теперь TS может подсказать про забытый await. Улучшили поддержку Unicode-символов в идентификаторах. get и set теперь разрешено использовать в ambient contexts (declare и d.ts-файлы). Декларирование функций-классов, которые инстанцируют объекты с оператором new и обычным вызовом, теперь более интуитивно — ambient классы и функции могут сливаться.Улучшили тулинг. Теперь TS понимает тип модульной системы при автоматическом импорте. Не вставляет точки с запятыми в тех файлах, где они не используются. Было добавлено новое API для инкрементальной сборки, что позволит сборщикам и таск-раннерам использовать результаты предыдущей сборки, ускоряя сборку проекта. Был переделан playground — теперь на сайте используется форк популярного плейграунда Артёма Тюрина.
#typenoscript #release
https://devblogs.microsoft.com/typenoscript/announcing-typenoscript-3-6/
Microsoft News
Announcing TypeScript 3.6
Today we’re happy to announce the availability of TypeScript 3.6! For those unfamiliar, TypeScript is a language that builds on JavaScript by adding optional static types. These types can be checked by the TypeScript compiler to catch common errors in your…
Недавно в блоге v8 Бенедикт Мойрер и Матиас Байненс написали пост про расследование причин деградации производительности в React — "The story of a V8 performance cliff in React".
В декабре прошлого года разработчики React столкнулись со странным поведением v8. Если было запущено профилирование, то падала производительность кода во время фазы commit. Как оказалось, проблема заключалась в следующем коде:
V8 внутри использует разные представления для чисел. Для 32-битных целых чисел используется small integer (Smi), для чисел с плавающей запятой — HeapNumber и MutableHeapNumber. Для создаваемых объектов v8 применяет оптимизации для снижения потребления памяти. Одна из таких оптимизаций гарантирует эффективное переиспользование памяти, если создаются похожие друг на друга объекты.
В коде класса FiberNode, который работал во время профилирования, значение поля объекта, на котором был применён preventExtensions, менялось со Smi на HeapNumber. Этот кейс не был учён в v8, и движок начинал аллоцировать дополнительную память. Видимая просадка производительности происходила из-за того, что в реальном React-приложении создаётся десятки тысяч объектов такого типа.
Баг был исправлен в v8, но разработчики React смогли устранить проблему раньше на своей стороне. Для этого они стали инициализировать поле объекта HeapNumber'ом (this.actualStartTime = NaN). В конце статьи Бенедикт и Матиас рекомендуют инициализировать поля объекта такими значениями, внутреннее представление которых не будет меняться со временем.
Мне статья понравилась. Рекомендую, прочитать всем, кто интересуется внутренностями v8.
#v8 #internals #performance
https://v8.dev/blog/react-cliff
В декабре прошлого года разработчики React столкнулись со странным поведением v8. Если было запущено профилирование, то падала производительность кода во время фазы commit. Как оказалось, проблема заключалась в следующем коде:
class FiberNode {
constructor() {
this.actualStartTime = 0;
Object.preventExtensions(this);
}
}
const node1 = new FiberNode();
const node2 = new FiberNode();V8 внутри использует разные представления для чисел. Для 32-битных целых чисел используется small integer (Smi), для чисел с плавающей запятой — HeapNumber и MutableHeapNumber. Для создаваемых объектов v8 применяет оптимизации для снижения потребления памяти. Одна из таких оптимизаций гарантирует эффективное переиспользование памяти, если создаются похожие друг на друга объекты.
В коде класса FiberNode, который работал во время профилирования, значение поля объекта, на котором был применён preventExtensions, менялось со Smi на HeapNumber. Этот кейс не был учён в v8, и движок начинал аллоцировать дополнительную память. Видимая просадка производительности происходила из-за того, что в реальном React-приложении создаётся десятки тысяч объектов такого типа.
Баг был исправлен в v8, но разработчики React смогли устранить проблему раньше на своей стороне. Для этого они стали инициализировать поле объекта HeapNumber'ом (this.actualStartTime = NaN). В конце статьи Бенедикт и Матиас рекомендуют инициализировать поля объекта такими значениями, внутреннее представление которых не будет меняться со временем.
Мне статья понравилась. Рекомендую, прочитать всем, кто интересуется внутренностями v8.
#v8 #internals #performance
https://v8.dev/blog/react-cliff
v8.dev
The story of a V8 performance cliff in React · V8
This article describes how V8 chooses optimal in-memory representations for various JavaScript values, and how that impacts the shape machinery — all of which helps explain a recent V8 performance cliff in React core.
В блоге WebKit появилась статья про проблему повышенного энергопотребления web-контентом — "How Web Content Can Affect Power Usage".
Повышенное энергопотребление очень критично для мобильных устройств. Основные потребители энергии — экран, CPU, GPU и сеть. Экран потребляет энергию предсказуемо, чего нельзя сказать про CPU, GPU и сеть. Энергопотребление CPU, GPU и сети напрямую зависят от текущей выполняемой задачи (парсинг страницы, рендеринг, выполнение JavaScript).
Когда страница переходит в неактивный режим (переключение на другую вкладку) браузеры могут приостановить выполняемый на странице код. В Safari на iOS работа внутри вкладки при первой возможности полностью останавливается. Тем не менее такие "замороженные" вкладки могут вызывать потребление CPU, если на странице работают таймеры, установленные с помощью
Статья хорошая. Она рассказывает про особенности работы WebKit на Apple-устройствах, но тем не менее большая часть статьи актуальна для всех браузеров.
#webkit #mobile
https://webkit.org/blog/8970/how-web-content-can-affect-power-usage/
Повышенное энергопотребление очень критично для мобильных устройств. Основные потребители энергии — экран, CPU, GPU и сеть. Экран потребляет энергию предсказуемо, чего нельзя сказать про CPU, GPU и сеть. Энергопотребление CPU, GPU и сети напрямую зависят от текущей выполняемой задачи (парсинг страницы, рендеринг, выполнение JavaScript).
Когда страница переходит в неактивный режим (переключение на другую вкладку) браузеры могут приостановить выполняемый на странице код. В Safari на iOS работа внутри вкладки при первой возможности полностью останавливается. Тем не менее такие "замороженные" вкладки могут вызывать потребление CPU, если на странице работают таймеры, установленные с помощью
setTimeout и setInterval или происходит работа с сетью. С помощью Page Visibility API и события blur можно отслеживать, когда страница перестаёт быть видимой или становится неактивной и, например, ставить на паузу обновление UI или отключать анимации.Статья хорошая. Она рассказывает про особенности работы WebKit на Apple-устройствах, но тем не менее большая часть статьи актуальна для всех браузеров.
#webkit #mobile
https://webkit.org/blog/8970/how-web-content-can-affect-power-usage/
WebKit
How Web Content Can Affect Power Usage
Users spend a large proportion of their online time on mobile devices, and a significant fraction of the rest is users on untethered laptop computers.
Валерий Карпов написал статью, посвящённую Symbol — "A Practical Guide to Symbols in JavaScript".
Symbol — это новый тип данных, который появился в ES2015. Символы могут использоваться в качестве ключа объекта. Они создаются с помощью функции
При создании символов с помощью
Статья небольшая, но хорошая. Рекомендую прочитать, если эта тема прошла мимо вас.
#js #es2015
http://thecodebarbarian.com/a-practical-guide-to-symbols-in-javanoscript.html
Symbol — это новый тип данных, который появился в ES2015. Символы могут использоваться в качестве ключа объекта. Они создаются с помощью функции
Symbol() и Symbol.for(), которые принимают на вход стоку-описание.При создании символов с помощью
Symbol() они гарантировано будут разными. Благодаря этой особенности можно отчётливо разграничивать пользовательские и программные данные. Например, в ES2015 символ Symbol.iterator используется для задания функции, которая будет вызываться при использовании for...of. При создании такого итератора его никто не сможет изменить по ошибке. При использовании Symbol.for('name') создаваемый символ сохраняется в глобальный реестр и становится доступен из разных мест программы при повторном вызове Symbol.for('name').Статья небольшая, но хорошая. Рекомендую прочитать, если эта тема прошла мимо вас.
#js #es2015
http://thecodebarbarian.com/a-practical-guide-to-symbols-in-javanoscript.html
The Code Barbarian
A Practical Guide to Symbols in JavaScript
Symbols, what are they good for? Here's some practical examples of what symbols are useful for in JavaScript.
Прочитал статью, в которой ребята из Miro поделились опытом работы с текстами в canvas — "Как мы учились рисовать тексты на Canvas".
Во время переезда Miro с Flash на JavaScript + Canvas появилась проблема при работе с текстами. Надо было бесшовно отображать текст и мини-редактор. Первое решение использовало
В статье очень много технических подробностей. Читать стоит, если делаете что-то подобное у себя в проекте или если просто интересно.
#rendering #canvas
https://habr.com/ru/company/miro/blog/458624/
Во время переезда Miro с Flash на JavaScript + Canvas появилась проблема при работе с текстами. Надо было бесшовно отображать текст и мини-редактор. Первое решение использовало
foreignObject из noscript. С его помощью можно "положить" любой html внутрь noscript в качестве изображения. От этого решения пришлось отказаться, когда появилось новое требование — необходимо было добавить поддержку разных шрифтов. Как пишет автор, была проблема с тем, что происходила загрузка шрифтов для каждой внедряемой картинки. В итоге им пришлось реализовать свою библиотеку для отрисовки текста на canvas. На небольших объёмах текста библиотека работает быстрее решения с foreignObject. Похоже, что библиотека не open source, так как никаких ссылок на код не нашёл.В статье очень много технических подробностей. Читать стоит, если делаете что-то подобное у себя в проекте или если просто интересно.
#rendering #canvas
https://habr.com/ru/company/miro/blog/458624/
Хабр
Как мы учились рисовать тексты на Canvas
Мы разрабатываем платформу для визуальной коллаборации. Для отображения контента мы используем Canvas: на нём рисуется всё, в том числе тексты. Готового решения для отображения текстов на Canvas...
Брайан Робинсон написал у себя в блоге статью про использование
Свойство
Советую посмотреть в статье хороший пример flexbox-раскладки, использующей gap (на данный момент работает только в Firefox).
#layout #css
https://bryanlrobinson.com/blog/gap-provides-bright-future-for-margins-in-flex-as-well-as-grid/
gap с flexbox'ами — "CSS Gap creates a bright future for margins in Flex as well as Grid".Свойство
gap в flexbox пришло из grid'ов. Раньше, для того чтобы сделать одинаковые расстояния между элементами, надо было указывать соответствующие расстояния с помощью margin. С приходом gap это стало немного проще:.flex-container {
display: flex;
gap: 1rem;
}Советую посмотреть в статье хороший пример flexbox-раскладки, использующей gap (на данный момент работает только в Firefox).
#layout #css
https://bryanlrobinson.com/blog/gap-provides-bright-future-for-margins-in-flex-as-well-as-grid/
Bryanlrobinson
CSS Gap creates a bright future for margins in Flex as well as Grid
In this tutorial, we'll take a look at how we've added margins in the past with Flex and how gap makes it so we can have these internal margins with no hacks.
Вчера вышел свежий релиз Firefox. Как обычно на Mozilla Hacks вышла статья с обзором новинок — "Firefox 69 — a tale of Resize Observer, microtasks, CSS, and DevTools".
Для пользователей самое большое изменение — включение по умолчанию опции предотвращения трекинга (Enhanced Tracking Protection). Теперь можно отключить автоматическое воспроизведение видео, не имеет значения со звуком оно или нет.
Для разработчиков тоже сделали много улучшений. Теперь Firefox поддерживает публичные поля классов в JavaScript. Добавление поддержки приватных полей (те, что начинаются с символа
В инструментах разработчика было добавлено пошаговое выполнение кода для асинхронных функций. Появилась возможность установки брекпойнтов на разные события: пользовательские (
#firefox #release
https://hacks.mozilla.org/2019/09/firefox-69-a-tale-of-resize-observer-microtasks-css-and-devtools/
Для пользователей самое большое изменение — включение по умолчанию опции предотвращения трекинга (Enhanced Tracking Protection). Теперь можно отключить автоматическое воспроизведение видео, не имеет значения со звуком оно или нет.
Для разработчиков тоже сделали много улучшений. Теперь Firefox поддерживает публичные поля классов в JavaScript. Добавление поддержки приватных полей (те, что начинаются с символа
# вначале) обещают в одном из следующих релизов. Реализован Resize Observer API. С помощью него можно зарегистрировать observer, который будет реагировать на изменение геометрии блочных элементов (некая JavaScript-альтернатива обсуждаемым в сообществе element queries). Добавлен новый метод self.queueMicrotask() для регистрации микрозадач, которые будут выполнены до передачи управления в event-loop. Эта фича позволит упростить реализацию фреймворков и обеспечит предсказуемость при работе с асинхронным кодом в разных браузерах. Появились CSS-свойства overflow-block и overflow-inline, обеспечивающие управление переполнением в блочном и инлайн элементах. Это свойство полезно при локализации страниц на те языки, которые используют разные направления письма. С помощью @supports теперь можно проверять поддержку новых типов селекторов.В инструментах разработчика было добавлено пошаговое выполнение кода для асинхронных функций. Появилась возможность установки брекпойнтов на разные события: пользовательские (
keypup, keydown ) и программные ( onanimationend ). Добавлена удалённая отладка, то есть теперь доступен дебаг других запущенных инстансов Firefox на одной и той же машине или в пределах локальной сети.#firefox #release
https://hacks.mozilla.org/2019/09/firefox-69-a-tale-of-resize-observer-microtasks-css-and-devtools/
Mozilla Hacks – the Web developer blog
Firefox 69 — a tale of Resize Observer, microtasks, CSS, and DevTools
For our latest excellent adventure, we’ve gone and cooked up a new Firefox release. Version 69 features a number of great new additions including JavaScript public instance fields, the Resize ...
Франсуа Бофор из Google написал туториал про использование GPU-вычисления в web'е — "Get started with GPU Compute on the Web".
Возможности для GPU-вычислений предоставляет разрабатываемый стандарт WebGPU. Благодаря этому стандарту из web-приложений будут доступны все возможности современных видеокарт. После появления полноценной поддержки API в браузерах, наибольшую пользу получат те приложения, основная задача которых сводится к выполнению однотипных операций на большом количестве данных (например, приложения, использующие алгоритмы машинного обучения).
В статье очень подробно разбирается пример реализации умножения матриц. Объясняются понятия command encoder, bind group, bind group layout. Разбирается шейдер для перемножения матриц. Шейдеры пишутся на языке GLSL (в будущих версиях стандарта язык может поменяться).
Туториал хороший. Рекомендую посмотреть.
#webgpu #future
https://developers.google.com/web/updates/2019/08/get-started-with-gpu-compute-on-the-web
Возможности для GPU-вычислений предоставляет разрабатываемый стандарт WebGPU. Благодаря этому стандарту из web-приложений будут доступны все возможности современных видеокарт. После появления полноценной поддержки API в браузерах, наибольшую пользу получат те приложения, основная задача которых сводится к выполнению однотипных операций на большом количестве данных (например, приложения, использующие алгоритмы машинного обучения).
В статье очень подробно разбирается пример реализации умножения матриц. Объясняются понятия command encoder, bind group, bind group layout. Разбирается шейдер для перемножения матриц. Шейдеры пишутся на языке GLSL (в будущих версиях стандарта язык может поменяться).
Туториал хороший. Рекомендую посмотреть.
#webgpu #future
https://developers.google.com/web/updates/2019/08/get-started-with-gpu-compute-on-the-web
Chrome for Developers
Get started with GPU Compute on the web | Capabilities | Chrome for Developers
This post explores the experimental WebGPU API through examples and helps you get started with performing data-parallel computations using the GPU.
Фред Шот — автор библиотеки pika — опубликовал статью с рекомендациями по настройке bundler-free окружения для разработки современных web-приложений — "Building without bundling: How to do more with less".
Может возникнуть резонный вопрос: "Зачем избавляться от бандлера?". В начале статьи Фред подсчитывает количество времени, которое отнимает у разработчиков сборка проекта. Для больших проектов, которые запускаются за 42 секунды и пересобираются за 11 секунд, время ожидания может занимать более часа (для 40-часовой рабочей недели).
Если вы используете у себя в проекте модульную систему из ES2015, сборка проекта необязательна, так как все современные браузеры уже поддерживают модульность в JS. Проблема остаётся с node_modules, которые могут содержать спецификаторы, которые браузер не сможет разрезолвить, или с node-специфичным кодом, например,
Описанный в статье подход — это возврат к той простоте, с которого начинался web. Очень рекомендую прочитать статью, если у вас большое приложение, которое собирается долго и вы хотите что-то с этим сделать.
#bundler #web #dx
https://blog.logrocket.com/building-without-bundling/
Может возникнуть резонный вопрос: "Зачем избавляться от бандлера?". В начале статьи Фред подсчитывает количество времени, которое отнимает у разработчиков сборка проекта. Для больших проектов, которые запускаются за 42 секунды и пересобираются за 11 секунд, время ожидания может занимать более часа (для 40-часовой рабочей недели).
Если вы используете у себя в проекте модульную систему из ES2015, сборка проекта необязательна, так как все современные браузеры уже поддерживают модульность в JS. Проблема остаётся с node_modules, которые могут содержать спецификаторы, которые браузер не сможет разрезолвить, или с node-специфичным кодом, например,
process.env.NODE_ENV. Для решения этих проблем Фред предлагает использовать его библиотеку pika, которая преобразует код из node_modules в esm-бандлы. По сравнению с традиционными бандлерами у такого подхода есть преимущество — это преобразование надо запустить только один раз после npm install. Для работы с JSX предлагается использовать библиотеку htm.Описанный в статье подход — это возврат к той простоте, с которого начинался web. Очень рекомендую прочитать статью, если у вас большое приложение, которое собирается долго и вы хотите что-то с этим сделать.
#bundler #web #dx
https://blog.logrocket.com/building-without-bundling/
LogRocket Blog
Building without bundling: How to do more with less - LogRocket Blog
@pika/web enables front-end software developers to choose whether or not they use a bundler when building fully-featured web apps.
Пару дней назад была представлена web-версия Apple Music. Web-версия также как и десктопная использует Ember, но с добавлением web-компонентов. Макс Линч — один из создателей Ionic — написал свои мысли по этому поводу в статье "Apple Just Shipped Web Components to Production and You Probably Missed It".
Макс пишет о том, что в сообществе очень много споров по поводу компонентных js-фреймворков и web-компонентов, так как они решают по сути одну и ту же задачу создания интерфейсов из переиспользуемых блоков. Тот факт, что Apple использует почти 50 компонентов у себя в приложении (нотификации, контролы для управления подкастами, видеоплейер и т.п.) говорит о том, что существует ниша для их применения. Например, их можно использовать для создания таких компонентов, которые могут быть использованы с разными фреймворками (скорее всего Apple решает именно эту задачу). Для создания web-компонентов в Apple music используется SencilJS, которая служит основой для Ionic.
Здорово видеть примеры удачного использования современных возможностей web-платформы в больших приложениях.
#webcomponents #ember #jsframeworks
https://dev.to/ionic/apple-just-shipped-web-components-to-production-and-you-probably-missed-it-57pf
Макс пишет о том, что в сообществе очень много споров по поводу компонентных js-фреймворков и web-компонентов, так как они решают по сути одну и ту же задачу создания интерфейсов из переиспользуемых блоков. Тот факт, что Apple использует почти 50 компонентов у себя в приложении (нотификации, контролы для управления подкастами, видеоплейер и т.п.) говорит о том, что существует ниша для их применения. Например, их можно использовать для создания таких компонентов, которые могут быть использованы с разными фреймворками (скорее всего Apple решает именно эту задачу). Для создания web-компонентов в Apple music используется SencilJS, которая служит основой для Ionic.
Здорово видеть примеры удачного использования современных возможностей web-платформы в больших приложениях.
#webcomponents #ember #jsframeworks
https://dev.to/ionic/apple-just-shipped-web-components-to-production-and-you-probably-missed-it-57pf
DEV Community
Apple Just Shipped Web Components to Production and You Probably Missed It
The biggest news of the Apple Music Web Client launch you probably missed
В блоге NPM была опубликована статья, посвящённая проблемам безопасности при работе с зависимостями, — "AppSec POV on Dependency Management".
В статье рассматриваются подходы, которые могут снизить риск атаки. Первое, на что стоит обращать внимание при выборе пакета, метрики качества (наличие тестов, актуальные версии зависимостей и т.п.) Стоит посмотреть на активность поддержки пакета. Если версии выходят нерегулярно или последнее обновление выходило очень давно, есть риск, что пакет может попасть в руки злоумышленников. Именно это произошло с пакетом event-stream в прошлом году.
Есть пара советов, что делать при исследовании потенциально-опасных пакетов. Для безопасной установки можно использовать
Статья очень толковая. Очень рекомендую почитать... Пойду-ка проверю зависимости в своих проектах.
#npm #security
https://blog.npmjs.org/post/187496869845/appsec-pov-on-dependency-management
В статье рассматриваются подходы, которые могут снизить риск атаки. Первое, на что стоит обращать внимание при выборе пакета, метрики качества (наличие тестов, актуальные версии зависимостей и т.п.) Стоит посмотреть на активность поддержки пакета. Если версии выходят нерегулярно или последнее обновление выходило очень давно, есть риск, что пакет может попасть в руки злоумышленников. Именно это произошло с пакетом event-stream в прошлом году.
Есть пара советов, что делать при исследовании потенциально-опасных пакетов. Для безопасной установки можно использовать
npm install --ignore-noscripts. В этом случае скрипты установки не будут выполняться. Можно запустить npm audit для проверки наличия уязвимостей в зависимостях. Для того чтобы можно было запустить аудит без установки пакетов, следует использовать флаг --package-lock-only.Статья очень толковая. Очень рекомендую почитать... Пойду-ка проверю зависимости в своих проектах.
#npm #security
https://blog.npmjs.org/post/187496869845/appsec-pov-on-dependency-management
blog.npmjs.org
npm Blog Archive: AppSec POV on Dependency Management
npm Blog (Archive); updates from the npm team are now published on the GitHub Blog and the GitHub Changelog
Эяль Эйзенберг из Wix рассказал про свой опыт уменьшения бандла приложения с помощью React Lazy/Suspense и код-сплиттинга — "Trim the Fat From Your Bundles Using Webpack Analyzer & React Lazy/Suspense".
В начале статьи автор пишет про меры, которые можно предпринять на этапе разработки, чтобы размер приложения внезапно не вырос. Для оценки размера подключаемой библиотеки её стоит проверить c помощью сервиса Bundlephobia. Для того чтобы размер импортируемых библиотек всегда был на виду, можно использовать плагин import-cost (есть поддержка VS Code, Vim, WebStorm, Atom). Далее в статье разбирается пример динамической загрузки кода с помощью React.lazy и React.Suspense, который позволяет вынести часть кода в отдельный чанк. Выглядит он так:
После всех оптимизаций размер бандла удалось уменьшить на 80%.
Статья хорошая с примерами из реальной практики. Если не знаете, куда копать при оптимизации размера приложения на React, то эта статья может помочь.
#performance #webpack #react
https://www.wix.engineering/post/trim-the-fat-from-your-bundles-using-webpack-analyzer-react-lazy-suspense
В начале статьи автор пишет про меры, которые можно предпринять на этапе разработки, чтобы размер приложения внезапно не вырос. Для оценки размера подключаемой библиотеки её стоит проверить c помощью сервиса Bundlephobia. Для того чтобы размер импортируемых библиотек всегда был на виду, можно использовать плагин import-cost (есть поддержка VS Code, Vim, WebStorm, Atom). Далее в статье разбирается пример динамической загрузки кода с помощью React.lazy и React.Suspense, который позволяет вынести часть кода в отдельный чанк. Выглядит он так:
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<React.Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</React.Suspense>
</div>
);
}После всех оптимизаций размер бандла удалось уменьшить на 80%.
Статья хорошая с примерами из реальной практики. Если не знаете, куда копать при оптимизации размера приложения на React, то эта статья может помочь.
#performance #webpack #react
https://www.wix.engineering/post/trim-the-fat-from-your-bundles-using-webpack-analyzer-react-lazy-suspense
Wix Engineering
Trim the Fat From Your Bundles Using Webpack Analyzer & React Lazy/Suspense
As client side applications become more complex, their bundle sizes become bigger and bigger. Devices and regions with slower connections suffer the most from increasing bundle sizes and it’s just getting worse every day. In this post I will go over a real…
Михай Парпарита из Quip написал статью про то, как они отлаживают своё приложение — "How Quip Builds In-Product Debugging Tools".
Основная мысль статьи — стоит немного потрудиться и сделать инструмент, который будет помогать в отладке. Такая инвестиция времени быстро возместится в будущем.
Quip использует много подобных инструментов. Например, для визуализации взаимосвязи уровня данных и представления у них есть "Overlay Id", который для каждого компонента показывает соответствующие данные модели. Есть инструмент для отладки редактора, который в инлайн-режиме отображает отладочную информацию об отображаемых сущностях. Такой подход исключает затраты времени на открытие инструментов разработчика и потерю фокуса из редактора. Есть небольшой инструмент, который показывает в оверлее количество ререндеров компонента. Реализуется он так: в каждый компонент инжектится
Мне статья понравилась. В ней есть интересные идеи, которые можно применить в своём проекте.
#dx #debug
https://quip.com/blog/how-quip-builds-inproduct-debugging-tools
Основная мысль статьи — стоит немного потрудиться и сделать инструмент, который будет помогать в отладке. Такая инвестиция времени быстро возместится в будущем.
Quip использует много подобных инструментов. Например, для визуализации взаимосвязи уровня данных и представления у них есть "Overlay Id", который для каждого компонента показывает соответствующие данные модели. Есть инструмент для отладки редактора, который в инлайн-режиме отображает отладочную информацию об отображаемых сущностях. Такой подход исключает затраты времени на открытие инструментов разработчика и потерю фокуса из редактора. Есть небольшой инструмент, который показывает в оверлее количество ререндеров компонента. Реализуется он так: в каждый компонент инжектится
componentDidUpdate, который увеличивает счётчик и записывает его в data-атрибут. Значение атрибута отображается поверх компонента с помощью CSS:.debug-react-rerender-count:after {
content: attr(data-debug-react-rerender-count);
// other styles for positioning and color
}Мне статья понравилась. В ней есть интересные идеи, которые можно применить в своём проекте.
#dx #debug
https://quip.com/blog/how-quip-builds-inproduct-debugging-tools
Quip
How Quip Builds In-Product Debugging Tools
Looking for ways to improve your development process? Learn how Quip engineers build customized in-product debugging tools for smoother development.
Сегодня прочитал статью Прити Сэм про создание анимированных иконок сайта — "The Making of an Animated Favicon".
Для создания анимированной favicon, можно использовать canvas, в котором с течением времени (или как реакция на сигнал от сервера) будет рисоваться индикатор загрузки. После каждой перерисовки получившийся результат переносится в тег <link>:
С примером из статьи есть проблема. Если перейти на соседнюю вкладку, то анимация в Chromium-based браузерах останавливается. Это возникает из-за того, что Chromium останавливает таймеры на неактивных вкладках. Чтобы обойти это ограничение, можно использовать web-воркеры.
#web #trick
https://css-tricks.com/the-making-of-an-animated-favicon/
Для создания анимированной favicon, можно использовать canvas, в котором с течением времени (или как реакция на сигнал от сервера) будет рисоваться индикатор загрузки. После каждой перерисовки получившийся результат переносится в тег <link>:
const canvas = document.querySelector('canvas'),
// [...] тут код отрисовки [...]
favicon.href = canvas.toDataURL('image/png');С примером из статьи есть проблема. Если перейти на соседнюю вкладку, то анимация в Chromium-based браузерах останавливается. Это возникает из-за того, что Chromium останавливает таймеры на неактивных вкладках. Чтобы обойти это ограничение, можно использовать web-воркеры.
#web #trick
https://css-tricks.com/the-making-of-an-animated-favicon/
CSS-Tricks
The Making of an Animated Favicon | CSS-Tricks
It’s the first thing your eyes look for when you’re switching tabs.
Два дня назад вышла новая версия Chrome 77. По каким-то причинам в этот раз не было отдельной публикации на официальном сайте, но появилось несколько видео на youtube.
В Chrome 77 появилась поддержка Largest Contentful Paint. Про эту метрику я писал ранее. С её помощью можно отследить время появления основной части контента на странице. Была добавлена поддержка Form Participation API. Благодаря ему можно создавать Custom Elements, которые будут вести себя как полноценные элементы управления стандартных форм. Также в рамках этого api у форм появилось событие
В инструментах разработчика тоже есть несколько нововведений. Теперь можно скопировать стили dom-узла (контекстное меню на элементе -> copy -> copy styles). Цветовая тема соответствует настройкам операционной системы. Добавили визуализацию сдвига контента. На вкладке "Network" появилась индикация того, что ресурс был загружен из Prefetch Cache. На вкладке "Application" видны push-сообещния и нотификации от сервис-воркеров. Можно логировать эти события до трёх дней даже при закрытых инструментах разработчика.
#chrome #release
https://www.youtube.com/watch?v=S8aVB3IfOR4
https://www.youtube.com/watch?v=R8KzoMoKhnM
В Chrome 77 появилась поддержка Largest Contentful Paint. Про эту метрику я писал ранее. С её помощью можно отследить время появления основной части контента на странице. Была добавлена поддержка Form Participation API. Благодаря ему можно создавать Custom Elements, которые будут вести себя как полноценные элементы управления стандартных форм. Также в рамках этого api у форм появилось событие
formdata, на который можно повесить обработчик для модификации отправляемых данных перед submit.В инструментах разработчика тоже есть несколько нововведений. Теперь можно скопировать стили dom-узла (контекстное меню на элементе -> copy -> copy styles). Цветовая тема соответствует настройкам операционной системы. Добавили визуализацию сдвига контента. На вкладке "Network" появилась индикация того, что ресурс был загружен из Prefetch Cache. На вкладке "Application" видны push-сообещния и нотификации от сервис-воркеров. Можно логировать эти события до трёх дней даже при закрытых инструментах разработчика.
#chrome #release
https://www.youtube.com/watch?v=S8aVB3IfOR4
https://www.youtube.com/watch?v=R8KzoMoKhnM
YouTube
New in Chrome 77: Native Lazy Loading, Largest Contentful Paint, and New Forms Capabilities
Chrome 77 is rolling out now! There’s a better way to track the performance of your site with Largest Contentful Paint. Forms get some new capabilities. Native lazy loading is here. The Chrome DevSummit is happening November 11-12, 2019. And plenty more.…
Дэвид Петер из Mailchimp написал статью про то, каких подходов при тестировании придерживается их команда — "Designing automated tests for React".
В статье очень много дельных мыслей, к которым стоит прислушаться. Например, следует придерживаться баланса при написании тестов — огромное количество тестов само по себе может стать проблемой, так как тесты это код, который следует поддерживать и писать. Зачастую на написание тестов может уходить больше времени, чем на написание фичи. Но при этом было бы глупо совсем отказываться от тестов, поэтому надо хорошо взвешивать, что тестить, а что оставить в покое. Ещё из статьи запомнилось то, что html создавался без учёта динамичных пользовательских интерфейсов. ARIA-атрибуты позволяют выражать недостающую семантику для элементов страницы, и этим фактом следует пользоваться при написании тестов.
Единственное, что у меня вызвало вопросы — отказ от снепшот-тестирования. Автор пишет, что снепшоты не выражают намерений. Я считаю, что их интент состоит в том, что они закрепляют контракт на уровне того, какую вёрстку должен генерировать компонент (мини-аналог скриншот-тестирования). Но при этом их стоит использовать благоразумно (например, не более одного снепшот-теста на компонент), так как большое количество снепшотов сложно ревьювить, и на них просто могут перестать обращать внимание.
Как бы то ни было, статья отличная. Советую прочитать всем без исключения, даже если вы не используете React.
#testing #react
https://increment.com/testing/designing-automated-tests-for-react/
В статье очень много дельных мыслей, к которым стоит прислушаться. Например, следует придерживаться баланса при написании тестов — огромное количество тестов само по себе может стать проблемой, так как тесты это код, который следует поддерживать и писать. Зачастую на написание тестов может уходить больше времени, чем на написание фичи. Но при этом было бы глупо совсем отказываться от тестов, поэтому надо хорошо взвешивать, что тестить, а что оставить в покое. Ещё из статьи запомнилось то, что html создавался без учёта динамичных пользовательских интерфейсов. ARIA-атрибуты позволяют выражать недостающую семантику для элементов страницы, и этим фактом следует пользоваться при написании тестов.
Единственное, что у меня вызвало вопросы — отказ от снепшот-тестирования. Автор пишет, что снепшоты не выражают намерений. Я считаю, что их интент состоит в том, что они закрепляют контракт на уровне того, какую вёрстку должен генерировать компонент (мини-аналог скриншот-тестирования). Но при этом их стоит использовать благоразумно (например, не более одного снепшот-теста на компонент), так как большое количество снепшотов сложно ревьювить, и на них просто могут перестать обращать внимание.
Как бы то ни было, статья отличная. Советую прочитать всем без исключения, даже если вы не используете React.
#testing #react
https://increment.com/testing/designing-automated-tests-for-react/
Increment
Designing automated tests for React – Increment: Testing
Practical insights from Mailchimp’s approach to frontend testing.
Зак Лезерман рассказал, как он ускорял загрузку web-шрифтов на CSS Tricks в статье "Developing a Robust Font Loading Strategy for CSS-Tricks".
Для того чтобы избежать FOIT (Flash of Invisible Text) и FOUT (Flash of Unstyled Text), Зак разбил исходные файлы шрифтов (regular и bold) на две части. Первая часть содержала информацию о кёрнинге (для предотвращения reflow документа) и минимальный набор глифов, которые необходимы для отображения латиницы и самых популярных символов, которые могут встречаться в заголовках статей на CSS Tricks. Вторая часть содержала всё остальное: лигатуры, хинтинг, кириллицу и т.п. Первый два файла загружаются с помощью
Так как файлы первого этапа весят всего по 13kb, они успевают загружаться до рендеринга документа. Более полная версия шрифта подгружается позже, но это не портит пользовательский опыт.
Рекомендую почитать статью, если вы используете кастомные шрифты на сайте и хотите ускорить их загрузку и отрисовку.
#typography #web
https://www.zachleat.com/web/css-tricks-web-fonts/
Для того чтобы избежать FOIT (Flash of Invisible Text) и FOUT (Flash of Unstyled Text), Зак разбил исходные файлы шрифтов (regular и bold) на две части. Первая часть содержала информацию о кёрнинге (для предотвращения reflow документа) и минимальный набор глифов, которые необходимы для отображения латиницы и самых популярных символов, которые могут встречаться в заголовках статей на CSS Tricks. Вторая часть содержала всё остальное: лигатуры, хинтинг, кириллицу и т.п. Первый два файла загружаются с помощью
preload, вторая часть — с помощью CSS Font Loading API.Так как файлы первого этапа весят всего по 13kb, они успевают загружаться до рендеринга документа. Более полная версия шрифта подгружается позже, но это не портит пользовательский опыт.
Рекомендую почитать статью, если вы используете кастомные шрифты на сайте и хотите ускорить их загрузку и отрисовку.
#typography #web
https://www.zachleat.com/web/css-tricks-web-fonts/
Zach Leatherman
Developing a Robust Font Loading Strategy for CSS-Tricks—zachleat.com
A post by Zach Leatherman (zachleat)