Osfonder's blog Just another wd weblog

23Апр/100

Разработка сайтов: Процесс загрузки страницы

Занимаясь оптимизацией работы сайта нужно хорошо представлять, что происходит после того, как посетитель, набрав адрес, нажал клавишу Enter.
Почему тема оптимизации загрузки сайта важна? Дело в том, что интернет сейчас и десять лет назад сильно отличаются. Сейчас люди ожидают, что загрузка должна происходить быстро. А многие, в том числе и поисковые роботы, слишком долго прождав требуемую страницу, просто закроют её (using site speed in web search ranking).

Интернет каналы шире с каждым годом, но несмотря на это в процессе загрузки всегда участвуют факторы, которые не зависят от пропускной способности.

Итак, что происходит после того, как пользователь ввел http://osfonder.ru/blog/ и нажал Enter? Заканчивается это все тем, что вылезет список постов, но до этого...

Визуально процесс выглядит так:

У вас отключен JavaScript. Воспользуйтесь ссылкой ниже для просмотра ролика.



оригинал на сайте bbc

1. DNS

Любой сайт в сети физически располагается на каком-либо сервере. Это компьютер, который постоянно работает и подключен к сети. Каждый сервер имеет, как минимум, один IP адрес. Он позволяет сей сервер уникально идентифицировать. IP адрес — это четыре числа от 0 до 255 разделенных точкой.
И после того как был нажат enter, браузер(читай компьютер) пользователя должен каким-то образом определить к какому серверу(читай IP адресу) относиться адрес osfonder.ru.

Для этого в интернете существуют DNS сервера. Они и хранят такую, необходимую для определения, информацию. По сути в определении адреса участвует цепочка DNS серверов, каждый из которых говорит к какому DNS серверу обратиться, дальше(делегируют) пока последний в этой цепи не выдаст желаемый IP адрес. Каждое звено цепи, естественно, тоже создает задержку.
Но ограничимся лишь тем, что система DNS, в итоге преобразует человеко-понятный символьный адрес в IP адрес и сообщает сколько времени считать его действительным и не дёргать систему, пока время не истечет.

2. Маршрутизация

Хорошо, IP-адрес определили. И, по идее, не плохо бы сразу обратиться к этому адресу просто выбрав нужный провод, на другом конце которого находится сервер. Но нет возможности напрямую соединять каждый компьютер с каждым. Да и интернет к вашему компьютеру подсоединен только с помощью одного провода.

А потому пакеты информации от вашего компьютера до сервера добираются через роутеры, работа которых схожа с DNS серверами. Добравшись до ближайшего роутера ваш пакет будет им направлен на следующий. И так далее и так далее пока не достигнет наконец сервера. И какова бы скорость вашего интернет соединения не была, каждый роутер выполняет вычисления, которые незначительно, но тормозят процесс получения вами информации. И фактически количество промежуточных роутеров зависит от расстояния между вами и сервером.

Поэтому, занимаясь серьезным проектом, который подразумевает, что пользователи будут находиться на определенной территории, в определенной стране, следует размещать сервера именно на там. Или же использовать зеркала, которые хранят полную копию необходимой информации, но опять же на территории большей части её пользователей. Это создает ощутимый прирост в скорости загрузки страниц для всех этих посетителей.

Для примера, зайдите на cnn.com, а затем на lenta.ru и почувствуйте разницу. Если вы находитесь на территории РФ скорее всего лента.ру загрузиться быстрее. И дело в том, что в первом случае информация полетит по проводам в Атланту и из Атланты к вам(скорее всего через Москву и Санкт-Петербург), а во втором — ограничиться Москвой. В первом случае количество промежуточных роутеров порядка 50-ти, во втором меньше 10. Каждый из них создает незначительную задержку.

3. Передача данных

Итак, с путешествием данных по проводам вопрос решили, дальше общение между нашим компьютером и сервером.
И вот время самой интересной части, т.к. она находится в прямой компетенции веб-разработчика и даже верстальщика.

Еще чуть технической информации и дальше пояснение.
Браузеру(компьютеру) требуются какие-либо данные от сервера. Я ввожу http://lenta.ru нажимаю Enter, значит мне нужна главная страница новостей. Браузер устанавливает соединение пройдя вышеописанный процесс и говорит серверу: "мне нужна главная страница сайта lenta.ru",
а буквально передает серверу

GET / HTTP/1.1
Host: lenta.ru
+ еще немного информации о себе и почти всегда cookie данные

Это называется HTTP запрос.
Сервер говорит: "хорошо у меня есть такая страница"(200 OK + еще немного информации) и начинается передача данных. Т.е. html кода этой страницы. После передачи соединение закрывается.

