▤ Руководства

Первый анализ сайта (версия 107)

Содержание

Человек вводит домен и быстро получает понятный результат; тяжёлые проверки досчитываются позже.

Что происходит после ввода адреса

  1. Проверка адреса. Браузер сразу сообщает о понятных ошибках: пробелы, IP-адрес вместо домена, адрес почты, нет зоны. Ссылка вида https://www.example.com/page?x=1 превращается в www.example.com. На сервере те же правила (FirstRun\Hints::inputProblem).
  2. Страница ожидания (/job/{id}). Показывает этапы проверки и ход выполнения. Как только загружена главная, появляется карточка «Первые данные» (ответ сайта, HTTPS, скорость ответа, сервер, CMS и технологии, название страницы). После основных проверок — «Предварительные итоги» (ранг, счётчики, три главные проблемы). Если сайт уже проверяли, показан прошлый результат со ссылкой.
  3. Отчёт открывается после основных проверок, обычно через 3–8 секунд, не дожидаясь WHOIS, веб-архива и сетевых запросов к почте и ссылкам.
  4. Отложенные проверки. Возраст и регистрация домена, история в веб-архиве, SPF/DMARC/BIMI и битые ссылки главной выполняются отдельной задачей analyze_more. В отчёте это отдельная плашка с ходом выполнения, ранг помечен «предварительно». Когда задача закончилась, страница обновляется сама.

Как устроено

  • Analyzer::run() с defer = true собирает главную, DNS, robots.txt, sitemap и запускает этапы checkMain, checkMore, checkPage; запросы к RDAP и веб-архиву, почтовые DNS-записи и проверка ссылок пропускаются. Отчёт получает phase = partial и список pending.
  • Всё, что нужно для продолжения (элементы проверок, флаги ранга, ссылки главной), сжимается и кладётся в таблицу analysis_pack — по одной строке на сайт, срок жизни 6 часов. Повторная загрузка главной не нужна.
  • Analyzer::resume() выполняет collectSlow() и этап checkSlow, пересчитывает ранг и заменяет предварительный отчёт полным в той же строке истории (Store::reportReplace). Итог совпадает с итогом обычной полной проверки (это проверяется тестом).
  • Очередь: задача analyze_more всегда уступает новым проверкам других сайтов (jobClaim).
  • Если фонового обработчика нет (проверка идёт прямо в запросе), отсрочки нет — проверка выполняется целиком. Отключить отсрочку совсем: 'deferred_analysis' => false в config.php.
  • API, пакетные проверки, мониторинг и расписания работают как раньше: полная проверка с defer = false.

Первые данные

Обработчик Analyzer::$onPreview получает два среза: head (после загрузки главной) и checks (после основных проверок). Они пишутся в jobs.preview и отдаются страницей /job/{id}.json. Сбой обработчика проверку не ломает.

Ошибки и повторный анализ

  • Сайт не открылся. Отчёт сохраняется, а наверху — причина (DNS, SSL, таймаут, отказ, обрыв, закрытая сеть) со списком советов, кнопкой «Повторить проверку» и ссылкой на соседний адрес (с www и без).
  • Сбой задачи. Страница объясняет причину по тексту ошибки, предлагает повторить и показывает последний успешный результат.
  • Задача «зависла». Если задача ждёт обработчика больше 45 секунд или выполняется дольше двух минут, появляется сообщение с кнопкой «Запустить заново». Нет связи с сервером — сказано прямо.
  • Повторная проверка. Прошлый результат остаётся доступным, пока идёт новая проверка. Кнопка «Проверить» не остаётся заблокированной, если вернуться кнопкой «Назад».
  • Потерянная догонка. Если задача analyze_more пропала, страница состояния ставит её заново; если пакет уже удалён — плашка предлагает «Перепроверить».

