Size: a a a

Defront (при поддержке Зарплата.ру) — про фронтенд-разработку и не только

2021 October 29
Defront (при поддержке Зарплата.ру) — про фронтенд-разработку и не только
Релиз Next.js 12

Три дня назад была представлена новая мажорная версия Next.js — "Next.js 12".

Next.js 12 по умолчанию использует swc для транспиляции JavaScript- и TypeScript-файлов. Swc — это очень быстрый аналог Babel, написанный на Rust. Благодаря ему время production-сборки стало в пять раз меньше. В три раза уменьшилось время обновления страницы при локальной разработке.

Была добавлена поддержка миддлвар для гибкой модификации HTTP-ответа. В зависимости от входящего запроса можно изменить ответ, добавить новые HTTP-заголовки, сделать редирект и т.п. Миддлвары могут работать на edge-серверах Vercel, улучшая отзывчивость приложения.

Была проведена работа для подготовки к переходу на React 18. В экспериментальном режиме доступны серверные компоненты и новый поточный серверный рендерер с поддержкой Suspense.

Теперь по умолчанию в Next.js используется ESM с поддержкой импорта CommonJS-модулей. Добавлена экспериментальная поддержка импорта модулей по URL.

В компоненте <Image> появилась поддержка формата изображений AVIF. Также компонент автоматически определяет основное изображение страницы, которому нужно передать пропс priority для улучшения метрики LCP.

В рамках нового релиза была опубликована библиотека @vercel/nft (Node File Tracer). Она используются для генерации облегчённых standalone-сборок Next.js-приложений для serverless-окружений и контейнеризации.

В Next.js 12 поисковым ботам будут отдаваться полностью отрендеренные страницы, использующие Incremental Static Regeneration. Обычные пользователи будут видеть интерфейс загрузки страницы.

В ломающих изменениях отказ от Webpack 4, деприкейт опции target, использование <span> вместо <div> в next/image, увеличение минимальной поддерживаемой версии Node.js с 12.0.0 до 12.22.0

#release #jsframeworks #react

https://nextjs.org/blog/next-12
источник
2021 November 01
Defront (при поддержке Зарплата.ру) — про фронтенд-разработку и не только
Числа, которые должны быть известны каждому

Пол МакЛелан рассказал о числах, которые должны знать все программисты — "Numbers Everyone Should Know".

По интернету давно гуляет список Питера Норвига со временем тика CPU, доступа к L1, L2-кешам, доступа к памяти и т.п. В статье Пола этот список обновлён и расширен новыми пунктами: временем доступа к L3-кешу, временем передачи TCP-пакета в пределах датацентра, из Америки в Европу и обратно и т.п.

Обновлённый список:
— Тик CPU: 0.3 нс
— Доступ к L1: 0.5 нс
— Стоимость ошибки предсказания ветвления в CPU: 5 нс
— Доступ к L2: 3 нс
— Доступ к L3: 28 нс
— Доступ к памяти (DRAM): 100 нс
— Передача 2 Kб по 1 Gbps-сети: 20,000 нс
— Последовательное чтение 1 Мб данных из памяти: 250,000 нс
— Передача TCP-пакета в пределах одного датацентра: 500,000 нс
— Обращение к SSD: 100,000 нс
— Обращение к магнитному жёсткому диску: 10,000,000 нс
— Последовательное чтение 1 Мб данных из сети: 10,000,000 нс
— Последовательное чтение 1 Мб данных с жёсткого диска: 30,000,000 нс
— Время передачи TCP-пакета из Калифорнии в Европу и обратно: 150,000,000 нс
— Время на написание одного слова: 1 c
— Время на открытие PowerPoint на macOS: 10 с

Величину разрыва между этими цифрами можно прочувствовать в масштабе. Если бы тик CPU занимал одну секунду, то время передачи TCP-пакета из Калифорнии в Европу и обратно составляло бы десять лет, а PowerPoint открывался бы тысячелетие.

#programming

https://community.cadence.com/cadence_blogs_8/b/breakfast-bytes/posts/numbers-everyone-should-know
источник
2021 November 02
Defront (при поддержке Зарплата.ру) — про фронтенд-разработку и не только
За прошедшие три недели в канале для патронов Defront было опубликовано пятнадцать постов:

— Проблема новичков-экспертов
— Проблемы использования видео в вебе
— Как ускорить сборку TypeScript-проекта
— Зачем инженерам пробовать себя в консалтинге
— Руководство по git без использования команд git
— Почему в фреймворках не используются веб-воркеры
— Читабельный HTML в 100 байт CSS
— Таинственный Script Error
— Непростой выбор между SPA и MPA
— Как заручиться поддержкой коллег
— Проблемы критического CSS
— Системные цвета в CSS
— Ванильный JavaScript как замена jQuery
— Оптимизация производительности автодополнения
— WeakMap на практике

Становитесь патроном канала на Patreon, чтобы получить доступ к дополнительным постам в Defront Plus. Все донаты идут на поддержку канала, оплату медицинских услуг, покупку еды, аренду квартиры и т.п.

Спасибо всем, кто читает и поддерживает Defront!

https://www.patreon.com/myshov
источник
Defront (при поддержке Зарплата.ру) — про фронтенд-разработку и не только
Потенциальные проблемы с Firefox 100 и Chrome 100

Близится день, когда Firefox и Chrome дойдут до сотой версии. Это не просто красивая цифра, но и потенциальная причина ошибок.

Немного истории. Opera стала первым браузером, дошедшим до версии 10. В альфа-версии десятки поломались сайты, неправильно парсившие User-Agent. Их логика парсинга предусматривала только одну цифру в версии, поэтому Opera 10 превращалась в Opera 1, ломая отображение сайта.

Подобная ситуация может случиться с Firefox 100 и Chrome 100, если логика парсинга не предусматривает трёхзначные числа. Поэтому разработчики браузеров рекомендуют проверить работу своих проектов с изменением версии браузера в User-Agent. Разработчики Chrome пошли немного дальше и сделали специальный флаг #force-major-version-to-100, который автоматически подымает версию Chrome до 100.

#announcement #web

https://developer.chrome.com/blog/force-major-version-to-100/
https://www.otsukare.info/2021/04/20/ua-three-digits-get-ready
источник
2021 November 03
Defront (при поддержке Зарплата.ру) — про фронтенд-разработку и не только
Подходы использования SVG и их производительность

Тайлер Ситка сравнил производительность разных методов использования SVG на HTML-страницах — "Which SVG technique performs best for way too many icons?".

Самым производительным способом добавления SVG стал элемент <img> c data URI — 72 мс для 1000 иконок. Но при таком подходе невозможно стилизовать SVG с помощью внешних стилей. Наиболее сбалансированным способом для оптимизированных SVG оказался инлайнинг — 87 мс для 1000 иконок. Самым медленным способом стала CSS-маска — 150 мс.

Тайлер также пишет о том, что не нужно сильно задумываться о выборе подходящего метода, если на странице используется менее сотни SVG-изображений. Используйте тот подход, который нравится.

#benchmark #performance #svg

https://cloudfour.com/thinks/svg-icon-stress-test/
источник
2021 November 04
Defront (при поддержке Зарплата.ру) — про фронтенд-разработку и не только
Релиз Angular 13

Сегодня вышла новая мажорная версия Angular. Марк Томпсон рассказал о всех нововведениях релиза — "Angular v13 is now Available".

— С этой версии больше недоступен View Engine — движок рендеринга, предшествующий Ivy. Благодаря его удалению открываются возможности сокращения времени компиляции, которые будут реализованы в будущем

— Изменён формат внешних модулей Angular Package Format (APF): добавлена поддержка ES2020, удалена необходимость использования ngcc

— Включена поддержка сохранения кеша сборки для ускорения скорости бандлинга. Прирост составляет 68%. Также в Angular CLI v12.2 была добавлена поддержка esbuild, который ускорил время сборки production-бандлов на 10%

— Упрощено API для динамического создания компонентов

— По умолчанию включена инвалидация окружения при прогоне каждого теста

— Улучшена доступность компонентов Angular Material

— RxJS обновлён до версии 7.4, TypeScript обновлён до версии 4.4

— Прекращена поддержка IE11. Пользователи Internet Explorer могут продолжать использовать Angular 12. Он будет поддерживаться до ноября 2022 года

#angular #release #jsframeworks