Любой сайт использует внешние файлы. Проще говоря — это картинки, css-стили, js-скрипты. И для каждого из них выполняется процесс маршрутизации, устанавливается новое соединение и вышеописанная операция повторяется. Чувствуете?
Например, в админ-панели последней версии UMI-CMS загружается около 70-ти внешних файлов(без учета системных xml). Что, в принципе, можно оптимизировать.
Админ-панель подходящий случай, т.к. подразумевает частое использование, её оформление не меняется, а потому может и должна работать быстро. И скорость загрузки админки UMI, чуть не единственная претензия нашего отдела сопровождения к ней.
Но не стоит умолять важность скорости загрузки любых страниц и веб-приложений.

Заключение

Все эти факторы долгое время оставались без внимания, т.к. интернет-соединения были медленными и посетитель не ожидал быстрого получения информации. Сейчас же когда каналы ширятся, сервера работают быстрее и каждая доля секунды на счету, камнем преткновения становятся такие, поначалу неочевидные, технические моменты, которые сейчас всё больше и больше учитываются передовыми веб-разработчиками.

Об основных способах ускорения в отдельном посте, здесь же ограничимся определением причин дополнительных задержек при загрузке сайтов и принципа загрузки вообще.

Посты по теме

  1. 10 Золотых принципов успешных Веб-приложений
  2. Используйте CDN для ускорения своих сайтов
  3. Способы ускорения загрузки страницы часть 1
  4. Способы ускорения загрузки страницы часть 2
  5. Способы ускорения загрузки страницы часть 3
17Апр/100

Внешний вид mod_autoindex или организация FTP

У вас есть сервер, который вы используете(в том числе) для хранения файлов и доступа к ним из любого места через интернет-браузер, а файлы, скорее всего, заливаете по FTP.
Если да, то скорее всего вам знакома такая картина

А нет, извините, вам знакома такая


Это стандартная выдача mod_autoindex сервера apache.

Но предлагаю немного упростить себе жизнь и превратить
её в такую.

Да и вообще в онлайн плеер.

Можно это сделать, установив по умолчанию индексным файлом, например, php скрипт, который и будет делать всю черную работу. Есть проект на sourceforge посвященный этому(autoindex).

Но использовать лишнее звено в виде php нет смысла, если есть возможность воспользоваться стандартными функциями или хотя бы просто добавить javascript файл в выдачу. И такая возможность есть.

Большую часть работы по этому уже проделана. Результат её здесь.

Доработанную её версию вам и предлагаю.

Загрузка

Скачать

Нужно просто распаковать архив в корень вашего ФТП хранилища.

Возможности

  1. Сортировка по имени, дате модификации, размеру, типу
  2. Предпросмотр фотографий и изображений
  3. Онлайн прослушивание mp3 файлов

Ну и приглядный внешний вид с иконками.

Техническая сторона

Ну и на последок немного технической информации.

  1. Предпросмотр изображений выполнен с помощью YUI Tooltip
  2. Проигрыватель музыкальных файлов Yahoo! Media Player
  3. JavaScript'ы и устанавливаются в обрамляющих выдачу файлах(см. .htaccess ниже)

P.S. Музыка на скриншоте моих друзей Waterplea, пишущих большей частью ambient.

#Файлы, вставляемые до и после выдачи(в них и крепяться стили и javascript'ы)
HeaderName /indexoverride/HEADER.html
ReadmeName /indexoverride/FOOTER.html
#Запрещаем в выдаче ненужные и системные файлы
IndexIgnore .htaccess indexoverride Thumbs.db .??* *~ *# RCS CVS *,v *,t

#Соритировка по умолчанию
IndexOrderDefault Ascending Description

#Настроки структуры выдачи
IndexOptions FancyIndexing FoldersFirst IconsAreLinks NameWidth=* IconWidth=32 IconHeight=32

#Кодировка по умолчанию
IndexOptions Charset=UTF-8

#Иконки и описания по расширениям файлов
AddIcon (IMG,/indexoverride/image.png) .jpg .JPG .png .PNG .bmp .BMP .svg .SVG .gif .GIF .wmf .WMF .psd .PSD
AddDescription "image / PNG" 		*.png *.PNG
AddDescription "image / JPG" 		*.jpg *.JPG
AddDescription "image / BMP" 		*.bmp *.BMP
AddDescription "image / SVG" 		*.svg *.SVG
AddDescription "image / GIF" 		*.gif *.GIF
AddDescription "image / WMF" 		*.wmf *.WMF
AddDescription "image / PSD" 		*.psd *.PSD

