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

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

Также советую канал @webnya
Download Telegram
Инженеры из Shopify рассказали про свой опыт улучшения производительности SPA — "Want to Improve UI Performance? Start by Understanding Your User".

Основная идея статьи заключается в том, что при оптимизации приложения в первую очередь нужно думать о потребностях пользователей. Например, их пользователи — это продавцы, которые могут работать с разных устройств, при этом они пользуются некоторыми функциями приложения чаще чем другими. В первую очередь с помощью обычного профилировщика и профилировщика из React Dev Tools они собрали метрики приложения на слабом смартфоне. Эти данные им позволили определить компоненты, которые работали дольше других. Размер загружаемого JS заставил задуматься о ленивой загрузке тех компонентов, которые используются редко. В итоге сделанные оптимизации позволили не только ускорить загрузку кода, но и ускорить выполнение наиболее популярных пользовательских сценариев.

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

#performance #ux #react

https://engineering.shopify.com/blogs/engineering/improve-ui-performance-understanding-your-user
На этой неделе вышла новая версия TypeScript 3.7 с большим количеством фич.

Добавили поддержку Optional Chaining. В release notes есть хорошее именование разных типов Optional Chaining, которое я нигде раньше не встречал: optional property accesse для foo?.bar, optional element access для arr?.[0] и optional call для method?.(). Также добавили Nullish Coalescing ( ?? ), которое призвано заменить использование || для определения дефолтных значений.

Улучшили поддержку уточнения типов после использования функций assert. Для этого была добавлена новая концепция assertion signatures. При реализации этой фичи улучшили поддержку функций, которые возвращают never.

Крутая новая фича — продвинутая поддержка рекурсивных типов. Раньше такой алиас type ValueOrArray<T> = T | Array<ValueOrArray<T>>; вызвал бы ошибку. С версии 3.7 это корректная конструкция. Теперь можно компактно описывать рекурсивные структуры данных. Вот пример для JSON:
type Json =
| string
| number
| boolean
| null
| { [property: string]: Json }
| Json[];


В релизе есть ломающие изменения. Обновили типы для lib.dom.d.ts. Поля классов при транспиляции теперь преобразуются в конструкции Object.defineProperty(). Если функция находится в операторе if и она не вызывается, это будет приводить к ошибке.

Улучшили совместимость между ts и js. Поменяли механизм работы с project references. Форматтер теперь может удалять или, наоборот, при необходимости автоматически добавлять символ точки с запятой.

#typenoscript #release

https://www.typenoscriptlang.org/docs/handbook/release-notes/typenoscript-3-7.html
Случайно увидел статью 2016 года Эрика Эллиота про когнитивную работу мозга программистов — "Are Programmer Brains Different?".

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

Как-то не задумывался над этим, но сходу могу вспомнить много людей, кто умеет играть на музыкальных инструментах и программирует. Более того в Яндексе и 2ГИС чуваки собираются в группы и играют музыку на вечеринках.

#programming #psychology

https://medium.com/javanoscript-scene/are-programmer-brains-different-2068a52648a7
Умеешь играть на каком-нибудь музыкальном инструменте?
Anonymous Poll
43%
Да
57%
Нет
Франк Форс у себя в блоге разобрал эффект 3D-тоннеля, код которого умещается в 140 символов, — "Dissecting A Dweet #8: Shattered Tunnel".

Этот эффект — идейное продолжение демо "Strange Сrystals", которое в 2013 году заняло первое место на конкурсе JS1k (соревнование среди демок, которые умещаются в 1024 байт). Из статьи узнал, что canvas.width = canvas.width используют для очистки canvas. Этот хак работает благодаря тому, что при присваивании любого значения размера canvas, происходит его инвалидация. В конкурсах, подобных JS1k, этот код сокращают до canvas.width |= 0, но этот хак не рекомендуют использовать в серьёзных проектах.

Статья интересная. Рекомендую почитать, если интересуетесь графикой и code golf.

#graphics #math #js