https://blog.angular.io/angular-v13-is-now-available-cce66f7bc296
источник
2021 November 05
Defront (при поддержке Зарплата.ру) — про фронтенд-разработку и не только
Поиск необработанных промисов

Свизек Теллер написал статью про ошибки, приводящие к возникновению необработанных промисов — "Finding unresolved promises in JavaScript".

Необработанные промисы — это большой источник проблем, который может привести к крешу программы. Они возникают при забытом перехвате исключения с помощью catch, при отсутствующем вызове resolve / rejet или при забытом return в цепочке промисов.

Свизек нашёл научную статью "Finding broken promises in asynchronous JavaScript programs", в которой авторы попробовали автоматизировать поиск подобных ошибок и создали утилиту PromiseKeeper. Идея интересная, но похоже, что работу над проектом остановили после публикации статьи.

#async #js #experimental

https://swizec.com/blog/finding-unresolved-promises-in-javascript/
источник
2021 November 07
Defront (при поддержке Зарплата.ру) — про фронтенд-разработку и не только
Компроментация npm-пакетов coa и rc

В четверг были скомпрометированы npm-пакеты coa и rc. На первый пакет приходится 7 миллионов загрузок в неделю, на последний — 14 миллионов.

Во взломанных пакетах был размещён Windows-троян, который воровал сохранённые пароли, данные кредитных карт и т.п.

На данный момент вредоносные версии пакетов уже удалены, но специалисты по безопасности рекомендуют на всякий случай проверить в системе наличие вредоносных файлов: compile.js, compile.bat, sdd.dll. Для предотвращения подобных инцидентов npm советует включить двухфакторную аутентификацию.

#npm #security

https://www.bleepingcomputer.com/news/security/popular-coa-npm-library-hijacked-to-steal-user-passwords/
источник
2021 November 08
Defront (при поддержке Зарплата.ру) — про фронтенд-разработку и не только
Оптимизация загрузки ресурсов с помощью хинтов приоритета (Priority Hints)

Лина Сохони, Эдди Османи и Патрик Минан рассказали про хинты приоритета — механизм для упрощения оптимизации загрузки ресурсов — "Optimizing resource loading with Priority Hints".

Хинты приоритета (Priority Hints) — это атрибут importance HTML-элементов <img>, <link>, <script> , <iframe> и одноимённая опция в fetch(). Они поддерживают три приоритета: low, high и auto. Пример ускорения загрузки LCP-изображения: <img src="lcp_image.png" importance="high">.

Хинты приоритета используются в качестве сигналов на уровне разметки документа. Благодаря им у разработчиков появляются удобные рычаги для регулирования последовательности загрузки ресурсов. Управлять приоритетом можно было и раньше с помощью preload, но это требовало ручной кропотливой работы, приводящей к частым ошибкам в приоритизации загрузки. Также хинты приоритета решают задачи, которые невозможно или неудобно решать с помощью preload: уменьшение приоритета загрузки скриптов, увеличение приоритета async-скриптов.

