Scrollbar в современном CSS / Хабр | Веб-студия Nat.od.ua
Scrollbar в современном CSS / Хабр
Всем привет! Начнем с того что scrollbar это очень обыденный элемент, присутствующий на всех веб-сайтах и в каждом приложении. Исторически сложилось так, что его было трудно кастомизировать и поэтому разработчики старались обходить стороной работу с ним если того четко не требовало ТЗ, но все же, как мне кажется, мы должны уделять им немного больше внимания. Давайте посмотрим, что мы можем сделать в 2022 году, чтобы улучшить возможности прокрутки для наших пользователей.
Основы
Когда содержимое элемента слишком велико и не помещается в нем, то, чтобы сделать его прокручиваемым, мы можем использовать overflow: auto. Это нужно, чтобы полосы прокрутки отображались по умолчанию.
Что касается стилизации scrollbar-a, то вы можете использовать свойства scrollbar с префиксом -webkit в сочетании со стандартными свойствами ширины: scrollbar-width и цвета: scrollbar-color. На эту тему есть множество публикаций, поэтому я не буду вдаваться в подробности. Если вы еще не знакомы с этими свойствами, я рекомендую вам ознакомиться с руководством, составленным Ахмадом Шейдидом.
Так же я хочу упомянуть плагин postcss-scrollbar, который генерирует свойства полосы прокрутки с префиксом -webkit из стандартных свойств, что позволяет вам получить кросс-браузерные стили только с помощью допустим такого кода:
.scroll-container {
overflow: auto;
scrollbar-width: thin;
scrollbar-color: hsl(0 0% 50%);
/* postcss-scrollbar will add the -webkit version automatically! */
}
Выглядит достаточно просто. А теперь перейдем к более интересным моментам.
Scrollbar и темы
Если вы все еще хотите использовать стили scrollbar по умолчанию, это ваше право. Но вам нужно учитывать, если ваш сайт поддерживает темную тему. На многих сайтах при переключении на темный режим полосы прокрутки застревают в светлом. Вот как выглядят документы remix.run в Windows в темном режиме:
Это можно исправить с помощью свойства color-scheme. Прибегать к ним вам придется в разных ситуациях, в том числе – не связанных со scrollbar. У Томаса Штайнера есть отличная статья на web.dev, если вы хотите узнать об этом больше.
html {
/* defer to OS preference */
color-scheme: dark light;
/* override, assuming the theme toggler sets a data-theme attribute */
& { color-scheme: light; }
& { color-scheme: dark; }
}Особенности полосы прокрутки в различных операционных системах
В данном разделе я буду размышлять о различных окружениях, поведении в них полос прокрутки и проблемах, связанных с тем или иным поведением, а также выскажу некоторые свои предположения. Если вас интересует только код, смело прокручивайте этот раздел до конца.
Windows
Как я продемонстрировал в предыдущем разделе, Windows всегда отличалась самыми уродливыми полосами прокрутки, по сравнению с другими платформами. Windows 10 имеет наиболее неприглядные полосы прокрутки во всех браузерах. Даже если выбрать правильную цветовую схему, они все равно выглядят излишне квадратными и толстыми.
В Windows 11 попытались модернизировать полосы прокрутки, сделав их тоньше и накладывая друг на друга. Что касается браузеров, Firefox загружает их в таком виде всегда, в то время как Edge или Chrome – модифицируют в той или иной форме.
Особенно мне не нравится реализация Firefox, потому что полоса прокрутки тонкая и исчезает, если вы активно не взаимодействуете с ней. Что еще хуже, кажется, что нет никакого способа изменить это поведение программным путем. Firefox поддерживает опцию «Всегда показывать полосы прокрутки» только в Windows 11, но она отключена по умолчанию, и естественно большинство пользователей не догадаются ее включить. Я очень надеюсь, что этот момент будет учтен в следующем обновлении браузера. Но пока мы ничего сделать с этим не в состоянии.
В Chromium все проще, там у нас гораздо больше возможностей повлиять на scrollbar, хотя бы с теми же стилями -webkit-scrollbar.
macOS
Полосы прокрутки в macOS выглядят менее безобразными, но они имеют свои недостатки.
Возможно, я слишком придирчив, но я разочарован, что не могу просто переместить курсор на правый край окна браузера и использовать его для прокрутки. Это связано с тем, что macOS резервирует края для изменения размера или перемещения окна, даже если курсор все еще находится на бегунке полосы прокрутки. Это неизбежно делает и без того тонкую полосу прокрутки еще тоньше (хотя и только для прокрутки окна просмотра).
Вторая проблема более актуальна: автоматически исчезающие полосы прокрутки. Они могут способствовать созданию приятного и не загроможденного интерфейса, но… это в том случае если пользователь знает, что часть страницы является прокручиваемой. Недавно у меня был случай, когда я буквально не мог найти билет на конференцию, потому что он был скрыт за пределами обозримой области, а полоса прокрутки была невидимой. Другими словами, исчезновение полос прокрутки может в буквальном смысле стоить вам денег. Чтобы обойти эту проблему, нужно высоту полосы прокрутки сделать такой, чтобы последний элемент был наполовину виден. Или же – использовать JavaScript для определения положения прокрутки и добавления тени прокрутки.
Но ест и хорошие новости, обе эти проблемы можно избежать путем задания пользовательского стиля.
Android, iOS и сенсорные экраны
У сенсорных устройств такие же тонкие, накладные и исчезающие полосы прокрутки, которые я назвал проблемой в macOS, но используются они совершенно по-другому: пользователь не взаимодействует напрямую с полосой прокрутки, а просто проводит пальцем по экрану. Кроме того, поскольку сенсорный экран обычно более маленький, на нем умещается меньше информации, и ожидается, что пользователь будет прокручивать намного чаще, чтобы просмотреть контент. Именно потому существуют специальные функции, такие как (1) прокрутка на основе импульса (инерция) и (2) визуальная подсветка или пружинная анимация при достижении края прокручиваемого контейнера. Android еще более внимательно относится к этому и показывает полосу прокрутки при первом появлении прокручиваемого элемента, а затем переключается на обычное автоматическое исчезновение полос после того, как пользователь прокрутил хотя бы один.
Мне очень нравится поведение по умолчанию этих scrollbar-ов и я хотел бы сохранить его. Это достижимо с помощью медиа-запроса pointer, который позволит нам условно стилизовать полосы прокрутки в зависимости от того, использует ли пользователь мышь или сенсорный экран.
@media (pointer: fine) {
.scroll-container {
/* …custom scrollbar styles only for desktop */
}
}
Я много где это использовал и мне честно говорят результат очень понравился.
Предотвращение поехавшей верстки
Одна из проблем с overflow: auto заключается в том, что оно показывает полосу прокрутки только в том случае, если содержимое переполнено. Это означает, что внезапное появление полосы прокрутки может вызвать небольшое смещение верстки. Эту проблему можно убрать с помощью overflow: overlay (в Chrome), чтобы полоса прокрутки никогда не занимала место, и / или с помощью overflow: scroll, чтобы она всегда была на месте.
В настоящее время мы можем указать браузеру, чтобы он зарезервировал место для полос прокрутки, используя scrollbar-gutter: stable. Он поддерживается в Chrome и Firefox. Если вы используете невидимый scrollbar, то этот резервный вариант должен работать так же, как scrollbar-gutter.
.scroll-container {
overflow: scroll;
@supports (scrollbar-gutter: stable) {
overflow: auto;
scrollbar-gutter: stable;
}
}
Здесь стоит отметить, что если вы хотите, чтобы scrollbar-gutter находилась в области просмотра, то работать с
ее заставить сложно, и, возможно, будет проще переместить ее в дочерний элемент.Еще больше возможностей для scrollbar в современном CSS
Хотя это не связано напрямую со стилем полосы прокрутки, я хочу кратко упомянуть еще несколько свойств, которые могут помочь улучшить прокрутку.
scroll-padding
scroll-padding позволяет создать смещение по краю области прокрутки. Это полезно, когда используется фиксированный заголовок (sticky header), способный закрывать заголовки фрагментов, которые прокручиваются на странице с помощью ссылок перехода или URL-адресов.
.scroll-container {
scroll-padding-top: var(–header-height);
}scroll-behavior
scroll-behavior позволяет включить плавную прокрутку, которая также очень удобна для переходов по ссылкам-якорям внутри страницы.
@media (prefers-reduced-motion: no-preference) {
.scroll-container {
scroll-behavior: smooth;
}
}scroll-padding
Overscroll-behavior выполняет совершенно иную функцию: позволяет предотвратить цепочку прокрутки во вложенных областях прокрутки. Удобно в некоторых местах, таких как диалоговые окна и боковые панели, где вы не хотите, чтобы базовая страница начинала прокручиваться, когда вы достигаете конца текущего контейнера прокрутки.
.scroll-container {
overscroll-behavior: contain;
}Scroll snapping
Представленная некоторое время назад в CSS scroll snapping претерпела многочисленные улучшения и исправления. Сегодня это достаточно надежный и оптимальный способ создания чего-то вроде галереи или компонента stories с почти нулевым использованием JavaScript.
.scroll-container {
scroll-snap-type: x mandatory;
& > * {
scroll-snap-align: start;
}
}Заключение
Благодарю за прочтение публикации и надеюсь, что она вдохновит вас идти по пути улучшения scrollbar на ваших проектах. А на этом собственно все.
Если вдруг кому интересно то я веду телеграм канал по фронтенду где выкладываю интересные статьи на разные темы а так же сам периодически пишу шорт-риды которые могут быть вам полезны.
Fresh — фулл-стек фреймворк для Deno / Хабр | Веб-студия Nat.od.ua
Fresh — фулл-стек фреймворк для Deno / Хабр
Эта статья — перевод оригинальной статьи Luca Casonato “Fresh 1.0”
Также я веду телеграм канал “Frontend по-флотски”, где рассказываю про интересные вещи из мира разработки интерфейсов.
Вступление
Fresh — это новый полнофункциональный веб-фреймворк для Deno. По умолчанию веб-страницы, созданные с помощью Fresh, не отправляют никакого JavaScript в браузер. Фреймворк не имеет шага сборки, что позволяет на порядок сократить время развертывания. Сегодня мы выпускаем первую стабильную версию Fresh.
В последние годы рендеринг на стороне клиента становится все более популярным. Страницы React (и подобные React) позволяют программам относительно легко создавать очень сложные пользовательские интерфейсы. Популярность проявляется в текущем пространстве веб-фреймворков: в нем преобладают фреймворки на основе React.
Но рендеринг на стороне клиента стоит дорого; фреймворк часто отправляет пользователям сотни килобайт клиентского JavaScript по каждому запросу. Эти пакеты JS часто делают немногим больше, чем рендеринг статического контента, который с таким же успехом можно было бы использовать как обычный HTML.
Некоторые новые фреймворки также поддерживают рендеринг на стороне сервера. Это помогает сократить время загрузки страницы за счет предварительного рендеринга на сервере. Но большинство современных реализаций по-прежнему предоставляют каждому клиенту всю инфраструктуру рендеринга для полного приложения, поэтому страница может быть полностью повторно отрендерена на клиенте.
Это плохой подход к разработке — клиентский JavaScript очень дорог: он замедляет работу пользователя, резко увеличивает энергопотребление на мобильных устройствах и часто не очень надежен.
Fresh использует другую модель: по умолчанию вы отправляете клиентам 0 КБ JS. Таким образом большая часть рендеринга выполняется на сервере, а клиент отвечает только за повторный рендеринг небольших островков интерактивности. Модель, в которой разработчик явно соглашается на отрисовку определенных компонентов на стороне клиента. Эта модель была описана еще в 2020 году Джейсоном Миллером в его сообщении в блоге Islands Architecture.
По своей сути Fresh представляет собой структуру маршрутизации и механизм шаблонов, который отображает страницы по мере их запроса на сервере. В дополнение к JIT-рендерингу на сервере Fresh также предоставляет интерфейс для плавного рендеринга некоторых компонентов на клиенте для максимальной интерактивности. Фреймворк использует Preact и JSX (или TSX) для рендеринга и создания шаблонов как на сервере, так и на клиенте. Клиентский рендеринг полностью включен на уровне компонентов, и поэтому многие приложения вообще не отправляют JavaScript клиенту.
Fresh не имеет шага сборки. Код, который вы пишете, является непосредственно кодом, который выполняется на стороне сервера и на стороне клиента, и любая необходимая транспиляция TypeScript или JSX в простой JavaScript выполняется вовремя, когда это необходимо. Это позволяет создавать очень быстрые циклы итераций с мгновенным развертыванием.
Быстрый старт
Чтобы действительно объяснить, что делает Fresh особенным, давайте создадим новый проект и посмотрим на код:
deno run -A -r https://fresh.deno.dev my-app
Эта команда создает минимальный шаблон, необходимый для проекта Fresh, в папке, которую вы указали в качестве последнего аргумента (в данном случае my-app). Вы можете узнать больше о том, что означают все файлы, в руководстве по началу работы.
my-app/
├── README.md
├── deno.json
├── dev.ts
├── fresh.gen.ts
├── import_map.json
├── islands
│ └── Counter.tsx
├── main.ts
├── routes
│ ├── .tsx
│ ├── api
│ │ └── joke.ts
│ └── index.tsx
└── static
├── favicon.ico
└── logo.svg
А пока обратите внимание на папку route/. Он содержит обработчики и шаблоны для каждого маршрута приложения. Имя каждого файла определяет, каким путям соответствует маршрут. Например, файл api/joke.ts обслуживает запросы к /api/joke. Структура папок может напомнить вам Next.js или PHP, так как эти системы также используют маршрутизацию файловой системы.
Давайте посмотрим на файл route/index.tsx:
/** @jsx h */
import { h } from “preact”;
import Counter from “../islands/Counter.tsx”;
export default function Home() {
return (
Welcome to `fresh`. Try update this message in the ./routes/index.tsx
file, and refresh.
);
}
Экспорт маршрута по умолчанию — это шаблон JSX, который обрабатывается на стороне сервера для каждого запроса. Сам компонент шаблона никогда не отображается на клиенте.
Это ставит вопрос: что, если вы хотите повторно отобразить некоторые части приложения на клиенте, например, в ответ на какое-либо взаимодействие с пользователем? Для этого и существуют острова в Fresh. Это отдельные компоненты приложения, которые повторно гидратируются на клиенте для обеспечения взаимодействия.
Ниже приведен пример острова, который предоставляет счетчик на стороне клиента с кнопками увеличения и уменьшения. Он использует хук Preact useState для отслеживания значения счетчика.
// islands/Counter.tsx
/** @jsx h */
import { h } from “preact”;
import { useState } from “preact/hooks”;
interface CounterProps {
start: number;
}
export default function Counter(props: CounterProps) {
const = useState(props.start);
return (
{count}
);
}
Острова должны быть помещены в папку islands/. Fresh позаботится об автоматическом повторном гидратации острова на клиенте, если обнаружит его использование в шаблоне маршрута.
Fresh — это не просто интерфейсный фреймворк, а полностью интегрированная система для написания веб-сайтов. Вы можете произвольно обрабатывать запросы любого типа, возвращать настраиваемые ответы, делать запросы к базе данных и многое другое. Этот маршрут возвращает обычный текстовый HTTP-ответ вместо HTML-страницы, например:
// routes/api/joke.ts
const JOKES = ;
export const handler = (_req: Request): Response => {
const randomIndex = Math.floor(Math.random() * JOKES.length);
const body = JOKES;
return new Response(body);
};
Это также можно использовать для асинхронной выборки данных для маршрута. Вот маршрут, который загружает сообщения блога из файла на диске:
// routes/blog/.tsx
import { HandlerContext, PageProps } from “$fresh/server.ts”;
export const handler = async (_req: Request, ctx: HandlerContext): Response => {
const body = await Deno.readTextFile(`./posts/${ctx.params.id}.md`);
return ctx.render({ body });
};
export default function BlogPostPage(props: PageProps) {
const { body } = props.data;
// …
}
Поскольку Fresh так сильно зависит от динамического рендеринга на стороне сервера, крайне важно, чтобы он был быстрым. Это делает Fresh очень подходящим для работы на периферии в средах выполнения, таких как Deno Deploy, Netlify Edge Functions или Supabase Edge Functions. Это приводит к тому, что рендеринг происходит физически рядом с пользователем, что минимизирует задержку в сети.
Развертывание приложения Fresh в Deno Deploy занимает всего пару секунд: отправьте код в репозиторий GitHub, затем свяжите этот репозиторий с проектом на панели инструментов Deno Deploy. Затем ваш проект будет доступен из 33 регионов по всему миру, при этом 100 000 запросов в день включены в уровень бесплатного пользования.
Production Ready
Fresh 1.0 — это стабильная версия, на которую можно положиться при использовании в продакшене. Многие общедоступные веб-сервисы Deno используют Fresh. Это не означает, что мы закончили разработку, у нас есть еще много идей по улучшению взаимодействия с пользователями и разработчиками.
За кулисами Google Colab / Хабр | Веб-студия Nat.od.ua
За кулисами Google Colab / Хабр
Заглянем во внутренности Google Colab и узнаем, как можно подстроить Colab под свои рабочие нужды, а не подстраиваться под ограничения этого инструмента. Подробности рассказываем к старту флагманского курса по Data Science.
Google Colaboratory, более известная как «Colab», — бесплатная платформа для блокнотов Jupyter. Кроме среды запуска блокнотов Python и R Colab позволяет совместно использовать свободный доступ к ограниченному количеству GPU и TPU.
Colab быстро стала де-факто средой программирования блокнотов Jupyter, но использовать Colab для чего-то кроме блокнотов Jupyter невероятно сложно. Особенно это верно для инженеров ML, желающих создать модели и вывести их со стадии блокнота. Блокнот идеален в исследовании, но плохо сочетается с широким инструментарием MLOps, кодифицирующим обучение в формальный конвейер.
За кулисами
Секретный соус Colab — это его бекенд: инфраструктурные серверы Google позволяют запускать код одним щелчком пальцев или одним нажатием кнопки. Так, наш первый шаг — анализ этого бекенд-API. Самое простое — проверить вызовы API Colab во время его нормальной работы:
Запускаем DevTools Chrome, находим вкладку Network и пытаемся запустить ячейку кода.
DevTools начинает записывать каждый запрос Colab — и почти сразу находим нечто интересное:
Похоже, URL /tun/m/
На этот раз тело ответа — JSON, перечисляющий файлы на удалённом узле. Похоже, что URL /tun/m/
Двойной щелчок по файлу на панели Files загружает и отображает этот файл в Colab. Если мы попытаемся нажать на /content/sample_data/README.md, то заметим запрос к /tun/m/
Понятно, что https://colab.research.google.com/tun/m/
Попробуем посмотреть, работает ли какой-то из сервисов внутри экземпляра контейнера Colab. Для этого запустим lsof, установленную внутри контейнера Colab: lsof -iTCP -sTCP:LISTEN, чтобы перечислить все процессы, которые прослушивают TCP-порт:
Угу. Перспективными для изучения поверхностями выглядят процессы colab-fileshim, node и jupyter-notebook. Мы уже имели дело с панелью Files, поэтому сначала посмотрим colab-fileshim. Его PID — 28, а раз так, проверим файловую систему /proc, чтобы увидеть всю команду CLI:
Следующий шаг — исследовать /usr/local/bin/colab-fileshim.py. По иронии судьбы сделать это можно, перейдя к нему на самой панели Files. В основном программа кажется неинтересным файловым сервером. Мало что понятно, кроме того, что сам сервер отвечает на запрос localhost:3453/files фактическим содержимым файла, а на localhost:3453/api/contents — метаданными JSON). А значит, Colab перенаправляет эти запросы с URL туннеля на порт 3453 самого экземпляра.
На вкладке Network Chrome DevTools мы можем щёлкнуть запрос правой кнопкой мыши, чтобы скопировать соответствующую команду cURL и воспроизвести её. Вот параметры cURL для просмотра README.md:
$ curl ‘https://colab.research.google.com/tun/m/m-s-3oy94z70yrj59/files/content/sample_data/README.md?authuser=0’
-H ‘authority: colab.research.google.com’
-H ‘x-colab-tunnel: Google’
-H ‘accept: */*’
-H ‘dnt: 1’
-H ‘accept-language: en-US,en;q=0.9’
-H ‘sec-fetch-site: same-origin’
-H ‘sec-fetch-mode: cors’
-H ‘sec-fetch-dest: empty’
-H ‘referer: https://colab.research.google.com/’
-H ‘cookie: <
-H ‘range: bytes=0-930’
–compressed
Выполнив эту команду на терминале локального компьютера, получим содержимое README, а после проб и ошибок увидим, что большинство из этих заголовков можно урезать, а оставить только эти:
$ curl ‘https://colab.research.google.com/tun/m/m-s-3oy94z70yrj59/files/content/sample_data/README.md?authuser=0’
-H ‘x-colab-tunnel: Google’
-H ‘cookie: <
Заголовок x-colab-tunnel предназначен помешать нам (или злоумышленникам) делать эти запросы из обычных вкладок браузера, якобы для остановки атак XSS. Заголовок cookie отвечает за аутентификацию Google, которая доказывает, что у нас есть право доступа к экземпляру блокнота. Сookie-файл длинный и громоздкий, поэтому сохраним его в переменной оболочки $COLAB_COOKIE.
$ COLAB_COOKIE=”<
# Usage: $ curl … -H “cookie: $COLAB_COOKIE”1. Замена серверов Colab своими серверами
Посмотрим, можно ли использовать обнаруженный обратный прокси для туннелирования запросов. Не будем возиться с существующим сервером colab-fileshim.py, а просто заменим процесс нашим сервером! Запускаем pkill -f colab-fileshim, чтобы убить процесс, а затем на том же порту запустить наш сервер. Демонстрация — HTTP-сервер по умолчанию для обслуживания наших файлов по адресу localhost:3453/files.
Вуаля! Теперь перепишем команду cURL для загрузки наших файлов!
$ curl ‘https://colab.research.google.com/tun/m/m-s-3oy94z70yrj59/files/message.txt?authuser=0’
-H “x-colab-tunnel: Google” -H “cookie: $COLAB_COOKIE”
Hi! You’ve reached our own file server!$ curl ‘https://colab.research.google.com/tun/m/m-s-3oy94z70yrj59/files/shadow?authuser=0’
-H “x-colab-tunnel: Google” -H “cookie: $COLAB_COOKIE”
root:*:18585:0:99999:7:::
daemon:*:18585:0:99999:7:::
bin:*:18585:0:99999:7:::
sys:*:18585:0:99999:7:::
sync:*:18585:0:99999:7:::
# …
Обратите внимание на строку лога в ячейке Colab. Она доказывает, что запрос обработал наш сервер:
Serving HTTP on 0.0.0.0 port 3453 (http://0.0.0.0:3453/) …
172.28.0.1 – – “GET /files/message.txt HTTP/1.1” 200 –
172.28.0.1 – – “GET /files/shadow HTTP/1.1” 200 –
К сожалению, из-за требования заголовка x-colab-tunnel: Google легко получить доступ к серверу из браузера нельзя.
Дальнейшая разведка
Взглянем на другой интересный процесс — это node. Проверим /proc/7/cmdline и увидим, что процесс выполняет /datalab/web/app.js. А там мы обнаружим, что /datalab/web содержит довольно стандартное приложение NodeJS. Наряду с маршрутом /socketio/ оно также предоставляет маршрут /_proxy/{port}/. Это должно позволить получить доступ к любому URL с любого порта !!! на экземпляре Colab:
$ curl ‘https://colab.research.google.com/tun/m/m-s-3oy94z70yrj59/_proxy/1234/some/path?authuser=0’
-H “x-colab-tunnel: Google” -H “cookie: $COLAB_COOKIE”
Hi from Colab!
path=/some/path
%
Если бы только мы могли просматривать эту страницу из вкладки браузера… К сожалению, Colab отказывается передавать запросы, если у них нет x-colab-tunnel: Google. В попытке посетить эти URL-адреса из браузера мы увидим HTTP-ошибку 400:
Отображение целых веб-страниц
К счастью, для вставки HTTP-заголовков в запросы браузера можно воспользоваться расширением Chrome. Настроим его на отправку x-colab-tunnel: Google по всем запросам:
И запустим туннельные URL прямо в браузере!
К Jupyter!
Напоследок посмотрим на третий и последний интересный процесс — jupyter-notebook, который слушает порт 9000. Можно попробовать посетить порт из браузера, используя наш прокси и трюк с заголовком, посетить /tun/m/
Странно. Пытаемся запустить !curl -i localhost:9000 из самого блокнота, но всё равно получаем сообщение об ошибке:
Прошлый вывод lsof даёт нам подсказку: вместо прослушивания 0.0.0.0/:: (все IP-адреса по всем интерфейсам) Jupyter прослушивает только приватный IP, предоставленный экземпляру Colab. Так сделано, по-видимому, чтобы избежать раскрытия интерфейса Jupyter. Конечно. Google не старался изо всех сил, чтобы скрыть его.
Чтобы обойти ограничение адреса прослушивания, нужно создать процесс, прослушивающий все интерфейсы и IP, перенаправляющий весь получаемый трафик на конкретный IP, который прослушивает Jupyter. Для этого можно установить socat («Socket Cat») и через него переслать трафик с localhost:9000 на $HOSTNAME:9000 и обратно:
Началось! Перезагрузив URL-адрес в браузере, увидим фрагменты UI Jupyter, но он явно сломан.
Jupyter ожидает, что доступ к нему будет получен в корне домена (/), но наш туннель Colab имеет путь /tun/m/
Показываем UI Jupyter
К счастью, для этого у Colab есть хорошо скрытое, но официальное решение! Как ни странно, оно скрыто настолько хорошо, что мне потребовалось больше времени, чтобы найти его, чем на то, чтобы найти внутренний обратный прокси!
Чтобы узнать, как использовать официальную переадресацию портов Colab, вам нужно открыть вкладку Code Snippets на левой боковой панели и найти фрагмент обработки вывода. Нажмите «View Source Notebook» и вы попадёте в advanced_outputs.ipynb, сборник фрагментов от Colab. Эти фрагменты демонстрируют пугающе документированные функции платформы. Конкретный фрагмент, который нам нужен, можно найти в разделе «Browsing to servers executing on the kernel».
Этим фрагментом мы можем воспользоваться для предоставления пользовательского интерфейса Jupyter на поддомене:
И теперь можно щёлкнуть ссылку, добавить /tree к URL, чтобы унять Jupyter, и увидеть полностью работающий UI Jupyter! Ну, почти полностью. Google, похоже, ограничил официальный прокси только запросами GET, что позволяет просматривать, но не запускать блокноты.
А мы поможем прокачать ваши навыки или с самого начала освоить профессию, актуальную в любое время:
Выбрать другую востребованную профессию.
Фронтенд-новости №12. Вышел EcmaScript 2022, фавиконки в 2022, как будет выглядеть веб только с Chromium | Веб-студия Nat.od.ua
Фронтенд-новости №12. Вышел EcmaScript 2022, фавиконки в 2022, как будет выглядеть веб только с Chromium
Дайджест новостей и полезных статей из мира фронтенд-разработки за неделю 20–26 июня.
🧍♂️Доступность
📔 Выбор даты и времени для всех. Ребята из Adobe сделали библиотеку react spectrum более доступной для выбора даты и времени. Очень полезно посмотреть со стороны UX на взаимодействие с формами выбора даты и времени, так как это действительно сложно.
📔 Как сделать переключатель тёмного режима. Применение ARIA, когда он необходим, то есть отсутствует в HTML и приносит пользу пользователю.
📔 Библиотека ARIA шаблонов для популярных элементов. Узнайте, как делать самые распространенные элементы более доступными, применяя роли, состояния и свойства WAI ARIA.
🧂 Спецификации
📔 Page Visibility Level 2. Вышел новый уровень спецификации для состояния видимости документа.
📔 EcmaScript 2022. 22 июня 2022 года 123 Генеральная ассамблея Ecma утвердила спецификацию языка ECMAScript 2022 — теперь он официально является стандартом. Внутри все новинки.
🧬 HTML
📔 Всплывающие окна мертвы, да здравствуют всплывающие окна. Узнайте, как Великобритания планирует убить всплывающие окна с файлами cookie.
📔 Семантическая карточка-ссылка. Семантика для обычных карточек: карточка товара или карточка статьи блога.
📔 Как создавать иконки сайтов в 2022 году — всё о favicon. Пришло время переосмыслить то, как мы создаем набор иконок для современных браузеров, и остановить безумные генераторы.
🖌️ CSS
📔Современная CSS-прокрутка. Большинство интерфейсов имеют полосу прокрутки у страницы или блока. Исторически так сложилось, что настройка полосы прокрутки никогда не была лёгким занятием. Кто-то даже умудряется написать тысячи строк кода, чтобы повторить работу полосы прокрутки на JavaScript.
Полосы прокрутки полезно стилистически изменять, когда меняется тема сайта с светлой на тёмную, иначе полоса прокрутки будет пестрить и перетягивать на себя внимание.
Также стоит помнить, что в различных операционных системах, десктопных и мобильных, у полос прокрутки меняется поведение и возникают кроссбраузерные проблемы.
У oveflow: auto тоже есть проблемы. Если в блоке становится много контента, то появляется полоса прокрутки, которая смещает следующий контент.
В статье рассматриваются современные CSS-возможности по настройке полосы прокрутки.
📔 Пожалуйста, дайте мне немного места в разметке для разделения слов. Текстовыми параметрами в стилях в тексте между словами и буквами. Трансформациями и позиционированием. Флексами. У таблиц с помощью стилей. Прозрачными блоками-заполнителями. Для каждой ситуации подойдёт свой способ.
📔 Две строки CSS, повышающие производительность рендеринга. Коротко:
{
content-visibility: auto;
contain-intrinsic-size: 1px 5000px;
}
content-visibility: auto — определяет будет браузер пропускать этапы paint и rendering для элемента. Поддержка браузерами.
contain-intrinsic-size — в связи с предыдущим пунктом элементы, которые не прошли этап rendering, скорее всего, будут иметь размер 0x0. contain-intrinsic-size позволяет подсказать браузеру действительные размеры элемента, чтобы интерфейс не прыгал. Поддержка браузерами.
📔 Многоточие для переполнения текстов вредно. Для эффективной работы text-overflow часто приходится использовать дополнительные CSS-свойства white-space: nowrap и overflow: hidden, но это может плохо сказаться на кнопках.
📔 Условное оформление выбранных элементов в гридах. Тренируемся в сложных селекторах, в которых используются комбинаторы и псевдоэлементы.
📔 Как и когда использовать :has. Теория о том, что такое :has, как с ним работать и применять в карточках и формах.
🏗️ JavaScript
📔 Блочный оператор. Помогает организовать код, придумать другое имя для той же переменной.
📔 В защиту блочного оператора
📔 Когда стоит отказаться от Map в пользу объекта
Используйте объект для записей, где у вас есть фиксированное и ограниченное количество свойств или полей, известных на момент создания, например, конфигурационных объектов. И вообще для всего, что предназначено для одноразового использования.
Используйте Map для словарей или хэш-карт с переменным количеством записей, с частыми обновлениями, ключи которых могут быть неизвестны в момент создания, например, эмиттер события.
Согласно тестам, если только ключи не являются строками маленьких целых чисел, Map действительно более производителен, чем объект, по скорости вставки, удаления и итерации, и он потребляет меньше памяти, чем объект того же размера.
📔 Точное определение времени с помощью API веб-анимации. Таймеры — необходимость для разработчика, чтобы точно знать, когда что происходит. Но на самом деле таймеры никогда не бывают вовремя. Web Animations API поможет отказаться от некоторых таймеров в некоторых случаях.
📔 Заметки о сервис-воркерах. Вещи, которые вы бы хотели знать раньше о сервис-воркерах.
📔 JavaScript: интересные возможности AbortController. Паттерны для AbortController.
📔 Как в современном мире обрабатывать ошибки в Javascript?
🚀React
📔 Над чем работает команда React. Команда решила начать заранее делиться тем, над чем они трудятся:
📔 Миграция нативных React библиотек на новую архитектуру. Обновлённые рекомендации для перехода приложения и библиотек на новую архитектуру.
📔Организация react-компонентов с помощью dot-notation и почему я часто прибегаю именно к этому способу. Существует несколько способов организации компонентов и каждый из них полезен в конкретной ситуации. И нужно выбирать подходящий дизайн его реализации в зависимости от функциональности компонента и его предназначения.
💽 Node.js
📔 Используйте веб-потоки в node.js. Web-streams — это стандарт для потоков, который теперь поддерживается на всех основных веб-платформах: браузеры, node.js и Deno.
📔 Альтернативы глобальной установки npm-пакетов. Для npm install –global package-name в macOS и некоторых Unix-платформах требуются root-права. Узнайте об альтернативных вариантах –global.
📔 Небольшой релиз v18.4.0
📔 Анализатор аргументов командой строки. Встроен в v18.3.0. Не такой мощный, как yargs , minimist или argparse, но уже можно пробовать.
🔮 Angular
📔Как Computed Properties в Angular помогают пропускать титры
📔Улучшение начальной загрузки приложения
🟩 Vue
📔Vue 2.7 в бете
А также на русском на Хабре.
📔 Тернистый путь к микрофронтам. Ребята из Азбуки вкуса делятся своим путём обновления приложения до Vue 2 + Nuxt 2 с поддержкой TypeScript.
📔 Использование v-model в Vue 3 для создания сложных форм
🛠️ Инструменты
Puppeteer 15.0
grammY — современная платформа Telegram-ботов
PSD 0.2 — синтаксический анализатор PSD с нулевой зависимостью для браузера или node.js
TypeScript beta 4.8 с улучшением производительности
🕸️Браузеры
📔 Что Github думает о браузерах. А точнее, какие версии браузеров, какое браузерное API поддерживают и какими инструментами они пользуются для кроссбраузерности.
📔 Как будет выглядеть веб только с Chromium?
📔 Safari Technology Preview 147
Live text. Переводите и взаимодействуйте с текстом внутри видео и изображениях на Venture и M-процессорах.
Web Push. Отправляйте пуш-уведомления со страницы в браузере.
Passkeys. Обезопасьте свои учётные данные на сайтах.
Improved Safari Web Extensions. Протестируйте улучшенный API для расширений.
Web Inspector Extensions. Создайте собственный инструмент для веб-инспектора.
Flexbox Inspector. Используйте новую визуальзацию флексов в веб-инспекторе.
📔 Chrome 105. Актуальная версия 103. А в 105 версии появится псевдокласс :has.
📔 Текущий Safari в iOS. Имеет баг перекрытия нескольких фулскрин-видео. Safari не проверяет, если ли другой ресурс, который уже получил полноэкранный доступ.
📔 Ку-ку. Internet Explorer никуда не делся. То, что поддержка прекращена, ещё не значит, что им перестанут пользоваться.
🎓Общее
📔 Взлет и падение неоморфизма. Скеоморфизм + плоский дизайн = Неоморфизм. Прошлое, настоящее, будущее, и почему неоморфизм быстро входит и выходит из моды.
📔 Что такое минималистичный веб-дизайн простыми словами. Часто дизайнеры воспринимают минимализм как набор необходимых элементов без добавления лишних деталей. Однако этим стиль не ограничивается. Основная идея минимализма — акцент на содержании сайта, а не на его дизайне.
Главные особенности минимализма в дизайне: простота, чистые цвета, изображения без фона, пространство, композиция, типографика и UX.
📔 Сочетания шрифтов от Google. Чтобы начать разбираться в шрифтовых парах, начните со статьи «Парные шрифты». В этой статье познакомимся с 9 парами. С этими парами можно поиграться в Figma.
Чтобы правильно подобрать пару нужно, чтобы пары вели к одной цели, которую вы хотите достичь:
были легко читаемыми;
имели различные веса и стили;
поддерживали необходимых языков;
имели интересные глифы, если это необходимо для цели.
📔 Прощай, Web3. Web5 уже здесь. Не успели вы даже понять, что такое Web3, а уже Web5. А Web4 вообще был? Web2 + Web3 = Web5.
📔 Как Apple может бить CAPTCHA? С помощью токенов частного доступа.
📔 Figma vs Sketch. Узнайте какой инструмент лучше подходит для UX/UI, прототипирования и совместной командной работы.
Обратная связь
Привет. Я поменял формат дайджеста и буду благодарен за обратную связь, чтобы сделать его ещё лучше. Спасибо.
Как читать статьи на английском языке
В дайджесте много статей и видео на английском языке, чтобы это не стало препятствием: в Google Chrome есть функция перевода страницы с любого популярного языка, а видео можно перевести в Яндекс Браузере.
Обзор паттернов хранения деревьев в реляционных БД / Хабр | Веб-студия Nat.od.ua
Обзор паттернов хранения деревьев в реляционных БД / Хабр
Всем привет! Меня зовут Пантелеев Александр и я бэкенд-разработчик в компании Bimeister.
Постараюсь описать исчерпывающе, кратко и понятно суть основных паттернов хранения деревьев в реляционных базах данных. Надеюсь, что статья будет полезна тем, кто до сего момента не сталкивался с такими паттернами, и станет отправной точкой в их понимании.
В этой статье не будет терминов реляционной алгебры или базы данных: таких как атрибут, домен и т. д. Также не будет привязки к какой-либо СУБД, какому-либо SQL или пользовательскому коду.
Всего существует 4 общепринятых паттерна хранения деревьев:
Adjacency List;
Nested Sets;
Closure Table;
Materialized Path.
Кратко рассмотрим каждый из них.
Adjacency ListОписание
Это самый простой и интуитивный вариант хранения. Каждому элементу сопоставляется его свойство — его родительский элемент. Если родительский элемент не задан, то он считается корневым элементом.
Когда связь сопоставления элемента и родительского элемента хранится отдельно от элемента, Adjacency List можно рассматривать как частный случай Closure Table со связями 1 уровня.
Преимущества
Лёгкость реализации, а также простота вставки, удаления и перемещения элементов в дереве.
Недостатки
Можно получить только непосредственные дочерние элементы. Чтобы получить все дочерние элементы, необходимо выполнить рекурсивный запрос либо производить множественные запросы.
ПримерыРисунок 1.
Элемент
Родительский элемент
A
–
B
A
C
B
D
C
E
B
F
B
G
A
H
G
I
A
Рассмотрим элемент «B»:
Чтобы получить все его дочерние элементы, нам необходимо выбрать элементы, удовлетворяющие условию:
Родительский элемент равен «B»
Nested SetsОписание
Каждому элементу сопоставляются свойства: левый и правый индекс, на основе которых будет производиться выборка дочерних элементов. Также, но необязательно, элемент может дополняться свойством уровень для указания желаемого уровня вложенности выбираемого элемента относительно корня или родительского элемента.
Запрос получения дочерних элементов строится на том факте, что для любого дочернего элемента выполняются условия:
левый индекс больше левого индекса родительского элемента;
правый индекс меньше правого индекса родительского элемента.
При создании и обновлении дерева левые и правые индексы элементов дерева, при его обходе в глубину, заполняются по определённым правилам.
Преимущества
Возможность получения дочерних элементов любых уровней вложенности с помощью простого одиночного запроса.
Недостатки
При использовании целочисленных типов для левого и правого индекса и уровня необходимо пересчитывать индексы всех связанных элементов в следующих случаях:
при вставке элементов;
при удалении элементов;
при изменении родительского элемента.
ПримерРисунок 2.
Элемент
Левый индекс
Правый индекс
Уровень
A
1
18
0
B
2
11
1
C
3
6
2
D
4
5
3
E
7
8
2
F
9
10
2
G
12
15
1
H
13
14
2
I
16
17
1
Рассмотрим элемент «B». Его значения свойств:
Чтобы получить все его дочерние элементы, нам необходимо выбрать элементы, удовлетворяющие условию:
левый индекс больше 2 И правый индекс меньше 11
Чтобы получить его непосредственные дочерние элементы, нам необходимо добавить к условию ограничение на уровень:
левый индекс больше 2 И правый индекс меньше 11 И уровень = 1
Чтобы получить дочерние элементы вместе с родительским элементом, нам необходимо ослабить условия индексов:
левый индекс больше или равен 2 И правый индекс меньше или равен 11
Closure TableОписание
Суть этого паттерна заключается в том, что мы сопоставляем каждому элементу множество связей со всеми его дочерними элементами или сопоставляем каждому элементу множество связей со всеми его родительскими элементами. Также, но необязательно, связь может содержать свойство Уровень. Уровень задаёт расстояние между элементами в дереве.
Если в запросе получения дочерних или родительских элементов по элементу необходимо получать в результате сам элемент, то нужно добавлять связь элемента самого на себя — то есть со значением уровня связи 0.
Преимущества
Возможность получения дочерних элементов любых уровней вложенности с помощью простого одиночного запроса.
Возможность получения родительских элементов любых уровней с их иерархией относительно дочернего элемента с помощью простого одиночного запроса.
Недостатки
При вставке и удалении элементов из дерева, а также при перемещении элементов в дереве необходимо пересчитывать все связи, в которых этот элемент участвует.
ПримерРисунок 3.
Родительский элемент
Дочерний элемент
Уровень
A
A
0
A
B
1
A
C
2
A
E
2
A
D
3
B
B
0
B
C
1
B
E
1
B
D
2
C
C
0
C
D
1
E
E
0
D
D
0
Рассмотрим элемент «B»:
Чтобы получить все его дочерние элементы, нам необходимо выбрать элементы, удовлетворяющие условию:
родительский элемент равен «B»
Чтобы получить его непосредственные дочерние элементы, нам необходимо добавить к условию ограничение на уровень:
родительский элемент равен «B» И уровень = 1
Чтобы получить дочерние элементы вместе с родительскими, нам необходимо ослабить условия индексов:
родительский элемент равен «B» И уровень = 0
Чтобы получить все его родительские элементы, нам необходимо выбрать элементы, удовлетворяющие условию:
дочерний элемент равен «B»
Materialized PathОписание
Каждому элементу сопоставляется свойство — его путь, который является последовательностью родительских элементов заданного элемента, отсортированных по уровням. В общем случае, чтобы формировать гибкие запросы, тип реализации свойства путь должен поддерживать сопоставление по шаблону в каком-либо виде. При денормализации пути в отдельную таблицу получается разновидность Closue Table.
Условия запросов на получение элементов заключается в применении предиката над свойством путь.
Преимущества
Возможность получения дочерних элементов любых уровней вложенности.
Возможность получения родительских элементов любых уровней с их иерархией относительно дочернего элемента.
Лёгкость вставки элемента.
Лёгкость удаления элемента.
Недостатки
Сложность изменения родителя для существующего элемента. Для всех дочерних элементов необходимо пересчитать новый путь.
Операции со свойством путь обычно происходят долго.
ПримерРисунок 4.
Элемент
Путь
A
B
A
C
A B
D
A B C
E
A B
Рассмотрим элемент «B»:
Чтобы получить все его дочерние элементы, нам необходимо выбрать элементы, удовлетворяющие условию:
путь содержит «B»
Чтобы получить его непосредственные дочерние элементы, нужно указать позицию, в которой содержится элемент. В примере путь отсортирован так, что последняя часть пути — это непосредственный родительский элемент:
последняя часть пути равна «B»
Заключение
Мы кратко рассмотрели основные паттерны хранения деревьев в реляционной базе данных. Их основные достоинства и недоставки, а также на примерах рассмотрели основные запросы к ним. В этой статье не были рассмотрены алгоритмы построения и заполнения метаданных деревьев, то есть операции добавления, обновления и удаления элементов.
Левитация — а не отделить ли нам сайт от движка? / Хабр | Веб-студия Nat.od.ua
Левитация — а не отделить ли нам сайт от движка? / Хабр
200 лет назад начались разборки с авто двигателем. Понадобилось 80 лет для создания двигателя внутреннего сгорания. Результатом разборок стало появление сразу двух индустрий — автомобилестроение и моторостроение.
20 лет назад появилось сайтостроение в виде фреймворков. Оно также началось с разборок с движком. Не с сайтом, с ним все было ясно, а именно с движком. И вот, похоже, разобрались. И с движком, и с сайтом.
Ныне фреймворки подобрались к естественному рубежу: отделение сайта от движка. Есть и достижение — первый российский (и мировой?) фреймворк Levitation с новой архитектурой.
Основная проблема нынешних фреймворков
Современные фреймворки основное внимание уделяют движку. Сайт для них является менее значимым потому, что с ним все более-менее понятно: html, css, js + шаблонизатор. А вот с движком не все было понятно, и основные усилия были направлены именно на движок. Причем на движок, который, естественно, управляет только одним сайтом.
В результате все популярные ныне фреймворки являются моно-сайтами, то есть их движок управляет одним сайтом. В их корневом дире всегда сидит `index.php` – это стартер их единственного сайта. Более того, многие компоненты сайта – конфиги, шаблоны, коды оказываются там же, где и компоненты движка. Результат такого сверх-внимания к движку – полное растворение сайта в движке!
Чтобы сделать бэкап, надо бэкапить все — не только сайт, но еще и движок! Чтобы сделать dev сайт — надо копировать все! А ведь все — это для сайта в 0.5-1 Mb еще и 50-100 Mb движка. Движок в сто раз больше полезной нагрузки!
Проблема с бэкапом сайта решалась легко – спец класс или утилита для бэкапа именно сайта.
А вот проблема `мультисайта`, которая во весь рост встала лет 10 назад, оказалась вообще говоря нерешаемой. Нерешаемой из-за того, что единственный сайт был напрочь растворен в движке, и чтобы вытащить его, надо было переписывать все! Однако переписать все – это уже не новая версия, а новый фреймворк. Компромисс нашелся в варианте ограниченного мультисайта, когда все мультисайты могли находиться только внутри некоторого спец-дира в движке. При этом основной сайт в корне фреймворка естественно остался – без него никак.
Ну и вишенка — у топовых фреймворков, с которыми я знаком (WP, Laravel, Symphony, Drupal, Yii2) вообще нет объекта (класса) Site! Как вам такое?
Фреймворк Levitation – сайт отделен от движка
Лет 5 назад появился фреймворк Grav. Он не входит в топ 20, и может даже в топ 50, но довольно продвинутый. В нем класса Site тоже нет, но зато есть шаг в верном направлении — конфиги движка и сайта разделены. Остался последний шаг — разделить коды движка и сайта.
Небольшая команда энтузиастов решилась на радикальную переделку Grav – переписать его с целью полностью отделить сайт от движка.
Это не было легкой прогулкой, но результат оказался впечатляющим:
сайт отдельно, движок отдельно,
любой сайт может обращаться к любому движку,
регулировать нагрузку на движок — без проблем,
dev сайты и движки — да сколько хочешь,
бэкап сайтов и движков — просто копируй/архивируй,
разграничить доступ разработчиков и техподдержки — один клик,
и вообще – один движок, много сайтов – это и есть мультисайт!
Назвали мы свой фреймворк оригинально: Lev или Levitation (Лев или Левитация). Это просто дань уважения к его предку Grav (Gravitation).
Достоинства LevСупер-скорость
По сравнению с другими фреймворками Lev отвечает на запрос не быстро, а мгновенно. И это связано не с тем, что архитектура и все сторонние компоненты Lev самые современные, нет. И даже не с тем, что система кэширования страниц – самая крутая (хотя это так и есть).
Супер-скорость связана с тем, что Lev не использует СУБД. Почему не использует? – Да потому, что нафиг просто не нужна! Об этом – ниже.
СУБД? – не нужна!
А зачем фреймворку СУБД? У фреймворка собственно только две основные функции. Первая – анализировать запрос браузера, вторая – формировать и возвращать ответ (html страницу). Спрашивается, а где здесь СУБД? А ее здесь нету. Есть файловая система и алгоритмы формирования страниц по запросу. Все.
Почему же тогда все топовые фреймворки не просто содержат СУБД, а еще и считают ее важнейшим своим компонентом? Да потому, что СУБД нужна для обработки больших данных. А большие данные могут появляться только в больших приложениях, типа магазинов, корпоративных сайтов, вики,… Ключевым здесь является слово `приложение` – СУБД нужна приложениям с большими данными.
А вот фреймворку для исполнения его базовых функций СУБД не просто не нужна – она противопоказана. Фреймворку нужна только файловая система сервера, которая однозначно быстрее любой СУБД.
Ультра-современные архитектура и компоненты
Lev – наследник Grav, а Grav – довольно свежий фреймворк, ему около 5 лет. Grav воспринял все достижения, наработанные своими предшественниками. Общая компоновка и все основные компоненты фреймфорков к моменту появления Grav были многократно отработаны. Grav собрал все самое лучшее.
А Lev просто добавил к этому последний архитектурный штрих — полностью отделил сайт от движка. Правда, для этого пришлось переписать ядро Grav.
Потоки вместо путей
Для управления файлами и директориями Lev использует систему управления потоками (streams), а не путями, как у большинства фреймворков.
Потоки гораздо удобнее, чем пути, потому, что позволяют определять не только собственно пути, но и дополнительные параметры типа `чтение-запись`, `только чтение`.
Но важнейшим достоинством потока является возможность определить его путь относительно другого потока. И даже относительно нескольких потоков. Собственно именно в последнем и кроется вся мощь управления потоками.
И вишенка — все основные операционки поддерживают не только пути, но и потоки.
Дружественный конфиг – yaml файлы
Дружественный конфиг – это правильная штука. Вот в каком плане. Любое приложение пользует две группы настроек – внутренние и внешние. Внутренние настройки определяют режимы функционирования компонентов приложения и сидят либо в конфигах, либо вообще где-то в коде.
А вот внешние настройки определяют режимы взаимодействия с внешним миром. И их лучше выносить из кода. Еще лучше отделять их от внутренних настроек. А еще лучше их декларировать не на языке программирования, а как-то более дружественно. Отличный выбор – `yaml` формат. Он легко понятен даже юзеру. Правда, прогеры не всегда с ним дружат за его фривольность, но это их проблемы. Тем более, что внешние настройки – вообще не их забота.
Компактность – ничего лишнего
Времена, когда во фреймворк пихали все, что типа может понадобиться – эти времена прошли. Индустрия развилась, специализация рулит. Фреймворк должен содержать только нужные ему самому компоненты – и ничего больше. Всякие дополнительные фичи (типа СУБД), нужные конкретному приложению, оно может подключить само. Точка.
Так вот, Lev не просто компактен – он сверх-компактен. Дистрибутив весит ~20 Mb. Из которых более половины – вендоры. Это без админки. А с админкой – еще ~20 Mb.
Разделение сайта и движка
Главной фишкой Lev является полное разделение сайта и движка. Сайт Lev сидит в своей собственной директории. Сидит весь, со всеми своими потрохами. То же относится и к движку Lev.
Понятно, что сайт и движок – это разные сущности. Сайт определяет свои роуты, конфиги, страницы и бизнес-логику приложения. Тогда как движок определяет логику взаимодействия с сайтом и логику обработки запроса браузера.
Взаимодействие сайт-движок такое:
Сайт получает запрос браузера и передает его на обработку движку.
Движок анализирует запрос браузера и формирует html страницу ответа, обращаясь к настройкам, шаблонам страниц и бизнес-логике приложения вызвавшего его сайта.
Движок возвращает сформированную страницу браузеру.
Мультисайт – полный и неограниченный
Благодаря разделению сайта и движка Lev поддерживает неограниченный мультисайт: один движок – много сайтов.
Такая архитектура имеет множество выгод.
Самой очевидной выгодой является бэкап – просто делаешь копию или архив директории сайта, и никаких проблем.
Другая выгода касается разработки и саппорта. Разделение движка и сайта автоматом приводит к разделению специализаций. Разработчики и саппортеры естественным образом делится на две разных группы по интересам – разработка и саппорт собственно сайта, и разработка и саппорт движка. И, что совсем хорошо, рабочие площадки группы сайта и группы движка не пересекаются — у каждой своя директория!
Ничто не мешает иметь не один движок, а сколько угодно, исходя из нагруженности, безопасности, бизнес-значимости, разработки/сопровождения и т.д. При этом все движки будут абсолютно одинаковы (в рамках одной версии).
Ничто не мешает выделить свой собственный движок для особо значимого сайта, или иметь тучу низко-нагруженных сайтов на один движок.
Ничто не мешает разместить движок на другом сервере для особо затратных или специфических запросов, скажем поиски, бэкапы, отчеты, … и тем самым освободить основной движок от таких запросов.
В общем, никаких ограничений для любой архитектуры пар сайт-движок!
Это как в автомобилестроении 100 лет назад, когда двигатель отделился от авто, а индустрия моторостроения – от автостроения.
Lev отделил сайт от движка – и это правильно!
Проект Levitation
Приветствую каждого, кто добрался сюда!
Проект Levitation еще совсем молод, но он уже передовой и он чисто российский!
У проекта амбициозные планы по дальнейшему совершенствованию. Главным направлением видится глубокая декомпозиция движка для уменьшения связности компонент и улучшения скоростных характеристик. Это потребует значительных усилий и ресурсов.
Если Вы желаете поддержать Levitation любым образом, включая спонсорство или участие в разработке, вот контакты:
Сергей Гусев, [email protected]
https://github.com/getlev/lev
UI редактора блок-схем / Хабр | Веб-студия Nat.od.ua
UI редактора блок-схем / Хабр
Dgrm.net
Придумывать интерфейс интересно. Похоже на головоломку. Вот что получается для Dgrm.net.
Dgrm.net это редактор блок-схем
работает на пк, планшетах и телефонах;
нет лишних кнопок;
быстрый;
бесплатный.
Редактор открывает схемы из картинокРис 1. Dgrm.net открывает картинки схем
Не нужно хранить исходники, картинка и есть исходник.
Например: посылаем схему по почте. Через месяц письмо возвращается – сразу правим картинку из письма, не ищем исходники.
Соединительные линии вытягиваем, а не добавляем как отдельную фигуруРис 2. Для соединения фигур вытягиваем стрелкиТочки входа подсвечиваются заранее при приближении к фигуре
На рисунке 3 показаны скрытые контуры.
Рис 3. Точки входа подсвечиваются заранее при приближении к фигуреФигуры автоматически подстраиваются под длину текста
Не нужно вручную менять размер.
Фигуры увеличиваются не плавно, а шагами. Чтобы на схеме не рябило от разных размеров.
Рис 4. Фигуры автоматически меняют размер в зависимости от текстаМинимум элементов управления
Возможности редактора сознательно ограничены.
Большие элементы управления
На телефонах элементы управления становятся еще больше.
Рис 5. Большие элементы управления на телефонахБлижайшие планы
Групповое перетаскивание фигур. Сейчас можно только одну фигуру перетащить.
Изменение цвета фигур.
Приближать/удалить схему.
Короткие ссылки на диаграммы.
Диалог “Сохранить как”. Сейчас сохраняет в “Загрузки” без возможности указать имя файла.
Копирование схемы из редактора в Word.
Перетаскивание схемы из редактора в Word.
Dgrm.net | GitHub (исходный код)
13 лучших игр с открытым кодом на Gamedev.js Jam 2022 / Хабр | Веб-студия Nat.od.ua
13 лучших игр с открытым кодом на Gamedev.js Jam 2022 / Хабр
В 2022 году в сообществе Gamedev.js прозвучал призыв делиться исходниками игр на GitHub. Подборку игр с открытым кодом представляем к старту курса по Fullstack-разработке на Python. Автор этого материала — основатель Enclave Games и конкурса js13kGames.
Возможно, вы уже слышали о конкурсе js13kGames, который начал историю в 2012 году. Помимо увлекательной задачи разместить ресурсы игры в zip-архиве на 13 килобайт, ещё одно требование — представить исходники в удобочитаемой форме на GitHub.
Сообщество Gamedev.js также зародилось примерно в 2012 году, и со временем сосредоточилось на местных встречах и хакатонах, а еженедельный информационный бюллетень Gamedev.js публикуется с 2014 года. Призыв делиться исходниками прозвучал в 2022.
И на него ответили. Открыт исходный код 27 из 95 игр. Ниже вы найдёте 13 лучших по общим результатам работ. Тема этого года звучала как «RAW» (сырой):
1. Поиски Аарона IV: Пока Моисея не было (Aaron’s Quest IV: While Moses Was Away)
Рейтинги: #2 в общем зачёте, #2 — в номинации «Игровой процесс», #2 — в «Инновациях», #7 — в «Аудио».
Joep van Duinen: Игра кажется действительно стоящей. Много чего можно добавлять в неё, например, новые улучшения, карты/режимы (испытания на время для получения определённых предметов), возможно, здесь есть разные рабочие или улучшения для них, которые по мере прохождения игры делают их сильнее. Сделана по-настоящему простая игра, но она прекрасно работает, поздравляю! С интересом буду следить за её будущим.
2. Суши-мания (Sushi mania)
Рейтинги: #9 в общем зачёте, #4 в номинации «Тема», #8 в номинации «Игровой процесс», и #8 — в «Графике».
Raptor9999: Увлекательный игровой цикл! Все неплохо сбалансировано, и управление работает очень даже хорошо. Я сам удивился, насколько хорошо смог нарезать нужные продукты, даже когда лента двигалась так быстро!
3. Оно не готово! (IT’S TOO RAW!)
Рейтинги: #12 место в общем зачёте, #1 в номинации «Тема», #2 в номинации «Децентрализация», и #3 в «Веб-монетизации».
Omhet: Эта игра рассмешила меня! Крайне инновационный подход к казуальному жанру. Думаю, Гордону это понравилось бы.
4. Режим .raw (.raw mode)
Рейтинги: #14 в общем зачёте, #1 в номинации «Инновации» и #12 в номинации «Игровой процесс».
Johnonym: Эта игра имеет интересную и уникальную механику, которую определённо хочется изучать дальше. Возможность поменять местами любой бит упростила игру.
5. Пещеры голема (Golem Caves)
Рейтинги: #17 в общем зачёте, #3 — в номинации »Децентрализация» и #9 в номинации «Игровой процесс».
Photonstorm: Очень весело! Хотя мне бы хотелось, чтобы кирка работала намного быстрее, очень долго прорубать себе путь. Зато после очень прикольно собирать сокровища!
6. Доработка (UNRAWIFY)
Рейтинги: #18 в общем зачёте, #3 в номинации «Инновации», #6 в номинации «Веб-монетизация», и #12 в номинации «Тема».
J.C. Games: Мне нравится, что фичи добавляются по ходу игры!
7. Супер-простой симулятор салата (Super Simple Salad Simulator)fig:
Рейтинги: #24 место в общем зачёте, #6 в номинации «Тема» и #14 в номинации «Инновации».
Makritzaa: Мне понравилось! Получилось очень круто!
8. Чез RAW (Chez RAW)fig:
Рейтинги: #26 место в общем зачёте, #8 в номинации «Тема».
Ardiam Games: Весёлая и экстравагантная небольшая игра! И спрайты очень милые. Правда, тяжело было убивать поросят. Отличная работа!
9. Суши Dou (Sushi Dou)
Рейтинги: #28 место в общем зачёте, #3 в номинации «Децентрализация»
Melky Pop: Какая милая игра! Я не понимал, как подавать тарелки, пока не прочитал инструкцию, думаю, что инструкции не помешали бы в самой игре. Игра начинается сумбурно и сложно, а клиенты в ней просто не хотят ждать!
10. Играй рок и забудь (Rock to forget)fig:
Рейтинги: #30 место в общем зачёте, #2 в «Аудио».
Caiofov: Хорошая игра! Тот факт, что в игре вы делаете кавер на песню, делает ее ещё лучше. Мне она показалась довольно трудной. Я хочу продолжать играть! Надеюсь на обновления в будущем!
11. Беги (RunAWay)fig:
Рейтинги: #33 в общем зачёте, #13 в «Графике».
Heru: Мне понравился арт и анимация на стартовом экране. Хорошая работа.
12. R.A.W.-бол (R.A.W. Ball)
Рейтинги: #36 в общем зачёте, #7 в номинации «Децентрализация», #8 в «Веб-монетизации», #9 в номинации «Аудио», и #13 в номинации «Графика».
BuyMyBeard: Мне понравилась визуальная составляющая игры, интро и главная тема.
13. Веб-шутер Raw Ascii (RAWS: a Raw Ascii Web Shooter)
Рейтинги: #41 место в общем зачёте.
Dashing Strike: Это действительно крутая игра! Играл довольно много раз, удалось набрать 4600 очков. И… увидел комментарий о том, что кто-то прошёл игру полностью, так что пришлось снова играть, пока и я этого не сделал. Мне очень нравится ASCII-графика, хотя она определённо не похожа на эмулятор терминала. Здорово получилось создать настроение. Звук тоже хорош!
Это всё! Не забудьте проверить всю коллекцию на itch.io, если хотите увидеть другие игры. Мы надеемся, что на Gamedev.js Jam 2023 будет ещё больше игр с выложенным на GitHub исходным кодом. Не забудьте присоединиться к itch.io, чтобы не пропустить мероприятие!
Хотите стать частью сообщества? Подписывайтесь на @Gamedevjs в Twitter и присоединяйтесь к нашему серверу в Discord. А мы поможем прокачать ваши навыки или с самого начала освоить профессию, востребованную в любое время:
Выбрать другую востребованную профессию.
Оптимизация загрузки js бандла использующего icon pack’и / Хабр | Веб-студия Nat.od.ua
Оптимизация загрузки js бандла использующего icon pack’и / Хабр
Иконки в проекте часто становятся причиной проблем разбухания размера бандла. Все из-за того что svg-иконки могут быть достаточно объемными.
Если мы загружаем только те иконки, что мы реально используем то это не самый плохой вариант. Все становится намного хуже когда мы устанавливаем готовые пакеты иконок, но используем только их малую часть, так произошло и со мной.
На скриншоте видно, что это приложение, состоящее из 2х элементов, весит 722kb. Но почему?
Исходные данные
Давайте посмотрим на код, в котором и находится проблема.
Вроде все просто. У иконки по пропсу name мы понимаем, какую именно иконку из пака нам нужно достать. Но бандл слишком много весит, тут же только одна иконка, почему так? Давайте посмотрим, что происходит внутри компонента иконки.
./components/Icon
Тут видно, что виной раздувания бандла является fontawesome и его наборы пакетов: free-regular-svg-icons, free-brands-svg-icons, free-solid-svg-icons, и т.д.
Мы импортируем сразу все иконки из всех наших пакетов, что и является основной проблемой.
Теперь взглянем на результаты анализа бандла.
602 kb сжатых gzip данных мы заставляем грузить наших пользователей только для того, чтобы показать им одну иконку! С этим точно нужно что-то сделать.
Сразу оговорюсь, вы можете сказать, что можно было бы загружать только нужные нам иконки через прямые импорты, а потом прогнать из через svg-sprite. Но тогда это привело бы к значительной переработке имеющихся проектов, что было бы крайне нежелательно.
Мне хотелось бы сохранить интерфейс взаимодействия с компонентом Icon и не заставлять разработчиков каждый раз добавлять новые иконки в проект и писать какой либо дополнительный код. То есть все должно остаться как есть, и при этом наша проблема должна быть решена.
Решение
Для сохранения обратной совместимости внешний интерфейс работы с компонентом Icon не должен меняться. И должна остаться возможность использовать любые иконки из установленных пакетов, а также кастомные иконки. Для достижения этих целей будем использовать динамические импорты. Для каждой иконки из наших пакетов нужно создать отдельную строку в специальных map-файлах.
Благодаря этим файлам наш бандлер поймет что нужно будет создать отдельный чанк под каждую иконку. Тогда мы сможем скачивать их по требованию.
В рабочем проекте были куплены расширенные пакеты fontawesome, кол-во иконок в них было примерно 7-8т шт. Писать мапы для такой кучи иконок однозначно задача не одного дня.
Поэтому был написан скрипт который сделает всю рутинную работы за нас.
Результат работы скрипта iconPackMapsGenerator
Внутри конфиг для его работы.
name: название генерируемого файл;
lib: путь до папки с файлами иконок;
prefix: префикс для названия иконки. Заменяет префикс fa.
Для кастомных иконок создаем отдельную папку, где каждый файл описан следующим образом:
И переделываем наш компонент Icon не трогая его интерфейс.
components/Icon.tsx
Вроде все. Что же у нас получилось в итоге?
Давайте вновь посмотрим на бандл.
Как видно, каждая наша иконка помещена в отдельный чанк, и также можно заметить, что размер бандла значительно увеличился. Было 600kb стало 2.01 Mb. Почему так?
Бандлер для создания чанка оборачивает его в специальный код который, как оказалось, весит больше чем многие наши svg.
При ближайшем рассмотрении чанка с компонентом Icon видно что, больше всего места занимают мапы иконок. Но нам нужны эти файлы так как иначе бандлер не поймет что нам нужно создать отдельный чанк под всевозможные иконки. И имея мапу можем создавать ts-типы для названий всех иконок.
А что же происходит теперь в браузере?
Теперь при загрузке страницы мы видим, что последний чанк размером 1.1kb это наша иконка.
При первой загрузки в начальном варианте мы загружали 722kb, а сейчас 89kb! Уже победа. Помимо этого мы получили:
Сохранение обратной совместимости с исходным проектом;
Динамическая загрузка иконок по требованию;
Возможность добавлять кастомные иконки
Заключение
Надеюсь эта статья вам поможет с оптимизацией ваших бандлов и сэкономит вам время и силы. Исходных код используемого тестового проекта вы можете найти по ссылке.
Также если вам интересно в своем Telegram я время от времени выкладываю интересные находки по фронтенду. И всем легких бандлов.
Фронтенд-новости №11. JQuery живее всех живых, замена CAPTCHA, вариативные шрифты в Figma | Веб-студия Nat.od.ua
Фронтенд-новости №11. JQuery живее всех живых, замена CAPTCHA, вариативные шрифты в Figma
Дайджест новостей и полезных статей из мира фронтенд-разработки за неделю 13–19 июня.
Доступность
Аспекты доступности – семантика, контратность и… тревога?
Спецификации
Замените CAPTCHA на Private Access Tokens. Cloudflare уже начинает тестирование
HTML
Несколько способов добавить пробел в размерку
Разбираемся с нативными веб-компонентами
CSS
10 трюков, которые должен знать каждый веб-разработчик
Руководство по высококонтрастному режиму в Windows
JavaScript
Сравнение простых примеров кода между React, Vue, Angular, Vue, Ember, Lit
AbortController для отмены синхронных задач
Исследователи: мы изучили 1 000 000 сайтов и видим, что jQuery самый популярный, а вы говорите, что не используете его.
React
Масштабируемая архитектура для создания React-приложений
Энциклопедия компонентов из более 5000 UI-элементов
Как я создал приложение для фокусировки с помощью React и Rust
Подробно про элементы, компоненты и экземпляры в React
История о том, как уменьшить количество ошибок в кодовой базе
Как поддерживать внутреннюю библиотеку компонентов
Node.js
Локальная разработка NestJS и Postgress с помощью Docker Compose.
Node.js 16 прекратит развитие в сентябре 2023. Пора переходить на node.js 18
Angular и Vue
Жду вас в комментариях с ссылкой на ресурсы по Angular и Vue. Спасибо
Инструменты
В Figma появились вариативные шрифты
Генератор CSS для теней с градиентами
Трассировка зависимостей node.js
Браузеры
История веб-браузеров за 28 лет
Firefox внедряет Total Cookie Protection по умолчанию
Общее
Шрифт Atkinson Hyperlegible разработанный специально для повышения разборчивости для людей с плохим зрением.
Исследование о том как шрифты могут вызывать эмоциональную реакцию.
Эдди Османи делиться софт скилами для разработки ПО.
P.S. Всю неделю писали и шутили о том, что IE всё, а я, пожалуй, продолжу выпуск дайджеста.
Как читать статьи на английском языке
В дайджесте много статей и видео на английском языке, чтобы это не стало препятствием: в Google Chrome есть функция перевода страницы с любого популярного языка, а видео можно перевести в Яндекс Браузере.