Уточнения проверок (v132)

  • BIMI: кроме наличия записи default._bimi проверяется сам логотип (по l=: https, SVG Tiny PS с baseProfile="tiny-ps" и version="1.2", квадрат, до 32 КБ, без скриптов, анимации и внешних ссылок) и сертификат VMC (по a=: читается, действует, не истекает в ближайшие 30 дней). Принадлежность сертификата доверенному центру и показ логотипа в почтовых клиентах не проверяются. Вес в ранг по-прежнему нулевой. Код — src/Mail/Bimi.php.
  • Keep-Alive: заголовки подтверждаются опытом — два запроса HEAD подряд на одном соединении (Http::reuseProbe); если второй пошёл по новому соединению, в отчёте сервера появляется предупреждение. Для HTTP/2 и HTTP/3 опыт не нужен.
  • Изображения: к расчёту WebP добавлен расчёт AVIF (качество 55) на самых тяжёлых файлах. Перекодирование идёт через пайплайн src/Image/Pipeline.php: Imagick, GD или утилита ImageMagick (magick/convert) — первый доступный; есть пакетный режим (до 20 файлов и 40 МБ, результат не хуже исходника). Если ни один движок не умеет писать AVIF, строка просто не выводится.
  • Код главной и внешние ссылки: при редиректах в строке кода указан итоговый адрес и число переходов; в строке «Ссылки на главной» — сколько внешних ссылок помечено nofollow/sponsored/ugc и к каким сайтам их больше всего.
  • Проверки-классы: в src/Analyzer/Checks/ перенесены ещё одиннадцать — registry, spa_shell, title, description, h1, og, viewport, alt, text, links_home, schema; значение, нужное следующим этапам (найденный в реестре домен), проверка передаёт через CheckContext::export().

Добор строк ниже 90% (v133)

  • Дубли по регистру адреса: проверка url_case_probe берёт внутреннюю ссылку главной и запрашивает её в обычном и в верхнем регистре пути; если обе отдают одну страницу с кодом 200 и canonical не указывает на основной адрес, в отчёте предупреждение (вес в ранг нулевой). Полный обход сайта находит такие дубли глубже (url_case).
  • Проверка портов: у открытых портов показан ответ службы — приветствие SSH/SMTP/FTP/POP3/IMAP и у TLS-портов владелец и срок сертификата. Сканируются по-прежнему только порты из короткого списка, не больше шести за раз, и только публичные адреса.
  • Ответы для роботов и HEAD запрашиваются одной параллельной пачкой (одна задержка вместо двух).
  • Единая цветовая семантика: хорошо — зелёный, предупреждение — жёлтый, ошибка — красный, нет данных — серый (.tag-n, .st-na, .c-na, в обеих темах). Функция status_class() в views/_helpers.php переводит статус в класс.
  • Посещаемость в отчёте: владелец сайта видит в отчёте сводку из подключённых источников и загруженных CSV — визиты, визиты из поиска и посетители за 7 суток против предыдущих 7. Чужим людям и публичным ссылкам она не показывается.
  • Шаблоны: файлы views/ не обращаются к хранилищу; данные каркаса страницы готовит src/View/Shell.php, остальное передают маршруты. Это проверяет тест.
  • HEIC → JPG: если ImageMagick собран без декодера HEVC (libde265), инструмент теперь объясняет это и подсказывает, что поставить или как отключить HEIC на телефоне; в tests/fixtures/sample.heic лежит настоящий файл для проверки.