Хинты приоритета также доступны в fetch(): fetch('https://...', {importance: 'low'}. По умолчанию fetch() загружает ресурсы с высоким приоритетом. С помощью хинта теперь можно уменьшать приоритет загрузки.

Поддержка атрибута importance существовала ранее в Chrome 73-76, но была удалена из-за проблем с preload, которые исправили в Chrome 95. Хинты приоритета будут доступны в рамках Origin Trial в Chrome 96-100.

#performance

https://web.dev/priority-hints/
источник
2021 November 09
Defront (при поддержке Зарплата.ру) — про фронтенд-разработку и не только
Сценарии использования HTML-элемента dialog

Сэм Торогуд из Google рассказал про сценарии использования элемента <dialog> — "In Defence Of Dialog".

Элемент <dialog> предназначен для создания диалоговых окон. Нативный HTML-диалог поддерживает автоматический захват фокуса при переходе по Tab и устраняет проблемы с контекстом наложения без использования JavaScript.

В статье рассказывается про создание одного и нескольких модальных окон с помощью <dialog>, про реализацию открывающегося сайдбара с закрытием по затемнённому фону, про предотвращение прокрутки при открытии окон. Также из статьи узнал про method="dialog" в формах. Если форма с method="dialog" находится внутри <dialog>, то она будет автоматически закрыта при отправке формы. Для всех сценариев использования в статье есть интерактивные демки.

У нативного диалога трагичная судьба — процесс его проникновения в основные браузерные движки занял десять лет. На протяжении этого времени его даже однажды хотели удалить из спецификации. Сейчас поддержка <dialog> есть в Chrome, в Firefox за экспериментальным флагом и в Safari Technology Preview 134.

#html

https://whistlr.info/2021/in-defence-of-dialog/
источник
2021 November 10
Defront (при поддержке Зарплата.ру) — про фронтенд-разработку и не только
Моделирование пользовательских сценариев в Lighthouse

Брендан Кенни рассказал про Flow API Lighthouse, благодаря которому становится возможен комплексный анализ страницы — "Lighthouse user flows".

Доступ к Flow API возможен из puppeteer-скриптов. Он позволяет протестировать загрузку страницы с прогретым кешом, подготовить страницу перед прогоном проверок и отследить метрики производительности на заданном промежутке времени.

Flow API — это большой шаг для Lighthouse, так как теперь в лабораторных условиях можно получить полноценные значения метрик, зависящих от пользовательского ввода. Например, сейчас можно открыть страницу и программно вызвать прокрутку, отслеживая изменение метрики CLS. По умолчанию Lighthouse не отслеживает изменение CLS и отображает значение, полученное сразу после загрузки страницы.

#performance #tool

https://web.dev/lighthouse-user-flows/
источник
2021 November 11
Defront (при поддержке Зарплата.ру) — про фронтенд-разработку и не только
Новые единицы измерения CSS, зависящие от области просмотра

Брамус Ван Дамм рассказал про новые единицы измерения, которые недавно были добавлены в спецификацию CSS Values and Units Level 4 — "The Large, Small, and Dynamic Viewports".

Довольно давно в браузерах появилась поддержка единиц измерений vw, vh, vmax, vmin. Их используют для ограничения размера элемента размером доступной области просмотра и для заполнения вьюпорта содержимым на мобилках. Когда создавалась спецификация, всё было логично. Однако ситуация изменилась, когда Safari стал скрывать части интерфейса во время прокрутки. Размер вьюпорта стал меняться динамически, и страницы, использующие vh, стали перекрываться интерфейсом браузера.

Для решения этой проблемы были придуманы разные хаки, а CSSWG разработала новые единицы измерения, более тонко учитывающие поведение вьюпорта:

lvw, lvh, lvmax, lvmin — единицы относительно вьюпорта браузера со скрытыми элементами интерфейса (префикс "l" — large viewport)
svw, svh, svmax, svmin — единицы относительно  вьюпорта браузера без скрытых элементов интерфейса (префикс "s" — small viewport)
dvw, dvh, dvmax, dvmin — единицы относительно вьюпорта, учитывающие динамическое изменение интерфейса (префикс "d" — dynamic viewport)

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

#css #spec #mobile

https://www.bram.us/2021/07/08/the-large-small-and-dynamic-viewports/
источник
2021 November 12
Defront (при поддержке Зарплата.ру) — про фронтенд-разработку и не только
Релиз Firefox 94

На прошлой неделе вышла новая версия Firefox. Официального блог-поста на Mozilla Hacks в этот раз не было, скорее всего из-за того, что изменений для разработчиков в релизе очень мало.

Самая интересная фича релиза — добавление поддержки структурного клонирования объектов с помощью метода structuredClone(). Этот метод предназначен для глубокого клонирования объектов в том числе с циклическими ссылками. Есть поддержка перемещения для transferable objects. Это полезно для обмена данными между веб-воркерами и главным потоком.

Появилась поддержка кастомизации лейбла кнопки Enter виртуальной клавиатуры с помощью свойства enterKeyHint элементов ввода и глобального атрибута enterkeyhint. Можно указать: enter, done, go, next, previous, search, send.

У динамически создаваемых скриптов стал доступен статический метод supports() для проверки поддержки ECMAScript modules. Добавлена поддержка свойства ShadowRoot.delegatesFocus для проверки текущего статуса делегирования фокуса у кастомных элементов.

Уменьшено потребление памяти JavaScript-движком. Ускорен перебор свойств объектов. Уменьшено потребление CPU во время поллинга HTTPS-соединений.

#firefox #release

https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/94
https://www.mozilla.org/en-US/firefox/94.0/releasenotes/
источник
2021 November 16
Defront (при поддержке Зарплата.ру) — про фронтенд-разработку и не только
Улучшение веба с помощью OffscreenCanvas

Брайан Карделл из Igalia рассказал о преимуществах OffscreenCanvas — "Making the whole web better, one canvas at a time".

HTML-элемент canvas по статистике HTTPArchive используется чаще чем тег video. Он используется для разных целей: для отрисовки карт, для создания графических редакторов и отображения любой сложной графики.

Canvas бывает большим источником проблем производительности, так как выполнение кода отрисовки и процесс рендеринга в canvas происходят в главном потоке. Для решения этой проблемы был придуман новый API — OffscreenCanvas. С его помощью тяжёлые вычисления можно вынести в воркер. Передача готовой картинки из воркера в главный поток очень быстрый процесс и не влияет на отзывчивость страницы. Также благодаря OffscreenCanvas можно распараллелить рендеринг по нескольким воркерам, открывая новые возможности для веба.

На данный момент полноценная поддержка OffscreenCanvas есть только в Chrome. В Firefox его можно включить с помощью флага gfx.offscreencanvas.enabled. В WebKit он находится на этапе разработки.

#performance #api #webgl

https://bkardell.com/blog/OffscreenCanvas.html
источник
Defront (при поддержке Зарплата.ру) — про фронтенд-разработку и не только
Улучшение отзывчивости ввода текста

Нолан Лоусон написал статью про улучшение отзывчивости ввода текста в ресурсоёмких приложениях — "Improving responsiveness in text inputs".

Если приложению требуется некоторое время для обновления интерфейса, то это негативно сказывается на отзывчивости ввода текста. Для решения этой проблемы Нолан предлагает использовать requestIdleCallback. С его помощью можно запланировать выполнение ресурсоёмкой работы на тот момент, когда главный поток будет свободен, освобождая его для быстрой обработки ввода текста:

let queued = false
textarea.addEventListener('input', () => {
 if (!queued) {
   queued = true
   requestIdleCallback(() => {
     updateUI(textarea.value)
     queued = false
   })
 }
})

Поддержка метода requestIdleCallback есть в Firefox и Chrome. В Safari он находится за экспериментальным флагом.

#performance

https://nolanlawson.com/2021/08/08/improving-responsiveness-in-text-inputs/
источник
2021 November 17
Defront (при поддержке Зарплата.ру) — про фронтенд-разработку и не только
За прошедшие две недели в канале для патронов Defront было опубликовано одиннадцать постов:

— Невыполненные обещания serverless
— Оценка проектов с помощью метода Монте Карло
— Как запомнить прочитанное
— Отключение scroll chaining с помощью overscroll-behavior
— Веб-платформа Aviasales
— Три ужасные фичи программирования из прошлого
— Проксирование сторонних скриптов с помощью Cloudflare Workers
— Оптимизация видео-обложек страницы (Hero Videos)
— Законы и принципы разработки
— Текущее состояние веба
— Создание компонента изображений для Next.js

Становитесь патроном канала на Patreon, чтобы получить доступ к дополнительным постам в Defront Plus. Все донаты идут на поддержку канала, покупку еды, аренду квартиры, оплату медицинских услуг и т.п.

Спасибо всем, кто читает и поддерживает Defront!

https://www.patreon.com/myshov
источник
Defront (при поддержке Зарплата.ру) — про фронтенд-разработку и не только
Релиз Chrome 96

Вчера вышла новая версия Chrome. Пит Лепаж и Джеселин Ин по традиции рассказали обо всех новинках релиза — "New in Chrome 96".

В рамках Origin Trail появилась поддержка хинтов приоритета (priority hints). Хинты приоритета устанавливаются с помощью атрибута importance. Они используются в качестве сигналов на уровне разметки документа для управления последовательностью загрузки ресурсов.

Включена поддержка флага #force-major-version-to-100 для поднятия версии Chrome до 100. Этот флаг был добавлен для поиска потенциальных проблем парсинга строки User-Agent.

Реализована поддержка оптимизации Back/Forward Cache (BFCache). Теперь при каждой навигации браузер не удаляет из памяти ресурсы, использующиеся страницей, а отправляет их в BFCache на несколько минут. Если пользователь захочет вернуться назад на предыдущую страницу, то она будет восстановлена из этого кеша. Данная оптимизация использовалась только в Firefox и Safаri. Теперь она есть во всех браузерах.

Сделано несколько улучшений для PWA. В Chrome 96 была добавлена поддержка указания явного идентификатора приложения в манифесте с помощью поля id. Также теперь PWA-приложения могут регистрироваться в качестве обработчиков протоколов. Например, если PWA почтового клиента зарегистрируется как обработчик протокола mailto, тогда это приложение будет открываться автоматически при кликах по ссылкам с префиксом mailto:.

Есть много изменений в инструментах разработчика. Отображение содержимого запроса переехало из вкладки "Headers" в новую вкладку "Payload". В тестовом режиме добавлен CSS Overview. Появилась возможность копирования CSS-деклараций в формате, пригодном для вставки в JS, — полезное новшество для всех, кто использует CSS-in-JS. Теперь ошибки CORS в консоли можно спрятать. Добавлена поддержка эмуляции prefers-contrast и тёмной автотемы.

#chrome #release

https://developer.chrome.com/blog/new-in-chrome-96/
https://developer.chrome.com/blog/new-in-devtools-96/
источник
Defront (при поддержке Зарплата.ру) — про фронтенд-разработку и не только
Google Chrome 96 «сломал» Twitter, Discord и многое другое

После релиза Google Chrome 96 пользователи сообщают о проблемах с Twitter, Discord, Instagram, рендерингом видео и так далее. Разработчики уверяют, что им уже известно об этих проблемах новой версии браузера.

https://xakep.ru/2021/11/17/shrome-96-bugs/
источник
2021 November 18
Defront (при поддержке Зарплата.ру) — про фронтенд-разработку и не только
Релиз TypeScript 4.5

Сегодня вышел TypeScript 4.5. Дениэл Розенвассер рассказал о всех новинках релиза.

Был добавлен новый утилитарный тип Awaited. Этот тип моделирует разворачивание промисов с помощью await в async-функциях и метода .then() у промисов. Awaited теперь используется для типизации Promise.all, улучшая вывод типов.

С версии 4.5 встроенные типы можно обновлять отдельно от компилятора. Также теперь можно оверрайдить встроенные типы, используя пакеты @typescript/lib-* в node_modules.

Строковые шаблонные типы могут использоваться в качестве дискрименантов в union'ах. Эта фича будет полезна при типизации ответов API.

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

Появилась возможность отключения удаления неиспользуемых импортов. Также в рамках этой фичи был добавлена поддержка модификатора type для импортируемых типов: import {someFunction, type BaseType} from "./module.js";.

Реализованы пропозалы "Ergonomic Brand Checks" и "Import assertions".

Также в этой версии должна была появиться поддержка ESM для Node.js, но она была временно удалена из-за несовместимости с экосистемой и проблем в реализации.

#release #typescript

https://devblogs.microsoft.com/typescript/announcing-typescript-4-5/
источник
2021 November 19
Defront (при поддержке Зарплата.ру) — про фронтенд-разработку и не только
Рендеринг DOOM с помощью чекбоксов

Эндрю Хэли из Vercel рассказал про свой эксперимент с DOOM — "DOOM Rendered via Checkboxes".

В статье рассказывается про интеграцию библиотеки Checkboxland и WebAssembly-порта DOOM. Checkboxland — это библиотека для рисования с помощью чекбоксов на HTML-странице. С её помощью можно рендерить текст, фигуры, изображения и видео.

Для рендеринга картинки DOOM используется видео. Изображение из <canvas> захватывается с помощью метода captureStream(), преобразуется в MediaStream и передаётся методу renderVideo из Checkboxland. Таким образом получается картинка. Автор пишет про то, что на высоких разрешениях всё тормозило, поэтому он остановился на разрешении 160x100. Вполне возможно, что в будущем мы увидим какой-нибудь бенчмарк на базе этого проекта.

Статья несерьёзная, но интересная. Рекомендую заглянуть.

#webassembly #fun

https://healeycodes.com/doom-rendered-via-checkboxes
https://habr.com/ru/post/590337/ (мой перевод на русский язык)
источник