AddIcon (AUDIO,/indexoverride/audio.png) .mp3 .MP3 .wav .WAV .ogg .OGG
AddDescription "audio / MP3" 		*.mp3 *.MP3
AddDescription "audio / OGG" 		*.ogg *.OGG

AddIcon (VIDEO,/indexoverride/video.png) .mov .MOV .avi .AVI .mpg .MPG
AddDescription "video / QuickTime" 	*.mov *.MOV
AddDescription "image / AVI" 		*.avi *.AVI
AddDescription "image / MPEG" 		*.mpg *.MPG

AddIcon (FLA,/indexoverride/flash_src.png) .fla .FLA .as .AS
AddDescription "flash / FLA" 		*.fla *.FLA
AddDescription "flash / AS" 		*.as  *.AS

AddIcon (SWF,/indexoverride/swf.png) .swf .SWF
AddDescription "flash / SWF" 		*.swf *.SWF

AddIcon (TXT,/indexoverride/text.png) .txt .TXT
AddDescription "document / TXT" 	*.txt *.TXT

AddIcon (XLS,/indexoverride/xls.png) .xls .XLS .csv .CSV
AddDescription "document / XLS" 	*.xls *.XLS
AddDescription "document / CSV" 	*.csv *.CSV

AddIcon (DOC,/indexoverride/doc.png) .doc .DOC
AddDescription "document / DOC" *.doc *.DOC

AddIcon (PPT,/indexoverride/ppt.png) .ppt .PPT
AddDescription "document / PPT" *.ppt *.PPT

AddIcon (PHP,/indexoverride/php.png) .php .PHP
AddDescription "PHP" *.php *.PHP

AddIcon (HTM,/indexoverride/html.png) .htm .html .HTM .HTML
AddDescription "HTML" *.htm* *.HTM*

AddIcon (HTM,/indexoverride/css.png) .css .CSS
AddDescription "CSS" *.css *.CSS

AddIcon (ARCHIVE,/indexoverride/archive.png) .zip .rar .arj .arc .tar .targz .gz .Z
AddDescription "Archive / ZIP" *.zip *.ZIP
AddDescription "Archive / RAR" *.rar *.RAR
AddDescription "Archive / ARJ" *.arj *.ARJ
AddDescription "Archive / ARC" *.arc *.ARC
AddDescription "Archive / TAR" *.tar *.TAR
AddDescription "Archive / GZ" *.gz *.GZ
AddDescription "Archive / TARGZ" *.targz *.TARGZ
AddDescription "Archive / compress" *.Z

#Иконка для родительской дирректории
AddIcon (PAR,/indexoverride/dir.png) ..

#Иконка по умолчанию
DefaultIcon /indexoverride/default.png