Добор строк ниже 95% (v134)

  • Анализ текста (инструмент «Анализ текста», API/MCP/CLI): кроме частот слов — частоты по основе (формы «окна/окно/окон» считаются вместе), повторяющиеся фразы из двух и трёх слов, число строк и цифр, средняя и наибольшая длина предложения, разнообразие лексики, слова, встреченные один раз, доли кириллицы и латиницы.
  • Предпросмотр сниппета: добавлен вид для телефона — заголовок до двух строк по ~328 px (шрифт 18 px), описание до трёх строк; вторая картинка snippet-mobile.png и строки «На телефоне» в числах. Это приближение: поисковики сами выбирают, что показать.
  • Разбор сертификата принимает PEM, цепочку из нескольких блоков и DER в base64. Показывает срок жизни, назначение ключа, OCSP/CRL, политики, наличие SCT; предупреждает о слабой подписи (MD5/SHA-1), коротком RSA-ключе, сроке больше 398 дней, отсутствии SAN и разрыве цепочки.
  • HTML: форматирование и сжатие (новый инструмент htmlfmt, src/Tools/Kit/HtmlTools.php): отступы по вложенности, сжатие без потери смысла (комментарии, пробелы между тегами; script, style, pre, textarea не меняются), сводка по тегам, список незакрытых и лишних закрывающих тегов. Строгая проверка валидности — отдельный инструмент «Проверка HTML».
  • Alt-Svc разбирается по RFC 7838 (ServerCheck::altSvc): протоколы h3/h3-29, время жизни ma, persist, clear, предложение другого хоста. Короткий ma и clear попадают в отчёт сервера. Сам протокол QUIC проверяет инструмент HTTP/3 (живой запрос).
  • Доступность: добавлены кнопки-картинки без alt, группы переключателей без fieldset/legend, несколько одинаковых областей nav/aside без названий, ссылки-пустышки (href="#", javascript:), автофокус, accesskey, ссылки в новой вкладке без предупреждения. Это статический разбор исходного HTML; ручная проверка по WCAG им не заменяется.
  • Согласие на cookie (Privacy::consent): название платформы (Cookiebot, OneTrust, CookieYes, Usercentrics и ещё около двадцати), наличие кнопки «Отклонить» / «Только необходимые» и число скриптов, заблокированных до согласия (type="text/plain", data-category).
  • Читаемость текста: к индексу Флеша добавлены уровень по классам школы (Флеш–Кинкейд; для русского — коэффициенты Оборневой), индекс LIX, словесная оценка, доли длинных предложений (больше 25 слов) и длинных слов; при большой доле длинных предложений выдаётся совет.
  • Защита проверки портов от злоупотребления: один и тот же адрес можно проверять не чаще 12 раз в час (общий счётчик для всех пользователей), а одному обратившемуся доступно не больше 60 портов в час; сверх лимита — понятный отказ. Раньше действовали только короткий список портов, не больше шести за раз, запрет закрытых адресов и общий часовой лимит на сетевые утилиты.

Страницы сервиса и добор до 100% (v135)

  • Предпросмотр сниппета по адресу: в поле «Адрес страницы для автозаполнения» достаточно ввести URL — заголовок, описание и название сайта (og:site_name) подставятся с живой страницы; то, что введено вручную, не затирается. Инструмент теперь считается сетевым (лимиты и право run в API).
  • HTML: безопасный предпросмотр: режим «предпросмотр (без скриптов)» показывает страницу в изолированной рамке sandbox=""; перед показом убираются скрипты, обработчики событий, javascript:-ссылки, фреймы, объекты, внешние стили, @import и перенаправления (HtmlTools::sanitize). Строгий CSP страницы остаётся в силе.
  • Страницы самого сервиса: /about, /contacts, /legal/privacy, /legal/terms, /legal/cookies (src/Legal/Pages.php, app/routes/94-legal.php). Тексты описывают то, что сервис делает на самом деле, а реквизиты оператора берутся из настроек; ссылки есть в подвале и в sitemap.xml. Тест сверяет список cookie на странице с теми, что ставит код.
  • Согласие при регистрации: на форме обязательный флажок со ссылками на политику и условия; сервер отклоняет регистрацию без него и записывает согласие (дата, версия текста) в журнал безопасности аккаунта.
  • Уведомление о cookie: сервис ставит только необходимые cookie, поэтому согласие до их установки не требуется; внизу страницы показывается информационное уведомление, выбор «Понятно» хранится в localStorage, а не в cookie.

