WAP и мобильный интернет в Кыргызстане 2010–2011: первые мобильные сайты
В 2010 году «мобильный интернет» в Кыргызстане означал три вещи: GPRS (редко EDGE), кнопочный телефон Nokia или Samsung, и WAP-браузер с поддержкой XHTML Mobile Profile.
iPhone в Кыргызстане был редкостью. Android — ещё меньше. Мобильный трафик нашего клиента — портала объявлений — на 78% шёл с кнопочных телефонов. Сделать «мобильную версию» значило сделать WAP-сайт.
Что такое WAP-сайт технически
WAP (Wireless Application Protocol) — протокол и стандарт для мобильных устройств. К 2010 году фактически стандартом стал XHTML MP (Mobile Profile) — подмножество XHTML, специально ограниченное для мобильных браузеров.
Ограничения XHTML MP:
- Размер страницы: желательно не более 15–20 КБ (включая HTML и inline CSS)
- JavaScript: не поддерживается большинством WAP-браузеров
- CSS: только базовое подмножество (без float, position, псевдоклассов)
- Медиа: только GIF и JPEG, PNG — не везде
- Таблицы: избегать, они плохо рендерились на экранах 128×160 пикселей
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN"
"http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Объявления Бишкек</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<!-- Viewport для телефонов с нормальным браузером (Opera Mini и др.) -->
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<style type="text/css">
/* Максимально простой CSS — только то что точно работает */
body { font-family: sans-serif; font-size: 14px; margin: 5px; padding: 0; }
h1 { font-size: 16px; margin: 0 0 8px 0; }
a { color: #0055AA; }
.item { border-bottom: 1px solid #CCC; padding: 6px 0; }
.price { font-weight: bold; color: #CC0000; }
</style>
</head>
<body>
<h1>Объявления</h1>
<!-- Поиск: только GET-форма, POST мог не работать на некоторых WAP-браузерах -->
<form action="/wap/search" method="get">
<input type="text" name="q" value="" maxlength="50"/>
<input type="submit" value="Найти"/>
</form>
<!-- Список объявлений: минимум разметки -->
<?php foreach ($ads as $ad): ?>
<div class="item">
<a href="/wap/ad/<?= $ad['id'] ?>"><?= htmlspecialchars($ad['title']) ?></a>
<br/>
<span class="price"><?= number_format($ad['price']) ?> сом</span>
</div>
<?php endforeach; ?>
<!-- Пагинация без JavaScript: только ссылки -->
<?php if ($page > 1): ?>
<a href="?page=<?= $page-1 ?>">← Назад</a> |
<?php endif; ?>
<?php if ($hasMore): ?>
<a href="?page=<?= $page+1 ?>">Вперёд →</a>
<?php endif; ?>
</body>
</html>
Определение мобильного браузера
Главная задача — автоматически перенаправить мобильного пользователя на WAP-версию сайта:
function isMobileBrowser(): bool {
$ua = strtolower($_SERVER['HTTP_USER_AGENT'] ?? '');
// Ключевые слова мобильных браузеров 2010 года
$mobileKeywords = [
'nokia', 'samsung', 'motorola', 'lg-', 'sonyericsson',
'blackberry', 'palm', 'windows ce', 'symbian', 'wap',
'midp', 'j2me', 'opera mini', 'opera mobi',
'mobile safari', // ранние iPhone
'android', // ранние Android
];
foreach ($mobileKeywords as $keyword) {
if (strpos($ua, $keyword) !== false) {
return true;
}
}
// Заголовки, которые операторы добавляли для WAP-трафика
if (!empty($_SERVER['HTTP_X_WAP_PROFILE'])) return true;
if (!empty($_SERVER['HTTP_PROFILE'])) return true;
return false;
}
// В index.php — перенаправление
if (isMobileBrowser() && !isset($_GET['full'])) {
header('Location: http://m.yoursite.kg' . $_SERVER['REQUEST_URI']);
exit;
}
Обратите внимание на ?full параметр — ссылка «Полная версия» позволяла пользователю принудительно открыть десктопный сайт. Это было стандартом — некоторые пользователи с продвинутыми телефонами (Nokia N97, ранние Android) предпочитали полную версию.
Оптимизация размера страницы
15 КБ — жёсткий лимит для надёжной работы на самых медленных соединениях. Что это означало на практике:
// Сжатие вывода: каждый байт на счету
ob_start('ob_gzip_handler');
// Минимизация HTML: убрать лишние пробелы и переносы
function minifyHtml(string $html): string {
// Удалить комментарии
$html = preg_replace('/<!--(?!<!\[)(?!DOCTYPE).*?-->/s', '', $html);
// Сжать пробелы (но не внутри pre и textarea)
$html = preg_replace('/\s+/', ' ', $html);
return trim($html);
}
// Изображения: только необходимые, минимальный размер
// Логотип: 80×20 px GIF = ~800 байт
// Иконки: 16×16 px GIF = ~200 байт
// Пагинация: показывать максимум 5 элементов на страницу
$perPage = isMobileBrowser() ? 5 : 20;
Opera Mini: неожиданный стандарт
Самым популярным мобильным браузером среди «продвинутых» пользователей в Кыргызстане 2010 года был Opera Mini. Он работал на любом телефоне с поддержкой Java (J2ME), сжимал трафик через серверы Opera, и рендерил даже сложные сайты.
Opera Mini имел важную особенность: он рендерил страницу на серверах Opera, сжимал и передавал телефону готовое изображение. JavaScript не выполнялся на клиенте — только на сервере Opera (частично). Это означало: интерактивные элементы на JavaScript не работали вообще.
// НЕ РАБОТАЕТ в Opera Mini 2010
document.getElementById('menu').style.display = 'block'; // Игнорируется
// РАБОТАЕТ: ссылки с параметрами, перезагрузка страницы
// Всё взаимодействие — через GET/POST, без AJAX
Это было ограничение, но и дисциплина: если что-то требовало JavaScript — значит, это не должно быть критичным для основного функционала. Мобильная версия работала без единой строчки JavaScript.
Переход на адаптивный дизайн (2012–2013)
К 2012 году доля смартфонов начала расти. Наш клиент в начале 2013: 52% — смартфоны, 48% — кнопочные телефоны. Поддерживать два отдельных сайта стало нецелесообразным.
Переход на адаптивный дизайн (CSS медиазапросы) позволил обслуживать оба сегмента одним кодом. WAP-сайт мы не удалили — оставили как резервный вариант для старых телефонов, которые не понимали CSS3 медиазапросы. Он работал ещё два года.
WAP-эпоха научила нас главному о мобильной разработке: скорость и лаконичность важнее визуальной сложности. Сайт, который загружается за 3 секунды на медленном соединении, лучше красивого сайта, который грузится 15 секунд. Этот принцип не устарел — изменились только пороговые значения времени загрузки.