#Иконки по типам
AddIconByType (TXT,/indexoverride/text.png) text/*
AddIconByType (IMG,/indexoverride/image.png) image/*
AddIconByType (VID,/indexoverride/video.png) video/*
AddIconByEncoding (CMP,/indexoverride/archive.png) x-compress x-gzip
10Апр/100

PHP Пасхальное яйцо

В PHP есть пасхальное яйцо, иногда позволяющее, определить, что сайт работает именно на нем.

Например вконтакте.ru

Достаточно добавить
?=PHPE9568F36-D428-11d2-A769-00AA001ACF42
в конце адресной строки.

Удаляется, обычно, при помощи mod_rewrite.

26Мар/101

Изменяем страницы ошибок

Для установки страниц, возвращаемых пользователю при возникновении ошибки, на сервере apache можно воспользоваться файлом .htaccess
Храниться в корне сайта должен содержать такие строки:

ErrorDocument 400 /system/badrequest.html
ErrorDocument 401 /system/authreqd.html
ErrorDocument 403 /system/forbidden.html
ErrorDocument 404 /system/notfound.html
ErrorDocument 500 /system/serverer.html

На месте /system/notfound.html и т.п могут быть любые документы.

Метки записи: , , 1 комментарий
22Мар/100

Используйте CDN для ускорения своих сайтов.

Создавая современный сайт или веб-приложение вы наверняка используете сторонние JavaScript библиотеки и css фрэймворки.

Самые популярные и используемые из них располагаются в CDN Google, Microsoft и Yahoo!. Это значит, что вы можете подключать их на ваших страницах прямо с серверов вышеуказанных компаний.

А следовательно посетитель, пришедший с другого сайта, который использует ту же библиотеку, с той же Content Delivery Network, не будет повторно ее скачивать и затратит меньше времени на загрузку страницы. Вы же — понизите побочный траффик своего сервера.

Ниже представлен список наиболее полпулярных библиотек с сылками в CDN.

jQuery

Последняя версия первой ветки:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

1.4.2
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>

<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.min.js"></script>

jQuery UI

1.7.2

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"></script>

CSS для jQuery UI

jQuery Validate Plugin

1.6
<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jQuery.Validate/1.6/jQuery.Validate.min.js"></script>

ASP.NET Ajax Start.js

beta 0911

<script type="text/javascript" src="http://ajax.microsoft.com/ajax/beta/0911/Start.js"></script>

Prototype

1.6.1.0

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js"></script>

script.aculo.us

1.8.3

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/scriptaculous/1.8.3/scriptaculous.js"></script>

MooTools

1.2.4

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/mootools/1.2.4/mootools-yui-compressed.js"></script>

Dojo

1.4.1

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/dojo/1.4.1/dojo/dojo.xd.js"></script>

SWFObject

2.2

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>

Yahoo! User Interface Library (YUI)

2.8.0r4

<script type="text/javascript" src="http://yui.yahooapis.com/2.8.0r4/build/yuiloader/yuiloader-min.js"></script>

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/yui/2.8.0r4/build/yuiloader/yuiloader-min.js"></script>

3.0.0

<script type="text/javascript" src="http://yui.yahooapis.com/3.0.0/build/yui/yui-min.js"></script>

Ext Core

3.1.0

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/ext-core/3.1.0/ext-core.js"></script>

Chrome Frame

1.0.2

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1.0.2/CFInstall.min.js"></script>

YUI CSS Reset

2.8.0r4

<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.8.0r4/build/reset/reset-min.css"/>

jQuery UI Themes

<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/base/jquery-ui.css"/>

Black Tie, Blitzer, Cupertino, Dark Hive, Dot Luv, Egg Plant, Excite Bike, Flick, Hot Sneaks, Humanity, Le Frog, Mint Choc, Overcast, Pepper Grinder, Redmond, Smoothness, South Street, Start, Sunny, Swanky Purse, Trontastic, UI Darkness, UI Lightness, Vader and Base

16Мар/103

Техническая сторона: отслеживание перехода по внешним ссылкам.

До этого был поднят вопрос об отслеживании перехода посетителя по внешним ссылкам не в ущерб удобству пользования сайтом.

Теперь коснемся его технической стороны.

Указанный раньше способ, довольно прост и, как следствие, имеет ряд недочетов. Дело в том, подмена адреса ссылки происходит во время перехода по ней, при этом учитывается, как клик левой клавишей мыши, так и средней(по колёсику), что в большинстве случаев приводит к открытию её в новой вкладке.

Текущая же вкладка, остается открытой, с измененным адресом ссылки, неприглядного вида. Её копирование или добавление в закладки приведет к не ожидаемому результату.

Кроме того, в некоторых браузерах клик средней кнопкой мыши не вызывает события onclick и подмены адреса, а значит переходы этой части пользователей зафиксированы не будут.

Обратимся к способу, используемому в поисковой выдаче Google.

В этом способе используется событие onmousedown, то бишь реакция на нажатие любой клавиши мыши, в том числе и правой.

Заключается он в загрузке с помощью JavaScript'a изображения в момент клика. Путь к изображению — есть наш собирающий статистику скрипт с передаваемым ему адресом перехода. Ссылка же продолжает работу, как любая другая, не изменяя своего адреса.

Код, дополняемый jQuery, выглядит следующим образом:

$('a.out').mousedown(function() {
    if(document.images) {
        $('<img>').attr('src', '/tests/out.php?'+$(this).attr('href'));
    }
    return true;
});

В указанном коде скрипту-счетчику,  передается всего один показатель — адрес перехода. Хотя можно усилить статистику, передавая и другие данные. Например время пребывания на странице, до перехода по ссылке и т.п.

Ну и пара слов о способе используемом яндексом. Заключается он в том, что адрес ссылки подменяется в момент клика, но возвращает прежний вид через пол секунды. Таким образом для глаза посетителя ссылка остается оригинальной. Его узкое место в том, что большинство браузеров при копировании ссылки в буфер обмена через контекстное меню, скопируют именно подмененный адрес.

Ну и в дополнение:

Чтобы перехватывать все внешние ссылки, без необходимости присвоения им класса, нужно заменить $('a.out') выражением:
$('a[href^=http://]:not([href*=osfonder.ru])')
где osfonder.ru домен вашего сайта.

Посты по теме

  1. Статистика и анализ: отслеживание переходов посетителя на внешние ресурсы