Доведение до 100% (v136)

  • Микроразметка Schema.org: инструмент «Микроразметка» теперь читает и RDFa (typeof/property, в том числе вложенные Offer и AggregateRating) наряду с JSON-LD и Microdata. Строка отчёта называет форматы и типы (Organization, Product…) и предупреждает об ошибках разбора JSON-LD: блок с синтаксической ошибкой поисковики игнорируют.
  • Favicon (src/Favicon.php): формат и размеры определяются по байтам файла /favicon.ico (ICO со списком размеров, PNG, SVG, GIF, JPEG, WebP); страница ошибки вместо значка распознаётся. Оценивается весь набор: rel="icon", SVG, значок от 48×48, apple-touch-icon, вес файла.
  • Связанные ссылки (проверка rel_links, вес в ранг нулевой): rel=prev/next, alternate (ленты, языковые версии, мобильная версия по media) и amphtml; предупреждения о ссылках на чужой сайт, AMP по http:// на HTTPS-странице и повторах.
  • Смешанное содержимое: активное (скрипты, стили, фреймы, шрифты — браузер блокирует) и пассивное (картинки, звук, видео — предупреждение) разделены; отдельно отмечаются формы, отправляющие данные по http://, и мета-тег upgrade-insecure-requests.
  • Viewport: разбираются ширина, initial-scale и запрет увеличения (user-scalable=no, maximum-scale меньше 2); запрет увеличения снижает оценку и объяснён в подсказке.
  • Изображения: первое изображение страницы с loading="lazy" отмечается как причина задержки LCP.

Доведение до 100% (v137)

Небольшие инструменты, где в коде оставались реальные пробелы:

  • Проценты: «процентная разница» между двумя числами (по среднему) и «наценка и маржа» по себестоимости и цене.
  • Цвета: кроме HEX и rgb() принимаются hsl(220, 100%, 59%) и базовые имена (red, navy…); смешивание на выбор: по RGB, в линейном свете (физически верно) или по HSL через оттенок.
  • HTML-сущности: режим «именованные» (©, é).
  • Единицы: категория «Скорость передачи» (бит/с … гигабайт/с).

Дизайн и юзабилити (v138)

Проверка живого интерфейса (скриншоты на 1366 и 390 px, обход 87 страниц на 360 px, расчёт контраста по всем текстам в светлой и тёмной теме):

  • Инструменты: форма и результат теперь сразу под заголовком, а плитка из десятков инструментов убрана в сворачиваемый блок «Все инструменты» с поиском по названию (Enter открывает первый найденный). «Похожие инструменты» идут после результата.
  • Подписи: у верхнего поля адреса, поиска-палитры и полей адреса на страницах инструментов есть доступное имя; подсказка в верхнем поле короткая и не обрезается на телефоне.
  • Контраст: подвал и ссылки в нём, серый текст, заголовки бокового меню, основная кнопка и ссылка «Перейти к содержимому» в тёмной теме доведены до 4,5 : 1 и выше.
  • Касание и клавиатура: крупнее цели нажатия на сенсорных экранах, звезда избранного видна без наведения, единый видимый фокус, уважается prefers-reduced-motion.
  • Адаптивность: нет горизонтальной прокрутки на списке методов API и в форме регистрации (длинные адреса переносятся, чекбокс согласия переносится по словам); cookie-плашка не закрывает подвал.

Проверки — набор Pack138, включая расчёт контраста по значениям из таблиц стилей.

Каталог инструментов и быстродействие (v139)

Каталог по задачам. Страница /tools без выбранного инструмента теперь открывает каталог: десять разделов («Проверить сайт», «SEO и содержимое страницы», «Ссылки и адреса», «Домен, DNS и сервер», «Работа с текстом», «Форматы и разметка», «Генераторы», «Кодирование, время и безопасность», «Изображения и файлы», «Расчёты и цвета»). У каждого инструмента — значок и описание. Поиск работает по названию, описанию и словам раздела (например, «сжать картинку», «редирект», «hash»); Enter открывает первый найденный. На странице инструмента — хлебные крошки «Инструменты › раздел», сворачиваемый каталог со сгруппированными ссылками и «Похожие» из того же раздела. Адреса ?t=… и внутренние группы не менялись; каждый инструмент стоит ровно в одном разделе (проверяет тест), новый инструмент без записи попадает в «Прочее».

