
Мой веб-сайт — это путешествие по волнам памяти. Я не хочу сказать, что нужно прекратить современную веб-разработку. На моём веб-сайте используются технологии, которые в обсуждаемые на нём времена были ещё недоступны. Он работает на мобильных (протестировано в Firefox для Android), отсутствует только фоновое изображение.
Свой первый веб-сайт я создал где-то в начале 2000-х, и как и большинство веб-сайтов того времени, он был очень простым. Это неудивительно, учитывая то, что большинство (включая и меня) писали такие веб-сайты в Блокноте, что накладывало ограничения на сложность. Можно было выбрать или Блокнот, или какой-то из WYSIWYG-редакторов, которые привязывали к себе тем, что сгенерированный ими HTML было бы совершенно невозможно поддерживать без них, а если вносить изменения вручную, то это вполне могло поломать всё в редакторе.
Тогда не было iPhone, почти не было SEO, а JavaScript, как и CSS, использовать было совсем необязательно.
Цветопередача первых ЖК-экранов была плохой, поэтому лучше было выбирать цветовую схему с высокой контрастностью.
Оптимальным разрешением было 1024×768 (или 1280×1024, если вы могли себе это позволить), однако стоило и обеспечить работоспособность размеров окна и панелей в 800×600. Вам же не нужно, чтобы контент выходил за левый или правый край экрана?
Для справки: на изображении ниже показаны разрешения 1920×1080 (HD), 1280×1024, 1024×768 и 800×600 относительно друг друга.

Базовая структура
Самые простые сайты представляли собой обычный HTML, не содержащий ничего, кроме базового форматирования. Иногда, если хотелось выделиться, разработчик мог добавить bgcolor=black
и text=white
.
Те, кому это было важно, могли менять шрифт на sans-serif (без засечек); часто это делалось при помощи тэга <font>
, распространявшегося на всю страницу. Безопасных шрифтов существовало не так много, так что можно было выбирать из следующих вариантов:
Times New Roman: из-за того, что шрифты с засечками применялись по умолчанию, его использование сейчас походит на ошибку или лень, но в нужных местах может добавить ностальгии. К тому же, он выглядит профессионально, ведь это «газетный шрифт». Так как он выбран по умолчанию, этот шрифт отображается, если выбранный владельцем веб-сайта шрифт не установлен в вашей системе.
Arial: шрифт, который выбирали, когда не знали, что выбрать. Разумный выбор, подходящий почти для всех областей применения.
Courier New: этот шрифт выбирали гики. Выбор тех, кто устанавливал для сайта зелёный или чёрный фон.
Comic Sans: сегодня это самый ненавидимый шрифт, однако в те времена он был хорошим выбором для личного веб-сайта. Пусть он и выглядит дурашливо, зато хорошо читаем. Он есть только в Windows, но тогда большинство сидело в Windows.
Анимации
Всегда можно было использовать анимированные gif, но они занимали ценную полосу пропускания. Для простых анимаций движения или мигания применялись тэги <marquee>
и <blink>
. <marquee>
устарел, но всё равно работает. <blink>
уже удалён, но его можно вернуть при помощи JS.
Кстати, можете оценить самую важную анимацию, сделанную на чистом HTML.
Изображения
В то время отсутствовало большинство современных фич CSS, поэтому цветовые градиенты, скруглённые границы и красивые кнопки создавались при помощи крошечных изображений. Часто на сайтах для этих целей использовалось до десяти или более изображений.
Также разработчики время от времени добавляли фоновые изображения. Обычно они были очень маленькими и заполняли плиткой всю страницу. Можно было украсть их с чужого веб-сайта или создать самостоятельно. На моём сайте есть фоновое изображение в виде стены, которое я нарисовал в mspaint за пару минут. Оно весит примерно 130 байт. Это не так изысканно, как анимированное изображение, но лучше, чем сплошной цвет.
Если фон делал текст нечитаемым, то можно было залить его другим цветом в mspaint или просто увеличить размер шрифта. Мы никуда не торопились и не старались уместить в окно как можно больше информации.
Кто-то мог оставлять фон неподвижным при скроллинге, как это сделано на моей странице.
Разбиение веб-сайта на части
С современными веб-сайтами всё просто: если вам нужно, чтобы заголовок или меню оставались видимыми, то достаточно использовать position:sticky;
— вот и всё, теперь при скроллинге элемент всегда будет оставаться в видимой области.
Мы такой роскошью не обладали, зато у нас были frameset. Frameset был (да и остаётся) способом разбиения окна браузера и отображения отдельных страниц внутри этих частей. Многие веб-сайты имели следующую структуру:

