Портрет 4X_Pro
Онлайн
Мультиблог
4X_Pro
Записки лишнего человека

Компьютерное

Асинхронная загрузка CSS

4X_Pro
В Интернете есть примеры асинхронной загрузки CSS через setTimeout или манипуляции с media, но есть более красивое и современное решение — через rel=preload. Выглядит оно так:
<link type="text/css" href="style.css" rel="preload" as="style" onload="this.rel='stylesheet'" /> <noscript> <link type="text/css" href="style.css" rel="stylesheet" /> </noscript>
Однако следует помнить, что если вы асинхронно загружаете основной CSS без выноса его критической части в тег style непосредственно в HTML, то получается довольно неприятный эффект — сначала страница отображается без стилей вообще, потом тут же перерисовывается заново. Поэтому такую асинхронную загрузку лучше применять только к вспомогательным CSS.

CondiLoader — условная асинхронная загрузка скриптов и CSS

4X_Pro
Я уже не раз писал в этом блоге о приемах для ускорения отображения сайтов. Это и отложенная асинхронная загрузка, и условная загрузка по имени класса, и запуск inline JavaScript-кода после загрузки внешнего файла по событию.
Теперь же я сделал библиотеку-загрузчик, которая упрощает и автоматизирует их применение, а также позволяет собрать список всех используемых на сайте библиотек в одном месте. Называется она CondiLoader, скачать ее можно на GitHub или же установить через npm:
npm install condiloader
Работает CondiLoader следующим образом: вы передаете скрипту список объектов для загрузки, он дожидается события DOMContentLoaded. После этого для каждого объекта проверяет, необходимо ли загружать его для данной страницы. Если да, приступает к загрузке, после чего вызывает функцию инициализации, либо пользовательское событие с указанным именем. Все объекты загружаются параллельно, и ошибка при загрузке одного из них на остальные не влияет. Читать далее…

Почему могут пропадать сессии в PHP при большой нагрузке

4X_Pro
Недавно столкнулся с вопросом, почему пропадают PHP-сессии при высокой нагрузке. Как известно, что по умолчанию сессии PHP хранятся в обычных текстовых файлах. В Debian/Ubuntu эти файлы располагаются в /var/lib/php/sessions/, в других дистрибутивах путь может отличаться. Сами файлы по размеру невелики, но если сессия открывается при каждом обращении к сайту, то когда на сайт заходит поисковый робот, таких файлов может создаваться весьма большое количество. Как этого избежать, я описывал в одном из предыдущих сообщений.
Теперь же рассмотрим ситуацию, когда сессию создавать действительно надо, но она не создается. Вероятная причина подобного — нехватка свободных inodes. Inodes — это записи в файловой системе, используемые для описания, где находится файл, и для каждой сессии PHP требуется как минимум один свободный inode. Если они заканчиваются, то создавать файлы становится невозможно, даже если на диске еще много свободного места. Количество inodes ограничено либо настройками файловой системы (на выделенных серверах и VDS под Xen), либо тарифным планом (на shared-хостинге и VDS под OpenVZ). Кроме того, на shared-хостингах обычно также существуют лимиты на количество файлов, не связанные с inode.
Проверить количество свободных inodes можно с помощью команды
df -i
 в командной строке, а посмотреть лимит на создание файлов — в панели управления хостингом. Для нормальной работы необходимо, чтобы запас и того, и другого составлял хотя бы десять тысяч.
Если стало ясно, что проблема не в inodes, проверьте, что в php.ini корректно выставлены параметры session.gc_maxlifetime, session.gc_probability и session.gc_divisor. И что ни в одном из скриптов, выполняемых на сервере они не меняются через функцию ini_set. Также имеет смысл заглянуть в crontab (на shared-хостинге он может называться «планировщик заданий»), и проверить, что там нет никаких скриптов, которые могли бы очищать каталог с сессиями.

Каким должен быть идеальный сайт?

4X_Pro
Некоторое время назад на SbUp.Com наткнулся на тему «каким должен быть идеальный сайт» с технической точки зрения, и решил изложить свою точку зрения по этому вопросу. На мой взгляд, идеальным сайтом можно назвать тот, который максимально похож на статику. Для некоторых типов сайтов (блог и простой магазин) лучше вообще генерировать в админке статические страницы с основными данными, например, текстом сообщения или карточкой товара, а часто меняющиеся второстепенные данные — содержимое корзины, список последних постов — подргружать через AJAX. (Я такой подход называю StaJAX, от static+AJAX, но, к сожалению, он не так распространен, как хотелось бы.)
Кроме этого, идеальный сайт должен обладать такими признаками:
  • Быть сверстан вручную, без всяких bootstrap и тому подобного, с минимально возможным количеством тегов и короткими именами css-классов.
  • 100%-валидный HTML и CSS.
  • Полностью асинхронная загрузка JavaScript после события DOMready.
  • Полная оптимизация всех картинок, настройка сжатия GZIP для HTML, JS, CSS и их минификация.
  • Использование разметки хлебных крошек — тоже обязательно.
  • Короткие и заданные вручную HURL, желательно, на английском, а не транслитом (то есть адреса вида /first-post.htm вместо /eto-pervaya-zapis-v-bloge.htm) и уж точно никакой кириллицы (исключением могут быть только словари и wiki-проекты).
  • Иметь правильную иерархию URL, то есть адреса вида /название-категории/имя-товара.htm вместо /categories/название-категории.htm и /products/имя-товара.htm.