http://frankforce.com/?p=7160
В блоге Акселя Раушмайера пару дней назад появилась статья про использование асинхронных итераторов со стримами в Node.js — "Easier Node.js streams via async iteration".

Код, который агрегирует поступающие данные из readable stream или, наоборот, записывает данные во writable stream может быть записан компактно, используя возможности асинхронных итераторов (ES2018). Вот пример из статьи. В нём с помощью конструкции for await ... of считывается текст из readable stream и записывается в переменную result:
async function readableToString(readable) {
let result = '';
for await (const chunk of readable) {
result += chunk;
}
return result;
}


Выглядит очень элегантно. В статье ещё есть хороший пример трансформации стримов с помощью асинхронных генераторов.

В общем, рекомендую почитать, даже если не работаете много с Node.js.

#js #nodejs #async

https://2ality.com/2019/11/nodejs-streams-async-iteration.html
HTTP Archive опубликовал очень крутой альманах про web в 2019 году — "Web Almanac 2019".

Web Almanac — это подборка отчётов, посвящённых разным web-технологиям и темам: JavaScript, CSS, HTML, производительность, безопасность, a11y, seo, мобильный web и т.п. В проекте участвовало 85 человек, каждый из которых является экспертом в своей области — Рик Вискоми, Матиас Байненс, Эрик Мейер, Марк Ноттингем, Эдди Османи и другие.

Бегло посмотрел статьи — инфы очень много. Будет чем заняться на выходных.

#report #web

https://almanac.httparchive.org/en/2019/
Матиас Байненс в блоге v8 опубликовал небольшой пост про новый метод строк replaceAll.

Для того чтобы заменить все вхождения подстроки в JS, нужно использовать String.replace с глобальным регулярным выражением в первом аргументе: 'aabbcc'.replace(/b/g, '_'). Более того, надо помнить про эксейпинг специальных символов, например, для замены всех символов + надо использовать выражение 'a+b+c'.replace(/\+/g, ''). Это не очень удобно.

Для решения этой проблемы в следующем стандарте ECMAScript запланировано добавление нового метода String.replaceAll. С его помощью последний пример может переписан так: 'a+b+c'.replaceAll('+', ''). Для консистентности с replace первым аргументом можно передавать регулярное выражение, но оно обязательно должно быть глобальным.

На данный момент String.replaceAll находится на третьем этапе добавления в стандарт. Пока его поддержка есть только в v8 за экспериментальным флагом.

#tc39 #js

https://v8.dev/features/string-replaceall
На прошедшем Chrome Dev Summit Google представил Web Bundles — новый механизм для распространения web-приложений.

Представьте, что любое web-приложение можно положить на флешку, поделиться им по Bluetooth или захостить в своей локальной сети. Всё это становится возможным благодаря Web Bundles (формальное название Bundled HTTP Exchanges), которые являются частью предложения добавления в стандарт «Web Packaging». Предполагается, что запаковать можно будет любое приложение или сайт. В статье "Get started with Web Bundles" разбирается пример создания бандла для небольшого todo-приложения.

На данный момент экспериментальная поддержка Web Bundles есть только в Chrome 80 (Canary). Разработчики призывают потестировать новую фичу и поделиться своим фидбеком.

#future #web #offline

https://web.dev/web-bundles/
Недавно на сайте web.dev появился раздел, посвящённый метрикам производительности. Насколько я понял, этот раздел собран из новых статей и из уже существовавших с небольшими правками.

Сейчас там можно найти описание всех пользовательских метрик. Каждой метрике посвящена отдельная статья: First Contentful Paint (FCP), Largest Contentful Paint (LCP), First Input Delay (FID), Time to Interactive (TTI) и т.п. Есть практические советы по улучшению этих метрик. Появилась статья про Custom Metrics — в ней рассказывается про использование User Timing API (позволяет замерять временные метрики), Long Tasks API (для выявления проблем с блокированием главного потока JS), Element Timing API (используется для определения времени появления на странице конкретных элементов).

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

#performance #metrics

https://web.dev/metrics/
В последнем подкасте HTTP 203 Джек Арчибальд и Сурма рассказали, почему из спецификации HTTP Modules была удалена возможность импорта JSON-файлов.