Если это не было заблокировано атрибутом, пользователи могли перетаскивать границу кадра, чтобы менять соотношение частей. Также границу можно было делать невидимой, чтобы между частями не было «швов». Если фоновый цвет всех фреймов был одинаковым, то обычно было сложно понять, что страница состоит из нескольких фреймов, если не приглядываться при её загрузке.
Фреймы могут взаимодействовать друг с другом. Можно присвоить им идентификатор при помощи атрибута name
, а ссылки могут менять URL фрейма при помощи атрибута target
. Так работала моя первая система переключения фоновой музыки. Фрейм мог содержать веб-сайт или ещё один frameset, что позволяло разделять окно многократно.
И да, эта технология всё ещё работает. Она помечена в спецификации, как устаревшая, но по-прежнему рендерится и ведёт себя точно так же, как больше двадцати лет назад.
Таблицы, кучи таблиц
Таблицы были практически единственным универсальным способом создания адаптивной структуры веб-страницы. Если указать ширину всех столбцов, кроме одного, то если ширина таблицы была установлена на 100%, ширина этого столбца будет автоматически подстраиваться под текущий размер окна.
Кроме того, таблицы были и первым универсальным способом центрирования контента по вертикали при помощи атрибута valign="middle"
. Показанную выше структуру frameset иногда создавали при помощи таблиц, а не фреймов. Люди могли запихивать в одну ячейку таблиц целые веб-сайты.
Адаптивная структура
Слово «адаптивная» означает, что страница будет подстраиваться под размер экрана компьютера. Никого не волновали современные мобильные прямоугольники, потому что их ещё не существовало. У нас не было flexbox, но многого можно было достичь и при помощи float:left.
Поначалу для мобильных устройств создавали полностью отдельные веб-сайты, оптимизированные под маленький экран. Пользователей перенаправляли на них в зависимости от строки user agent.
JavaScript
JavaScript — это язык, который задумывался ровно для того, чтобы анимированные gif танцевали по странице, а курсор мыши разбрасывал искорки при перемещении.
Именно так мы его и использовали. Ну, и ещё для раскрывающихся меню. Если попробовать что-то более сложное, то уже могли начаться проблемы совместимости с браузерами. Из-за этих проблем и получил свою популярность jQuery — он определял браузер и абстрагировал все его различия с другими браузерами, но ещё долгое время использовались условные комментарии HTML, позволяющие приструнить IE. Практически на каждой странице был раздел <!--[if IE lt 7]>...<![endif]-->
.
Если вам нужен был маленький скрипт, то можно было зайти на сайт наподобие dynamicdrive.com
(уже не работает), поискать его там и скопипастить в свой веб-сайт. Сегодня почти ничего не изменилось, только теперь мы ходим на StackOverflow или спрашиваем у ИИ. В те времена не было ничего лучше, чем копипастить скрипты, потому что инструментов для отладки JS практически не существовало.
Загрузка скриптов блокировала (и сегодня продолжает блокировать) рендеринг на странице всего того, что идёт после них, поэтому тэги скриптов традиционно размещались в конце страницы, а не в заголовке, а маленькие скрипты вставляли прямо в файл html. Сегодня у нас есть атрибут defer
.
Разумеется, если скрипт находится внизу страницы, то пользователи с медленным соединением могли начать взаимодействовать с ней ещё до полной загрузки. Часто эту проблему решали, пряча основной элемент страницы и отображая вместо него текст «Loading» (или gif, если хотелось чего-то изысканного). Небольшой скрипт, засунутый в атрибут onload
тела страницы, затем прятал баннер загрузки и отображал основной контент.
Если сегодня вам требуется, чтобы страница становилась интерактивной ещё до полной загрузки, то можно использовать для корневого элемента документа наблюдатель, следящий за добавляемыми узлами, а затем просто добавлять события к соответствующим элементам в процессе их потоковой передачи.
В те времена у нас такого не было. Мы регистрировали функцию setInterval, часто добавлявшую события, и разрегистрировали эту функцию в событии onload
.
Вне зависимости от количества скриптов на странице, серьёзные веб-сайты в той или иной степени могли работать без них: JS представлял собой угрозу для безопасности, поэтому во многих корпоративных средах его отключали.
При отключённых скриптах для рендеринга любого контента (в том числе и тэгов <style>
) можно использовать тэг <noscript>
. Обычно его используют, чтобы сообщить пользователю, что JS необходим, или чтобы указать ссылку на менее интерактивную версию сайта.
Однако сегодня JS считается обязательным требованием для большинства веб-сайтов. При отключённом JS сайты, использующие рендеринг UI на основе JS, просто остаются пустыми.
Динамический контент на стороне сервера
Суперкрутая страница могла отображать и обновлять динамический контент с сервера. Простейшим решением, которое работало во всех браузерах, был iframe с метатэгом refresh. Он безусловно перезагружал iframe. Если сделать границу невидимой, то пользователь не сможет увидеть разницы.
Разумеется, это плохо, потому что при этом страница перезагружается вне зависимости от того, появился ли новый контент.
Долгие опросы
Долгие опросы (long polling) — это, вероятно, самый «грязный» и хитрый способ динамического обновления контента с сервера. При загрузке веб-сайта браузер рендерит HTML-элементы в процессе их потоковой передачи по сети. Именно поэтому на некоторых медленных сайтах ширина разных элементов меняется с постепенной загрузкой.
HTTP — это протокол, инициируемый строго от клиента к серверу. Однако мы разобрались, как использовать потоковую природу HTML для реализации протокола, инициируемого от сервера к клиенту.
Для этого нужно загрузить страницу в iframe, который намеренно спроектирован так, чтобы загрузка никогда не прекращалась. Время от времени он отправляет невидимый комментарий HTML, чтобы соединение оставалось открытым, но во всё остальное время остаётся молчаливым, пока не появится необходимость отправки нового контента клиенту. При этом можно просто отправить тэг script
с новыми командами JavaScript внутри или, если контент предназначен только для просмотра, div
с контентом внутри, плюс фрагмент кода CSS для сокрытия предыдущего div
.
При такой структуре веб-сайты неограниченно разрастались, но эту проблему можно было решить при помощи meta refresh, выполняемого при завершении соединения.
Это сырая система, зато она позволяла реализовывать динамический контент без JS. На её основе мы создавали целые системы интерактивных чатов.
Первым истинным способом замены long polling были веб-сокеты. В HTTP 2 и 3 появилась возможность отправки событий клиенту без ожидания запроса клиента (это называлось «server push»), но на реальных сайтах я ни разу с таким не сталкивался.
Ajax
Ajax расшифровывается, как «Asynchronous javascript and XML». Эта технология была разработана Microsoft для упрощения коммуникаций между веб-браузерами (на самом деле, только Internet Explorer) и веб-интерфейсом Exchange Server. Это достаточно древняя технология. Впервые она появилась в Internet Explorer 5, но вскоре её освоили и другие браузеры. В продуктах Microsoft активно использовался XML, именно поэтому в слово Ajax попал XML, объект JS для создания запросов называется XMLHttpRequest
и в нём есть специальное свойство responseXML
.
ActiveX
Всё, что невозможно было реализовать по веб-стандартам, можно было расширить при помощи ActiveX. По сути, это был способ загрузки и вызова функций из нативных DLL, которые регистрировались, как компонент ActiveX. Он был необходим для воспроизведения видео. И для звука он тоже был необходим, если вам требовался хоть какой-то контроль над воспроизведением, потому что <bgsound>
не позволял управлять воспроизведением, кроме как заменой его на about:blank при помощи JS для полной остановки. Устаревший сегодня <bgsound>
заменён на <audio>
. К счастью, полностью автоматизированное воспроизведение звука не разрешено в современных браузерах; к этому я бы определённо не хотел возвращаться.
В то время ActiveX позволял и обходить некоторые системные ограничения. В моей школе блокировался удалённый клиент десктопа, но блокировка распространялась только на исполняемые файлы. Я просто загружал библиотеку MSTSCAX в файл html, а затем через веб-браузер подключался к своему домашнему компьютеру, если обнаруживал, что какой-то веб-сайт заблокирован.
Вся эта система была кошмаром, но благодаря огромной доле рынка Internet Explorer компания Microsoft, по сути, могла делать, что пожелает. В каждом браузере эта технология реализовывалась по-своему, и разработчикам постоянно приходилось обновлять эти компоненты.
Flash
Flash (или «уязвимость как сервис») давал множество ранее недоступных возможностей, в том числе воспроизведение видео и аудио вне зависимости от локально установленных кодеров, прямую потоковую передачу, загрузку файлов с полосой прогресса и сетевые многопользовательские игры.
На каком-то временном промежутке его установка была практически обязательной, потому что большинство веб-сайтов в той или иной мере его использовало.
Полоса пропускания
Разумеется, она была на вес золота. И хотя в то время всё было гораздо медленнее, мы не хотели ждать вечно. DSL только набирал свою популярность, и мне повезло, что я начал с подключения 5000/500 Кбит/с.
Однако хорошие веб-сайты загружались за вполне приемлемое время и на коммутируемом соединении. Обычно его называли «56k», потому что такой была скорость при идеальных условиях — 56 килобита в секунду, то есть 7 килобайт.
Часто соединение поддерживало сжатие, а поскольку HTML достаточно легко сжать, можно было добиться и более высоких скоростей.
Оптимизация изображений
В те времена изображения считались медиа, требующим хорошей ширины канала, поэтому не стоило размещать на своей странице кучу картинок без внесения в них серьёзных изменений.
Ниже по тексту показана новая версия стандартных обоев Windows XP, также известных, как «bliss», недавно выпущенная Microsoft. Цвета в новой версии менее яркие, чем в оригинале, но мне кажется, что эта «исправленная» версия больше подходит духу оригинала. Изображение имеет размер 2345199 байт. При соединении 56k оно бы загружалось 5,5 минуты.
Разрешение
Для повышения скорости загрузки мы первым делом снижали разрешение. Если сайт должен работать с дисплеями 800×600, то нет смысла хранить на них изображение в исходных 4089×2726, а поскольку из-за меню frameset мы всё равно не сможем использовать экран целиком, можно ещё уменьшить картинку до 640×480 (до разрешения VGA).
Качество
Потом мы брались за качество. Снизив качество jpeg до 75%, можно ещё больше уменьшить размер. Это значение качества подходит для подобных шумных изображений, но у резких границ (которых здесь нет) возникали бы артефакты.
Благодаря этим ограничениям изображение загрузится примерно за 6 секунд.
Прогрессивное сканирование
Можно имитировать ускоренную загрузку изображения, сохранив его, как прогрессивное. Прогрессивные изображения хранят пиксели не в обычном порядке, а в группах. (Это упрощённое объяснение) В первой группе хранится только каждый восьмой пиксель по горизонтали и вертикали. В следующей группе хранится каждый четвёртый пиксель (минус те, которые уже содержатся в первой группе) и так далее, пока не будут сохранены все пиксели. При не очень хорошем зрении можно и не заметить последний проход.
Хранящиеся в таком виде изображения немного больше по размерам, зато пользователю не приходится ждать, пока они медленно появляются построчно. Мы можем достаточно быстро отрендерить их первоначальную (размытую) версию, которая прогрессивно (отсюда и название) будет становиться лучше.
Такое возможно проделать и с изображениями PNG.
Показанное ниже изображение было сохранено со всеми описанными ограничениями и настройками. Теперь оно весит около 35 КБ. Чтобы увидеть, как оно прогрессивно загружается, обновите страницу или откройте изображение в новой вкладке.