В общем, у идеального сайта скорость загрузки и экономия траффика должны быть на первом месте (после самого контента, конечно). Ещё полное отсутствие всплывающих блоков, которые закрывали бы контент (типа «закажите обратный звонок» или «подпишитесь на нас в социальных сетях»). И небольшой субъективный момент: не должно быть «обрезанных» URL без / или .html на конце. Выглядит просто отвратительно!

Как добавить на свой сайт прием оплаты через Google Pay

4X_Pro
Вчера узнал, что Goolge Pay теперь можно использовать не только в приложениях, но и на Web-сайтах, и решил разобраться, как это делать. Как выяснилось, с технической точки зрения там все достаточно просто. Подключение состоит из трех этапов:
  1. выбрать платежный шлюз — либо один из тех, которые сотрудничают с Google, либо какой-то сторонний, и получить от него merchantID, и, возможно, другие параметры для подключения. В случае проведения оплат через сторонние шлюзы также потребуется их публичный ключ.
  2. добавить на страницу оплаты контейнер для кнопки оплаты и необходимые скрипты, и проверить работу Google Pay в тестовом режиме,
  3. подать заявку в Google на проверку и подключение сайта. После ее прохождения поменять в скриптах некоторые настройки с тестовых на рабочие.
Рассмотрим подробнее второй этап. Читать далее…

Загрузка файла на Яндекс.Диск из командной строки

4X_Pro

Недавно я уже давал несколько рекомендаций, как делать резервное копирование баз данных. К этому хотелось бы добавить совет не хранить backup на том же сервере, что и основные данные. Но как быть, если сервер всего один? На помощь могут прийти облачные хранилища, которые работают по протоколу WebDAV, например Яндекс.Диск. Загрузить туда файл можно обычным HTTP-запросом с помощью утилиты curl из командной строки или bash-скрипта. Делается это так:

curl -T локальный_файл https://webdav.yandex.ru/удаленный_файл --user логин:пароль

При необходимости у имени удаленного файла можно указать и путь, например, Backups/daily.gz, но тогда все каталоги в пути должны уже существовать на сервере.

Как преобразовать дамп базы данных в другую СУБД

4X_Pro

Занимаясь разработкой форумного движка Intellect Board, я столкнулся с двумя задачами:

  • нужно отслеживать изменения в структуре БД для выпуска обновлений
  • преобразовывать скрипт с SQL-операторами создания таблиц для MySQL в SQL для Postgres, SQLite, и, возможно, других СУБД.

И то, и другое — задачи весьма рутинные, и хотелось бы их автоматизировать. Довольно долго я искал решения для этого, но попалась только утилита mysqldiff (весьма неудобная и с множеством ограничений) и ряд платных программ, использование которых для меня неприемлемо.

Недавно я нашел модуль для Perl и набор готовых утилит к нему, который помог мне решить эти задачи. Модуль называется SQL::Translator. Читать далее…

Плавная прокрутка до нужного элемента

4X_Pro
На многих сайтах для плавной прокрутки страницы к нужному элементу средствами jQuery рекомендуют использовать примерно такой код:
jQuery('body').animate({
       scrollTop: jQuery("#myTab").offset().top
   }, 1000); // myTab — это элемент до которого нужно прокрутить
Но недавно обнаружил, что такой код перестал работать на одном из сайтов. По всей видимости, причиной этого было свойство height или min-height, прописанное для body. Стал искать, как это исправить, и выяснил, что в качестве селектора нужно указывать и body, и html через запятую: jQuery('html,body').animate({. После этого прокрутка начинает работать нормально.

Два бота для Telegram

4X_Pro
Сегодня запустил двух собственных ботов для Telegram.
https://telegram.me/SiteKnockerBot — мониторинг состояния сайта. Отслеживает доступность сайта, наличие на странице заданных ключевых слов, время ответа сервера, и сообщает о возникновении проблем. Также умеет предупреждать о подозрительных ситуациях (выдается почти пустая страница, присутствуют слова, характерные для дефейса или сообщения об ошибках PHP).
Из соображений безопасности число сайтов на мониторинге ограничено: до 1 сентября 2017 года можно добавить 10 сайтов для одного пользователя, после — 5.
https://telegram.me/TypograferBot — типографирование текста. Расставляет правильные кавычки, тире, многоточия, пробелы вокруг знаков препинания, простейшие дроби, обозначения типа см2, м2 и т.п., а также знаки дюйма, градусы по Цельсию и Фаренгейту. За основу взят типографер из моей давней разработки — TextCMS.

Асинхронная загрузка при наличии inline JavaScript

4X_Pro

Часто при ускорении загрузки сайта не получается сделать асинхронной загрузку тяжелых библиотек вроде jQuery из-за того, что зависимый от них код вставлен прямо в HTML-страницу с помощью тега script (так называемый inline JavaScript), а вынести его в отдельный файл и использовать HeadJS по каким-либо причинам нет возможности. Чаще всего такое встречается, когда JavaScript генерируется CMS. Но недавно я узнал, как можно сделать загрузку асинхронной и в этом случае: через пользовательские события (custom events). Делается это так: существующий inline-код оборачиваем функцией-обработчиком события с выбранным нами именем, например jQeuryLoaded:

Читать далее…

Страницы:
Задать вопрос

Здесь можно задать мне вопрос или спросить совета по любой теме, затронутой в блогах или на форуме. После того, как я отвечу, вопрос и ответ появятся в соответствующем разделе. Но не забываем, что я — сторонник slow life, поэтому каких-либо сроков ответов не обещаю. Самые интересные вопросы станут основой для новых тем на форуме или записей в блоге.
Сразу предупреждаю: глупости, провокации, троллинг и тому подобное летит прямо в /dev/null.