Быстродействие (результаты не менялись):

  • Форматирование SQL: время было квадратичным (копирование строки на каждом токене) — 100 КБ занимали ≈2 с, теперь ≈0,08 с; вывод совпал со старым на 16 000 случайных запросов.
  • Проверка валидности HTML: номер строки считался с начала документа для каждого тега — теперь по приращению, в 4 раза быстрее на 200 КБ; результат совпал на 3000 случайных документах.
  • Анализ сайта: запросы архива/RDAP и проверки ссылок главной идут одним параллельным пакетом (раньше второй пакет ждал первый — до 10 с при медленном архиве); то же при отложенной догрузке.
  • Инструмент «Редиректы и зеркала»: четыре цепочки идут параллельно (Http::followMany), результат совпал с последовательным на 60 сценариях (циклы, относительные адреса, порты, ошибки сертификата).
  • Описание инструментов строится один раз за запрос; звезда избранного в боковом меню — одна общая картинка вместо 75 копий; список инструментов на странице инструмента без значков (−45 КБ HTML).
  • deploy/nginx.conf: уровень и минимум сжатия, Vary, больше типов, неизменяемый кэш статики, nosniff в блоке статики (add_header в location отменял заголовок сервера); deploy/php.ini: память opcache, число файлов, кэш путей.

Определение CMS (v145)

CMS, конструктор или магазин определяется по сумме признаков, а не по первому совпадению. Учитываются meta generator, заголовки и cookies, адреса файлов в HTML, скрипты и стили, robots.txt и страница 404. Каждый признак даёт баллы, баллы одной системы складываются; побеждает система с наибольшей суммой.

Уверенность показана в отчёте: от 80% — «уверенно», 50–79% — «вероятно», 40–49% — «возможно»; ниже 40% система не показывается. Рядом выводятся признаки, по которым сделан вывод, и версия, если её удалось найти (из generator, из ?ver= у файлов ядра или из служебного файла).

Если после просмотра главной уверенность ниже 70%, сервис делает до шести дополнительных запросов к типовым адресам: вход в админку (/wp-login.php, /administrator/, /bitrix/admin/, /user/login, /manager/). Страница засчитывается, только если ответила кодом 200 и содержит признаки именно этой системы; перенаправление на главную и ответ 404 ничего не доказывают. Если уверенность высокая, лишних запросов нет.

Магазин на готовой CMS показывается дополнением: например, «WordPress» и рядом «WooCommerce». Пользовательские сигнатуры из админки по-прежнему работают и учитываются как умеренно надёжный признак. Если признаков нет, отчёт пишет «Не определена» — сайт может быть самописным или закрывать признаки. Это оценка по открытым признакам: сайт может скрывать CMS, поэтому при низкой уверенности её стоит проверить вручную.

Языки, фреймворки и библиотеки (v146)

К определению CMS добавлено определение технологий, на которых построен сайт. Справочник вырос до 250+ сигнатур, а список категорий в отчёте — четырьмя группами: «Серверные фреймворки», «Операционные системы», «Хостинг и платформы», «Сборщики и инструменты».

Язык программирования определяется по заголовкам (X-Powered-By, Server, X-AspNet-Version), cookies (PHPSESSID, JSESSIONID, ASP.NET_SessionId, CFID), расширениям адресов в ссылках и формах (.php, .aspx, .jsp, .cfm, .pl) и по найденному фреймворку. Поддерживаются PHP, Python, Java, .NET, Ruby, Node.js, Go, Rust, Perl, ColdFusion и Elixir. Фреймворк подразумевает язык: Laravel или Symfony — PHP, Django или Flask — Python, Rails — Ruby, Spring — Java, Express — Node.js. Версия берётся из заголовка, если сервер её сообщает, в том числе из строки Server: Apache/2.4.52 (Ubuntu) PHP/8.1.2.