В Node.js есть возможность зареквайрить json в JavaScript-файл. Это очень удобно, если нужно зафолбечиться на какие-то данные в случае проблем с API или просто для чтения конфигов. Похожий механизм импортов был предложен для добавления в web-платформу в спецификации HTTP Modules: import json from 'some.json'. Проблема в том, что в web расширение файла не влияет на интерпретацию загружаемых данных, тип ресурса определяется HTTP-заголовком content-type. Это означает, что если мы импортируем json с чужого домена import json from 'https://example.com/some.json' и если этот сайт будет компроментирован таким образом, что вместо application/json в заголовке будет отправляться application/javanoscript, это открывает дыру в безопасности, так как содержимое json-файла может быть заменено на любой JavaScript-код. Теперь разработчики спецификации думают над тем, как добавлять метаинформацию на уровне модульной системы, чтобы избавиться от таких случаев.

Webpack решает проблему с метаинформацией, добавляя свои расширения в спецификатор импорта. Разработчики Rollup и Parcel тоже размышляют над этой проблемой. В любом случае код может получиться непереносимым между бандлерами, если все будут работать над этой задачей независимо. Таким образом решение возникшей проблемы в импорте json на уровне спецификации, позволит унифицировать использование метаинформации и в бандлерах.

#esm #security #specification

https://www.youtube.com/watch?v=jG7VfbqqTGw
На CSS-Tricks Артём Денисов написал про производительность JAM-сайтов — "A Look at JAMstack’s Speed, By the Numbers".

Под понятием JAMstack (JavaScript, APIs, Markdown) понимаются статически генерируемые сайты. В отличие от традиционных сайтов, построенных с помощью CMS, все страницы JAMstack-сайтов генерируются на этапе сборки чаще всего из Markdown-файлов. Этот подход в последнее время набирает большую популярность. В статье сравниваются метрики TTFB, FCP и FID для среднестатистических сайтов, CMS- и JAMstack-сайтов. Последние (при условии использования CDN) показывают наибольшую производительность.

В статье есть хорошая мысль по поводу производительности: "Мне встречались клиенты, которые требовали поддержку IE10 и IE11, потому что этими браузерами пользовался один процент пользователей, что эквивалентно миллионам долларов выручки. Пожалуйста, подсчитайте свои потери, когда один процент пользователей уходит с сайта и никогда не возвращается из-за плохой производительности. Если пользователи страдают, будет страдать и бизнес".

#performance #metrics #jamstack

https://css-tricks.com/a-look-at-jamstacks-speed-by-the-numbers/
Мануэль Матузович написал хорошую статью про проблемы автоматического тестирования доступности — "Building the most inaccessible site possible with a perfect Lighthouse score".

В статье рассказывается, как написать недоступный сайт, который будет выбивать в Lighthouse 100%. Для этого автор поэтапно делает html-страницу нечитабельной, недоступной для скринридеров, с неработающим режимом чтения в браузерах, не реагирующей на клики мыши и на нажатие клавиш клавиатуры. Каждое изменение не влияет на 100% показатель доступности в Lighthouse. Этим всем Мануэль доказывает, что полагаться только на инструменты автоматического тестирования доступности нельзя, их надо обязательно дополнять ручными проверками.

В общем, рекомендую почитать. В статье есть ссылки на хорошие статьи по теме.

#a11y #lighthouse

https://www.matuzo.at/blog/building-the-most-inaccessible-site-possible-with-a-perfect-lighthouse-score/
https://habr.com/ru/post/455016/ (перевод)
Для ускорения установки соединения с доменами, на которых находятся загружаемые ресурсы, используют хинты dns-prefetch и preconnect. Дэниэл Александерсен рассказал как их правильно использовать в статье "What to <link rel=dns-prefetch> and when to use preconnect".

