Можно ли ускорить сегодняшний Internet чисто программным способом, не используя более дорогие каналы каналы связи? Можно, и довольно существенно.
Мы хотим предложить вашему вниманию ряд идей, позволяющих добиться подобного ускорения. Мы также кратко опишем нашу программу AlgART HTML Packer 2.0, реализующую некоторые из этих идей.
Сжатие HTML: нужно ли это?
Наиболее очевидный путь к ускорению Internet - сжатие (компрессия) передаваемых данных с помощью алгоритмов сжатия информации, таких же, какие применяются в известных архиваторах типа WinZip, GZip, Rar, Arj. При этом Web-сервер выдает все страницы в некотором упакованном формате, а броузер автоматически их распаковывает. Скорость распаковки, которую может обеспечить процессор клиентского компьютера, многократно превосходит скорость передачи данных даже на самом хорошем Internet.
Подобная техника давно и повсеместно используется в Internet при передаче картинок, видео и звука: это общеизвестные форматы gif/png/jpeg и всевозможные специализированными форматы типа RealVideo или "фрактального" сжатия. Однако, собственно HTML-текст, составляющий основу всех (или почти всех) Web-страниц, для подавляющего большинства сайтов передается в несжатом виде.
Строго говоря, на многих каналах связи используются различные методы "низкоуровневого" сжатия - например, такое сжатие обеспечивает большинство модемов. Но качество такого сжатия много ниже того, которое дает обычный архиватор WinZip для файла HTML-страницы.
Может быть, сжимать HTML-текст попросту не нужно? Даже самые медленные современные модемы способны обеспечить, как минимум, 1-3 Kb/сек, т.е. 30-килобайтная страница грузится 10-30 секунд. Это вполне достаточно для просмотра текста. Вот графика, если бы ее не сжимали, заняла бы сотни килобайтов и даже мегабайты - там сжатие необходимо, а HTML-текст сжимать вроде бы не стоит.
Я попробую убедить вас, что это не так.
1. HTML-текст гораздо важнее графики
Основа любой Web-страницы - это ее HTML-текст. Пока этот текст не загрузится, пользователь должен просто пассивно ждать - он не может переходить по гиперссылкам, заполнять формы, смотреть картинки, слушать аудиосопровождение и т.д. Самая важная информация обычно тоже представлена в текстовом виде. Таким образом, время, требуемое на загрузку HTML-составляющей Web-страницы - самое критичное. По своему опыту могу сказать, что при активной профессиональной работе в Internet - поиске информации, участии в обсуждениях, переписке (в Web-интерфейсе) и пр. - на анализ содержимого страницы и принятие решения о дальнейших действиях (обычно - переходах) может уходить всего несколько секунд. Средняя же цифра, пожалуй, не больше минуты. Причем при быстром просмотре Internet графика требуется крайне редко (если не считать очень маленьких картинок с кнопками и различными управляющими элементами). Изображения, видео и аудио нужны только на "конечных пунктах" путешествия по Internet, когда начинаешь внимательно изучать найденную страницу. Поэтому экономия нескольких секунд (или, тем более, десятков секунд) на каждой странице - это очень существенная экономия времени пользователя.
2. Траффик
Кроме времени, имеет значение еще экономия траффика на линии. Некоторые Internet-провайдеры берут плату именно за трафик - например, за каждый перекачанный пользователем мегабайт. Html-текст может составлять довольно значительную часть этого трафика. Очевидно, если удастся сократить объем передаваемого HTML-текста в несколько раз - это будет прямая экономия денег пользователя.
Врочем, экономия трафика гораздо важнее не для пользователя, а для держателя Web-сервера. Для него оплата трафика может стоит очень дорого - владелец популярного Web-сайта может платить за канал десятки тысяч долларов ежемесячно. Здесь любая экономия приобретает очень большой смысл.
3. Длинный текст
Иногда бывает удобно представить на одной Web-странице достаточно большой текст - до нескольких сотен килобайтов. Это может быть длинный каталог, литературное произведение, документация, большая статья или монография.
Конечно, длинный текст всегда можно разбить на несколько страниц "разумных" размеров - так обычно и делается. Однако, размещение такого текста на одной странице во многих случаях сильно облегчило бы работу с ним. Прежде всего, такой текст куда удобнее читать - если, конечно, он логически связный. Навигация по нему (с помощью предусмотренных в HTML закладок и гиперссылок) практически мгновенна. В большинстве броузеров существуют встроенные команды для поиска текста в пределах текущей страницы.
Есть и чисто технические преимущества размещения текста на одной странице. Например, такой текст очень легко сохранить на диске - в любом броузере это делается одной командой. С ним лучше работает встроенный кэш: достаточно зайти только на одну страницу, чтобы дальнейшее чтение любой части текста не требовало загрузки по сети. Последнее качество особенно ценно при повременной оплате Internet-подключения, когда пользователю выгодно сначала загрузить все интересующие его страницы в кэш броузера, затем отключиться и не спеша просматривать их в offline-режиме. Очевидно, длинные тексты всегда имеет смысл сжимать.
4. Вписывание в таблицу фиксированной ширины
Очень часто при оформлении HTML-страниц применяется "жесткая" разметка страницы по горизонтали: весь текст размещается внутри вертикальной полосой шириной 500-700 пикселов. Такая разметка, кроме чисто дизайнерских целей, позволяет сохранить читабельность текста при любой ширине окна броузера. Если этого не сделать и позволить тексту занимать по горизонтали все окно броузера, то текст станет практически нечитаемым при большой ширине окна - а это значит, что счастливые обладатели мониторов 1280x1024 или 1600x1200 не смогут читать текст при максимизированном броузере.
Стандартный способ ограничения ширины текста - помещение его внутрь таблицы фиксированной ширины (<table border="0" width="700"...>). Но этот способ в большинстве броузеров порождает побочный эффект: броузер не показывает ничего, пока не загрузится все содержимое таблицы. Это резко обостряет проблему, о которой говорилось в 1-м пункте: 10-секундная пауза, в течение которого пользователь наблюдает чистый экран, воспринимается крайне неприятно.
Ситуацию можно частично исправить, разбив таблицу на несколько таблиц одинаковой ширины. Но обычно текст и графику можно разбивать не в любом месте: скажем, нельзя разбивать абзац, многоуровневый список, текст с расположенными по обеим сторонам "обтекаемыми" картинками или таблицами. Вряд ли стоит разбивать таблицу, имеющую нетривиальный фон (скажем, имитирующий свиток пергамента). Так что разбиение таблицы, в лучшем случае, снижает остроту проблемы, но не снимает ее полностью.
5. "Разбухание" текста из-за HTML-тегов
Некоторые приемы форматирования HTML-текста приводят к значительному увеличению его размера за счет HTML-тегов. Например, банальная таблица чисел - скажем, результаты тестирования чего-либо - может "весить" в 2-3 раза больше, чем ее полезная часть, состоящая собственно из цифр. В еще большей степени это касается таблиц, содержащих маленькие картинки (thumbnails) - здесь практически весь HTML-текст является "бесполезным", исключая, возможно, alt-подписи к картинкам.
Этот эффект может сделать недопустимо большой HTML-страницу, содержащую даже сравнительно немного информации.
В практике нашей фирмы был очень выразительный пример такой ситуации. На странице размещалось порядка 50 небольших изображений - галерея картин нескольких художников с небольшим количеством текста. Каждое изображение было снабжено красивой декоративной рамкой и подписью, сделанными с помощью сложной таблицы. Общий размер всех изображений был примерно 300 Kb. С этим приходилось мириться - при меньших размерах страдало художественное восприятие страницы; тем более, на хорошем Internet такую страницу вполне можно просматривать "сверху вниз", читая сопроводительный текст. Однако табличные HTML-теги, реализующие рамки вокруг картинок, увеличили размер HTML-текста до 130 Kb - при объеме "чистого" текста 15 Kb! В комбинации с размещением всего текста внутри таблицы фиксированной ширины - прием, описанный в предыдущем пункте, - это приводило к крайне долгому ожиданию, пока можно будет хоть что-нибудь прочесть.
Очевидно, описанный эффект тоже может сделать целосообразным сжатие HTML. Заметим также, что стандартные алгоритмы сжатия очень хорошо компрессируют текст с большим количеством повторяющихся слов и комбинаций - в частности, текст, содержащий в основном HTML-теги.
6. Развитые JavaScript-модули
Все современные броузеры поддерживают встроенный язык сценариев - JavaScript, позволяющий реализовывать нетривиальное поведение объектов на странице. В Internet Explorer 5.X встроенный JavaScript настолько мощный, что позволяет реализовать пользовательский интерфейс, практически не уступающий по возможностям профессиональным Windows-программам. В Netscape Communicator 4.X+ средства JavaScript заметно слабее, но все же позволяют решать множество интерфейсных задач.
Казалось бы, что мешает создавать с помощью JavaScript и HTML действительно профессиональные пользовательские интерфейсы к Web-сайтам, работающие на клиентском компьютере? Это могли бы быть различные навигационные деревья с возможностями поиска, графические отчеты по выбранным пользователем параметрам, различные нестандартные элементы типа "всплывающих" иерархических меню, развитые редакторы - и все это без обращения к Internet-серверу!
Одно из важнейших препятствий на этом пути - ограниченный объем JavaScript-кода, передаваемого вместе с HTML-страницей. Обычно до полной загрузки сопуствующего JavaScript пользователь не может или почти не может работать с сайтом и вынужден просто ждать - хорошо еще если не с пустым экраном. Это ограничивает размеры JavaScript-программы примерно 10-20, максимум 50 килобайтами. Понятно, при таких ограничениях ничего серьезного написать нельзя.
В то же время, классические алгоритмы сжатия способны хорошо сжимать исходные тексты программ - в 3-5 раз и даже лучше. Соответственно, сжатие JavaScript-программы повысило бы предельный размер такой программы до 150-250 Kb (не считая комментариев и "лишних" пробелов, которые можно удалить без всякого ущерба для работоспособности программы). Это уже размер достаточно солидного модуля, вполне достаточного, чтобы начать работу - и, если нужно, организовать фоновую загрузку других модулей.
7. Очень медленный Internet
Наконец, бывают случаи, когда скорость Internet из-за перегрузки канала падает практически до нуля. Это характерно в основном для бесплатных или очень дешевых российских каналов. В этих случаях уже не до графики - трудно (а иногда невозможно) просто дождаться, пока на экране появится основная информация. Те, кто с этим сталкивался, безусловно оценили бы всякое сокращение передаваемых данных - даже с 10Kb до 3Kb.
8. И так далее...
Мы рассмотрели далеко не все случаи, когда сжатие текстовых данных в Web-страницах может быть полезно. Например, сжатие явно уместно для текстовых баннеров, так как позволяет увеличить их размер - или количество автоматически сменяющих друг друга вариантов. Очевидно, полезно сжимать всевозможные каталоги и результаты поиска, "нарезаемые" обычно на страницы фиксированной длины: сжатие позволит увеличить количество данных на одной странице. Наверно, список подобных ситуаций можно продолжнить.
Сжатие HTML: почему это не используется
Оказывается, уже несколько лет существует стандарт для сжатого формата HTML-текста - так называемый "GZip-encoding". В действительности, это просто формат известного архиватора GZip, сравнимый по плотности с общеизвестным WinZip. Оба самых распространенных броузера - Netscape Communicator (начиная с версии 4.06) и Internet Explorer (начиная с версии 4.0) - поддерживают этот стандарт, т.е. умеют загружать и показывать страницы, сжатые по стандарту GZip-encoding. Почему же подавляющее большинство сайтов до сих пор не используют этого стандарт?
К сожалению, использование GZip-Encoding сопряжено с некоторыми проблемами. Прежде всего, в отличие от gif или jpeg, формат GZip-Encoding все же известен не всем броузерам - по крайней мере, несколько процентов броузеров "не понимают" страницы, сжатые таким образом. Поэтому Web-сервер должен "уметь" выдавать по запросу как упакованную, так и распакованную версии страниц, в зависимости от версии броузера. Ситуация еще более осложняется тем, что даже броузеры Internet Explorer и Netscape Communicator "понимают" стандарт GZip-Encoding несколько по-разному, причем ни тот, ни другой не соблюдают этот стандарт строго. Например, Netscape неверно интерпретирует длину сжатого сообщения, а Internet Explorer не всегда корректно работает, когда Web-сервер сообщает о наличии сжатия с помощью http-заголовка "Content-Encoding: x-gzip" вместо "Content-Encoding: gzip" - стандарт же требует поддержки обоих вариантов. Другой пример: Internet Explorer "понимает" упаковку подключаемых JavaScript-файлов, а Netscape Communicator не понимает.
Кроме броузеров, стандарт сжатия страниц должны понимать также все proxy-сервера. Здесь тоже царит разнобой: например, клиентский proxy-сервер Naviscope (в сущности, отличная утилита для оптимизации некачественного Internet) всегда требует от оригинального Web-сервера неупакованную версию страницы, т.е. блокирует весь механизм сжатия.
Есть и более тонкая проблема: некоторые (кэширующие) proxy-сервера могут породить ошибку, если по одному и тому же адресу http://www.pupkin.ru/mypage.HTML часть броузеров "видит" упакованную страницу, а часть - неупакованную. А именно, если первое обращение к странице было сделано из "хорошего" броузера, понимающего стандарт GZip-Encoding (например, Internet Explorer), то эта страница попадет в кэш proxy-сервера и будет в дальнейшем - если proxy недостаточно "умный" - возвращаться без разбора всем броузерам, даже тем, которые GZip-Encoding не понимают. Для решения этой проблемы технология упаковки должна обеспечивать для упакованных страниц другие адреса: скажем, упакованная страница могла бы называться http://www.pupkin.ru/GZipped/mypage.html. Но тогда возникает другая, чрезвычайно сложная (в общем случае) проблема коррекции гиперссылок: если распакованная страница http://www.pupkin.ru/mypage.html содержала ссылку на http://www.pupkin.ru/mypage1.html, то в упакованной версии страницы эта ссылка должна вести на http://www.pupkin.ru/GZipped/mypage1.html.
Далее, HTML-страницы, в отличие от картинок gif или jpeg, очень часто бывают динамическими - зависящими от действий пользователя. Простейший пример - результат запроса к поисковой системе. Очевидно, система сжатия страниц должна уметь сжимать подобные страницы "на лету", т.е. в момент обращения пользователя.
Какие решения предлагают самые популярные на сегодня Web-сервера Apache и Microsoft IIS?
Сервер Apache позволяет хранить HTML-файл в GZip-упакованном виде (обычно с расширением .gz). Если к такому файлу обращается броузер, не поддерживающий GZip-Encoding, сервер автоматически распаковывает файл и возвращает неупакованную версию страницы. К сожалению, доступные на сегодня версии Apache реализуют формальный стандарт на GZip-упаковку, не слишком считаясь с особенностями реальных броузеров Internet Explorer и Netscape Communicator. В результате, Internet Explrorer иногда вообще "не понимает" страницы, упакованные по стандарту GZip-Encoding, а Netscape Communicator отказывается кэшировать такие страницы (что гораздо существеннее "тормозит" Internet, чем отсутствие упаковки). Кроме того, Apache никак не поддерживает сжатие "на лету" динамических Web-страниц, зависящих от запроса пользователя.
Сервер Microsoft IIS (Internet Information Server), начиная с версии 5.0, поддерживает GZip-упаковку наиболее удобным для Web-разработчика способом: достаточно поставить некий флажок, и все страницы, выдаваемые сервером, будут автоматически упаковываться. Но за простоту приходится платить. Чтобы эта техника надежно работала, сервер IIS блокирует упаковку (выдает распакованные страницы) для броузера Netscape Communicator, а также при использовании любого proxy-сервера - по крайней мере из того десятка proxy, которые мы проверили. (Возможно, на proxy-серверах фирмы Microsoft все будет нормально: этот случай мы не проверяли.) В результате, достаточно большой процент пользователей (если не большинство) не получит никакого выигрыша от упаковки сайта с помощью IIS.
Как видите, создать сайт, упакованный по стандарту GZip-Encoding, не так просто.
Так ли плотны форматы картинок gip и jpeg?
Конечно, по сравнению с отсутствием упаковки форматы gif и jpeg обеспечивают очень высокую плотность. Иногда - до нескольких десятков раз. Но и в таком виде картинки занимают много места - часто больше, чем весь (неупакованный) HTML-текст. Нельзя ли сжать их еще более плотно?
Оказывается, на сегодня уже давно существуют алгоритмы, обеспечивающие лучшее сжатие картинок. Так, алгоритмы вейвлет-сжатия "обгоняют" jpeg на 30%, а иногда и на 100%.
Кроме того, далеко не все картинки, помещаемые на реальные сайты, делаются действительно аккуратно. Формат jpeg, используемый для упаковки больших изображений, является форматом "с потерей данных". Жертвуя некоторыми мелкими деталями, неразличимыми невооруженным глазом, можно добиться высокой степени сжатия. Но не все авторы картинок тщательно регулируют степень сжатия. Так, иногда 100-килобайтную jpeg-картинку с какого-нибудь сайта удается "дожать" до 50 килобайт, не ухудшая ее внешнего вида - т.е. пользователь вынужден совершенно напрасно загружать лишние 50 килобайт. Эта проблема, конечно, присуща в основном непрофессиональным сайтам - но ведь их очень немало!
Напрашивается идея: сделать программу, автоматически "дожимающую" реальные картинки, размещенные на сайте, с использованием самого лучшего на данный момент алгоритма сжатия, при фиксированном допустимом уровне потерь. Для загрузки и визуализации таких картинок можно использовать Java-апплеты, размещенные на странице вместо обычных тегов <img...>.
Магический формат .mht
От чего еще зависит время загрузки страницы, кроме объема передаваемых данных?
Когда броузер загружает Web-страницу, он ищет на ней всевозможные "подключаемые" объекты, расположенные в отдельных файлах: прежде всего, это файлы изображений. Для каждого такого объекта броузер выполняет отдельный запрос к серверу, чтобы проверить, не изменился ли объект с момента последнего обращения, и при необходимости загрузить его.
Для Web-страницы, активно использующей графические элементы, это может означать десятки запросов. А запрос, даже с ответом "ничего не изменилось", означает передачу по сети довольно большого объема данных - как минимум, пары сотен байтов, а чаще - одного-двух килобайтов. Легко прикинуть, что для страницы средних размеров на это может уйти довольно много времени.
Большинство известных мне утилит "ускорения Internet", а также популярный броузер Opera, рекламируемые как "самый быстрый броузер", позволяют сэкономить это время. Для этого есть много способов. Например, можно более "активно" кэшировать изображения, вообще не проверяя их возможные изменения в течение, скажем, одних суток (так работает Opera). Можно кэшировать так называемые запросы к DNS: использовать при обращении к объекту прямой цифровой IP-адрес вместо обычного "http://www.pupkin.ru/..." (это примерно вдвое снижает накладные расходы).
Однако, мне пока не попадалось использование другой, более перспективной, на мой взгляд, идеи. Internet Explorer 5.0 поддерживает новый формат Web-страниц, в котором все подключаемые объекты "встраиваются" непосредственно в HTML-файл. Откройте в этом броузере любую Web-страницу, содержащую графику, выполните команду "File/Save As..." и выберите формат "Save as Type: Web-arhive for email (*.mht)". Полученный файл, так же как обычную HTML-страницу, можно размещать на Internet-сайте: при ее загрузке не будет ни одного лишнего запроса.
Конечно, практическое использование данной техники требует довольно нетривиальной организации сервера. Так, для броузера Netscape нужно выдавать страницы в прежнем формате (впрочем, сегодня этим броузером пользуются лишь около 15% клиентов). Кроме того, получаемую страницу необходимо упаковывать по стандарту GZip-Encoding, о котором мы говорили выше: иначе изображение, встроенное в .mht-файл, займет на 33% больше места, чем в отдельном файле. Наконец, преобразование в формат .mht не имеет смысла, если HTML-текст меняется гораздо чаще, чем картинки, а суммарный объем картинок достаточно большой - ведь тогда картинки не будут кэшироваться броузером.
AlgART HTML Packer 2.0
Мы разработали программу AlgART HTML Packer (AHP), реализующую некоторые из описанных выше идей. А именно, реализован "прозрачный" для Web-разработчика механизм сжатия сайта по стандарту GZip-Encoding, решающий основные проблемы, описанные в разделе "Сжатие HTML: почему это не используется". Кроме того, имеется бесплатная Web-версия этой программы, позволяющая ускорить доступ к "чужим" сайтам. Всю информацию об AHP можно найти на сайте http://siams.com/ahpr.
В будущем планируется включить в AHP средства дожатия картинок с помощью алгоритмов вейвлет-упаковки, а также реализовать автоматическую конверсию в .mht-формат (там, где это имеет смысл).