Серверные фреймворки: Laravel, Symfony, Yii, CodeIgniter, CakePHP, Laminas, Phalcon, Django, Flask, FastAPI, Ruby on Rails, Express, NestJS, Spring, Struts, ASP.NET MVC, Blazor, Phoenix. Операционная система определяется из заголовка Server (Ubuntu, Debian, CentOS/RHEL, Windows Server, FreeBSD), если сервер её не скрывает. Хостинг и платформы: Vercel, Netlify, GitHub Pages, Heroku, Plesk, cPanel, WP Engine, Kinsta, Firebase Hosting.

Для JavaScript-фреймворков, библиотек и UI-наборов (более 100 позиций) версия берётся из адреса файла, в том числе с публичных CDN: cdnjs, jsDelivr, unpkg, Google Hosted Libraries, code.jquery.com. Библиотеки с неизвестными пакетами не выводятся, чтобы не засорять отчёт.

Что важно знать. Определение идёт по открытым признакам главной страницы и заголовкам ответа; серверная часть часто скрыта (прокси, CDN, убранные заголовки), поэтому «не найдено» не значит «не используется». Если для сайта не нашлось признаков, поле остаётся пустым, а название в тексте страницы (например, статья про Laravel) признаком не считается. Свои сигнатуры можно добавить в админке: они попадут в те же категории.

SEO самого сервиса (v147)

Адреса инструментов содержат ключевые слова по основным поисковым запросам: /tools/proverka-robots-txt, /tools/proverka-ssl-sertifikata и так далее (87 инструментов; справочник — Seo\ToolSeo). Старые адреса вида /tools?t=… не поддерживаются: сервис новый, перенаправления не нужны. Параметр ?d= (домен) не создаёт отдельных страниц для поиска: такие адреса получают noindex,follow, а в robots.txt закрыты правилом Disallow: /*?d=.

Шапка каждой страницы собирается в одном месте (Seo\Head). Кроме title, description, keywords и h1–h6 выводятся более редкие теги: robots с max-snippet, max-image-preview, max-video-preview; googlebot; Open Graph с изображением, размерами, подписью и локалью; article:* для блога; Twitter Cards; Dublin Core; referrer; format-detection; color-scheme; theme-color для светлой и тёмной тем; коды подтверждения Яндекса, Google и Bing (задаются в config/app.php или окружении); hreflang (ru и x-default); канонический адрес; значки и манифест; ссылки на RSS, OpenSearch, sitemap.xml и humans.txt. Микроразметка JSON-LD: Organization, WebSite с SearchAction, WebPage или CollectionPage, BreadcrumbList, SoftwareApplication (главная), BlogPosting (с автором, датами, изображением), speakable.

Служебные файлы (Seo\Files): robots.txt (с Clean-param для Яндекса), sitemap.xml (с lastmod, changefreq, priority), llms.txt, feed.xml, opensearch.xml, manifest.webmanifest, humans.txt, .well-known/security.txt. Даты lastmod берутся из дат изменения файлов, поэтому они отражают обновление сервиса, а не каждой страницы.

Проверка заголовков (Seo\Outline): один h1, без пропуска уровней и пустых заголовков. В админке («SEO страниц») у каждой страницы можно переопределить title, description, keywords и h1.

Что важно знать. Метатег keywords Яндекс и Google не учитывают, он нужен другим системам. Главная страница остаётся по адресу /: ключевые слова в адрес не добавить. Язык выбирается cookie, поэтому английская версия отдельных адресов не имеет и в поиск отдельно не попадает. Влияние на позиции зависит от конкурентов и измеряется только по реальной выдаче.