Самая распространённая ошибка при использовании dns-prefetch — добавление доменов, ссылки на которые уже есть в html-документе. В этом нет особого смысла, так как браузер будет устанавливать соединение во время парсинга документа. Наибольшую выгоду от использования dns-prefetch можно получить, если домен неизвестен на момент парсинга документа, например, когда установка соединения с новым доменом происходит при выполнении загруженного кода. Другой хинт — preconnect — не только резолвит доменное имя, но и устанавливает TCP-соединение. Это может быть очень полезно на мобильных устройствах.

Если хотите узнать больше подробностей про использование dns-prefetch и preconnect, рекомендую почитать статью.

P.S. Передаю спасибо @oleg_log за ссылку.

#net #performance

https://www.ctrl.blog/entry/dns-prefetch-preconnect.html
Брайан Гринстед — разработчик Firefox — рассказал как происходила миграция интерфейса Firefox на web-компоненты — "The Firefox UI is now built with Web Components".

Для разработки интерфейса Firefox используется XUL (XML User Interface Language). Этой технологии уже больше двадцати лет. Впервые она появилась в прародителе Firefox — Netscape в 1997 году. XUL разрабатывался для унификации разработки интерфейса браузера на разных платформах (Windows, Linux, Mac OS X). Для описания внешнего вида и поведения элементов интерфейса браузера используется XBL (eXtensible Bindings Language). Пару недель назад XBL был полностью заменён на web-компоненты. Это важное событие для разработчиков браузера на пути к полному отказу от XUL в пользу стандартных web-технологий. Переход на web-технологии упростит кодовую базу и ускорит добавление новых фич.

По ходу переноса, конечно, были проблемы. Вот интересный случай из статьи: "Также был пользователь, у которого было открыто полторы тысячи вкладок. Он заметил сильные тормоза при открытии списка "All tabs". Оказалось, что он попал в пограничный случай, в котором алгоритм работал за O(N²). Проблема была исправлена".

Очень рекомендую почитать статью. Про опыт большого рефакторинга разработчики браузеров пишут нечасто.

#firefox #webcomponents #internals

https://briangrinstead.com/blog/firefox-webcomponents/
На Mozilla Hacks пару дней назад появилась статья Рейчел Эндрю про column-span — "Multiple-column Layout and column-span in Firefox 71".

В многоколоночной разметке контент непрерывно "перетекает" из одной колонки в другую. Эта разметка очень популярна в газетах и журналах, так как улучшает читабельность текста. Спецификация Multiple-column Layout описывает необходимые свойства для создания такой разметки. В рамках этой спецификации описывается свойство column-span, с помощью которого можно стилизовать элементы так, чтобы они занимали несколько колонок сразу, например, как заголовок в газете. С релизом Firefox 71 column-span будет поддерживаться во всех современных браузерах.

В статье рассказывается о том, как работает это свойство и какие были проблемы при его добавлении в спецификацию.

#css #specification #layout

https://hacks.mozilla.org/2019/11/multiple-column-layout-and-column-span-in-firefox-71/
Ришаб Рао из Yelp написал статью про то, как они используют subresource integrity при подключении скриптов со сторонних CDN — "Organizing and Securing Third-Party CDN Assets at Yelp".

Subresource integrity — это механизм, который позволяет гарантировать блокирование выполнения кода, который был скомпроментирован на стороне CDN-провайдера. Это достигается с помощью добавления атрибута integrity в тег noscript. В атрибуте находится хэш загружаемого скрипта. В Yelp не используют хэши, которые предоставляются CDN — они генерируют хэши сами. Для хэширования используют алгоритм SHA-384, так как он наименее подвержен атаке length extension. Суть этой атаки сводится к добавлению в скомпроментированный скрипт дополнительного текста таким образом, чтобы не менялся результат хэширования.

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

#security #cdn #sri

https://engineeringblog.yelp.com/2019/11/organizing-and-securing-third-party-cdn-assets-at-yelp.html