Если разработчик не хотел снижать качество, то он создавал миниатюру, при нажатии на которую пользователь переходил к сырому изображению.
Вот код на PHP, который я использовал для конвертации этого изображения.
$bliss = ImageCreateFromJpeg('bliss.jpg');
// "-1" означает, что нужно вычислить высоту для сохранения соотношения сторон
$scaled = ImageScale($bliss, 640, -1, IMG_BICUBIC);
ImageDestroy($bliss);
// Включаем прогрессивное сканирование
ImageInterlace($scaled, TRUE);
// Сохраняем с качеством 75%
ImageJpeg($scaled, 'bliss_scaled.jpg', 75);
ImageDestroy($scaled);
Динамическая загрузка
Если у клиента был включён JavaScript, то благодаря ему можно было загружать изображение, только когда пользователь проскроллит окно к нему. На сайтах с большим количеством изображений это могло сэкономить много ресурсов.
Это по-прежнему можно реализовать самостоятельно, но браузер также способен делать это автоматически, если добавить атрибут loading="lazy"
. Кроме того, это не позволяет изображению блокировать событие загрузки страницы.
Интерактивность
В определённой степени изображения можно было делать интерактивными. Если изображение находилось внутри тэга <a href>
, то к картинке можно было добавить атрибут ismap
. При нажатии на изображение браузер переходил к URL по ссылке, но добавлял к URL координаты X и Y в виде строки запроса ?X,Y
. Это позволяло серверу определять, в каком месте изображения щёлкнул пользователь. Благодаря этому можно было реализовывать изображения-меню или игры в стиле «Где Уолли?».
Позже появились карты изображений на стороне клиента — невидимые кликабельные области, на которые можно было накладывать изображения.
Обе эти технологии работают, и ни одна из них не помечена, как устаревшая.
Развёртывание
В те времена для личных сайтов и страниц небольших компаний нормой было развёртывание в стиле YOLO. Разработчик менял несколько строк, затем загружал изменения на веб-сервер через FTP-клиент, часто даже в незашифрованном виде. Обычно использовались PHP на веб-сервере Apache и ASP на IIS.
«Staging»? Какой ещё «staging»?
Система была грубой, но как же быстро можно было создавать что-то новое! С PHP очень просто разобраться новичку, он многое прощает, в отличие от других языков, доступен практически везде и всё ещё активно поддерживается. Наверно, он, подобно тараканам, переживёт нас с вами.
Именно так и развёртывается мой веб-сайт, только вместо FTP я использую syncthing, потому что при внесении изменений я хочу, чтобы всё загружалось на сервер автоматически; всё идёт прямиком в прод. Не требуется никакая компиляция или сборка.
В заключение
Тогда всё было проще. Может, не всегда лучше, но точно проще. Мы добивались многого, имея малые возможности. Мы оптимизировали медиа и использовали очень мало скриптов. Теперь всё не так, никого больше не волнует то, что веб-сайт весит десять или двадцать мегабайт.
Скучаю ли я по созданию веб-сайтов в обычном текстовом редакторе? Нет. Мне бы хотелось продолжать работать в моём IDE с подсветкой и проверкой синтаксиса, а также автозавершением кода. К тому же мне нужны библиотеки, упрощающие мою жизнь. Я уже давно не писал никаких операторов SQL в своём бэкенд-коде. ORM-мэпперы SQL прекрасно справляются со своей задачей.
Мечтаю ли я о том, чтобы мы могли снова создавать более простые страницы? Да. Я считаю, что хотя веб-сайты в те времена были проще, а технологии ограниченнее, не всегда это было хуже, чем сегодня. Многие современные сайты кажутся раздутыми и переусложнёнными. Интернет перестал быть местом для творчества, теперь это пространство потребления. Мне бы хотелось возвращения Дикого Запада World Wide Web. Мне бы хотелось снова находить при помощи поисковых движков чудаковатые веб-сайты, а не служить корпоративным алгоритмам.
В процессе написания этой страницы я узнал, что в 2021 году Warner Bros отключила выпущенный в 1996 году веб-сайт фильма «Космический джем» (Space Jam). Хотел бы я указать на него ссылку, но, вероятно, наша единственная надежда сегодня — это Web Archive. Если у вас есть лишнее время, то изучите, как устроено главное меню этого сайта.
Я отдал дань почтения тому времени, написав клон Wordle. Если у вас есть Internet Explorer 1.5 или более поздней версии или любой современный браузер (я слышал, популярность набирает какая-то Mozilla), то вы можете сыграть. Рекомендую установить как минимум IE 2.0, потому что в 1.5 отсутствует поддержка цветов, из-за чего подсказки менее заметны.
Если вы хотите полного олдскула и можете запустить NCSA Mosaic (первый веб-браузер), то сыграйте здесь. Могу подтвердить, что браузер работает в Windows XP и, возможно, в более свежих версиях Windows, но, скорее всего, только в 32-битных версиях.
Примечание: изначально WWW проектировался для обмена топорно отформатированными научными документами и ссылками на них; это объясняет, почему он настолько враждебен к созданию экранных приложений, но имеет множество функций, хорошо подходящих для печатных медиа.
Именно этот набор функций и предоставляет Mosaic 1.0. В нём отсутствует поддержка цвета и даже нет средств для ввода текста, но мне всё равно удалось собрать кое-что и для него. Можно сказать, что поддержка HTTP в нём «где-то есть», поэтому эта версия Wordle работает через собственный порт.
Этот вайб 56k
Перейдя к оригиналу страницы, вы можете ощутить его прямо сейчас. Этот веб-сайт получает обратную связь через последовательное подключение RS-232 со скоростью передачи 56k (на самом деле, немного больше, чтобы справляться с оверхедом протокола). Я отключил кэш сервера, поэтому вы можете сами наблюдать за уменьшением полосы прокрутки в процессе постепенной загрузки контента.
Но некоторые вещи стоят потраченного на них времени. Пользователи могут и не заметить, что ваш веб-сайт медленный, если вы дадите им контента для чтения, прежде чем бросите в лицо сгенерированное ИИ изображение заголовка.
Для этого вам не потребуется обратная связь последовательного соединения, с этим вполне справится инструмент наподобие SlowPipe, размещённый перед сервером.
Спасибо за прочтение статьи
NO CARRIER█