P.S. Отписался в issue cdnjs про использование SHA-384 (https://bit.ly/2QHGYAx). Будет здорово, если SHA-384 будет использоваться по умолчанию. Сейчас там используется SHA-256.
В статье Эдди Османи "The cost of JavaScript in 2019", про которую я писал пару месяцев назад, есть рекомендация про ускорение загрузки в память больших объектов. Вместо использования обычных объектов в статье рекомендуется использовать JSON.parse().

Пару дней назад было опубликовано видео, в котором Матиас Байненс — разработчик V8 — объясняет, почему использование JSON.parse() быстрее. Для того, чтобы распарсить объект, который представлен в виде обычного литерала в коде JavaScript, парсеру необходимо совершить гораздо больше работы на этапе токенизации. Во время же исполнения JSON.parse('{"key": 123}') парсеру надо делать меньше работы, так как грамматика JSON гораздо проще грамматики JavaScript. Использование такого подхода даёт буст в скорости не только в V8 (1.7x), но и в движках других браузеров: JavaScript Core (Safari) — 2x, SpiderMonkey Firefox) — 1.2x. Webpack уже автоматически применяет эту оптимизации при импорте JSON-файлов, ещё можно воспользоваться Babel-плагином для автоматического преобразования объектов.

Ну что сказать. Повышайте Time to Interactive — используйте JSON.parse().

#js #performance #json

https://www.youtube.com/watch?v=ff4fgQxPaO0
Илья Стрельцын написал небольшой пост про развитие CSS — "CSS4 не будет… потому что он давно прошел. Встречайте CSS8!".

На данный момент не существует такого понятия как "версия CSS", потому что спецификация для упрощения поддержки была разбита на модули с независимым версионированием. Но было бы неплохо иметь какой-нибудь неофициальный ориентир для отслеживания развития спецификации в целом. Таким ориентиром Илья предлагает взять раздел "The Official Definition" документа "CSS Snapshot". У этого документа есть пять редакций c 2007 года. До разбития на модули у CSS было две версии, поэтому можно сказать, что актуальная на данный момент версия CSS — "CSS7".

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

#musings #css #specification

https://css-live.ru/css/css4-ne-budet-potomu-chto-on-davno-proshel-vstrechajte-css8.html
Иногда в интерфейсах можно встретить эффект "прыгающих цифр". Например, в таймере который отображает время или в числе, которое меняется при прокрутке слайдера. Робин Рэндл написал статью "The Smallest Difference" про исправление этого эффекта на примере таблиц.

В шрифтах OpenType для некоторых символов есть альтернативные глифы, отображение которых можно включать с помощью CSS. Для цифр есть альтернативный глиф перечёркнутого нуля, глифы старого и моноширинного стиля. Использование последнего стиля как раз и может решить проблему "прыгающих цифр". Для этого необходимо подключить OpenType-шрифт с такой возможностью (у меня заработало с шрифтом -apple-system) и добавить к необходимому контенту CSS-свойство font-variant-numeric: tabular-nums;. Использовании tabular-nums в таблице с большим количеством чисел очень положительно сказывается на читабельности. В статье есть гифка, где хорошо виден эффект от применения этого свойства.

Кажется, что это мелочь, но именно такие мелочи формируют пользовательский опыт.

#css #ui #ux

https://www.robinrendle.com/notes/the-smallest-difference.html
Валерий Щавель из Яндекс.Карт рассказал на хабре про опыт использования WebAssembly — "Как мы внедряли WebAssembly в Яндекс.Картах и почему оставили JavaScript".

В Яндекс.Картах объекты перед отрисовкой разбивают на треугольники прямо в браузере. Это ресурсоёмкая задача, которую решили попробовать вынести на уровень WebAssembly. Ребята сделали прототип, который использует wasm, и внедрили его в своё TypeScript-приложение. Скорость обработки тайлов выросла в несколько раз, но появилась просадка из-за накладных расходов на передачу данных из wasm в js. Также вырос размер бандла (в комментариях пишут, что это скорее всего из-за неиспользуемых фич emnoscripten). В итоге от WebAssembly на данный момент решили отказаться.

Статья интересная. Советую почитать, если интересуетесь темой WebAssembly.

#webassembly #experience #yandex

https://habr.com/ru/company/yandex/blog/475382/