→ Пошук по сайту       Увійти / Зареєструватися
Знання Технологія AJAX

Блеск и нищета Ajax

Компетенція Використання AJAX

Пару слов о жизни…

Нет, сначала не про Ajax. Сначала - о прогрессе. Если не о прогрессе в целом, то хотя бы в IT-сфере.

Скажите, есть ли реальный прогресс в этой области – скажем, за последние двадцать лет? С одной стороны – бесспорно. Достаточно учесть только, что быстродействие и объем оперативной памяти компьютеров за это время выросли на два десятичных порядка, и ответ станет очевиден. С другой стороны, когда видишь так же подтормаживающий на суперсовременном компьютере с мультиядерным процессором и четырьмя гигабайтами оперативки под управлением Висты фильм, как подтормаживал он на стареньком “Pentium-II” под Windows-98, когда убеждаешься, что даже директорию последнее детище Microsoft открывает все так же неспешно, как открывала ее Windows-95, то в правильности первого ответа начинаешь сомневаться все больше.

То есть, прогресс вроде бы наличествует, “музыка играет, штандарт скачет”, только все это – для сугубо внутреннего корпоративного употребления. Стремительно растущие возможности “железа” всего лишь позволяют софтвейрным фирмам переходить к более высоким уровням языков и технологий, пропорционально снижая требования к квалификации, а стало быть, и зарплате, работающих в них программистов. Конечному потребителю от всей этой роскоши в виде гигагерц и гигабайт достаются только жалкие крохи.

Что изменится, когда мощности компьютеров возрастут еще на несколько порядков? Ничего, разве что очередной монстр Microsoft будет целиком написан на Visual Basic учениками третьего класса за порцию мороженного. А фильмы будут так же тормозить…

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

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

Конечно, практически все интересные применения этого мощного инструмента оказались невозможны. Раз запросы выполняются браузером, на них распространяется и принятая в нем модель безопасности – так называемая “песочница”: запрос может быть послан только тому домену, с которого был загружен документ. Но кое-какие новые возможности доступ на уровне http все-таки дал. Этого “кое-чего”, что и принято называть Ajax, c головой хватило для очередной Интернет-ррр-р-революции.

Любой сайтописатель с общим уровнем знания сетевых технологий, который принято определять как “ниже плинтуса”, выучив пяток свойств объекта XMLHttpRequest (да и те обычно обернуты библиотечными функциями) и научившись втыкать полученный результат в DOM-дерево, автоматически превращается во Владеющего Самого Современными Технологиями Специалиста. Облапошенные заказчики готовы платить втридорога за модные сайты-инвалиды. А провайдеры и площадкодержатели чешут в затылке и в аварийном порядке пытаются в несколько раз расширить свои забитые под завязку белым шумом каналы.

Как и бывает всегда в среде людей с низким уровнем грамотности, аргументы фанатиков в пользу применения Ajax базируются не на знаниях, а на наборе первобытных суеверий. О двух самых нелепых связанных с этой технологией мифах, а соответственно – о двух самых непростительных ошибках при написании подобных сайтов, я и хочу поговорить. Заранее приношу свои извинения за то, что сказанное всем, кроме Ajax’оманьяков, покажется банальной очевидностью. Проверьте сами: именно эти нелепости предлагаются в нескольких учебниках по Ajax, именно так написаны минимум три из популярных “современных” CMS, а искать “продвинутый” Ajax-сайт, лишенный обеих ошибок, можно долго.

Итак… Миф первый: ”быстро – потому, что асинхронно”.

Да, именно эту фразу можно считать основополагающей в том причудливом мире иллюзий, где обретают Ajax’опоклонники. Первая буква в аббревиатуре от “Asynchronous JavaScript and XML”, собственно, и символизирует асинхронность.

Чтобы вы поняли, о чем идет речь, позволю себе привести хрестоматийный пример из статьи 2001 года “Mastering Ajax, Part 1: Introduction to Ajax” Брэта Маклафлина, и оригинал, и русский перевод которой можно найти на весьма авторитетном сайте http://www.ibm.com/developerworks/. Если по прочтении вы усомнитесь в здравости своего рассудка, могу вас только заверить, что именно предлагаемый способ кочует из учебника в учебник, а также применяется Ajax’офилами и сейчас на полную катушку.

Автор статьи сначала показывает стандартные телодвижения по созданию нового объекта XMLHttpRequest, обработке пришедших от сервера данных и т.д., а затем переходит к главному:

“Что нам осталось? В сущности, не много. Вы имеете JavaScript-метод, собирающий введенную пользователем в форму информацию, передаете ее серверу, предоставляете еще один JavaScript-метод для обработки ответа и даже устанавливаете значение поля, когда этот ответ приходит. Все что осталось на самом деле – вызвать этот первый метод и запустить полный процесс”.

Вот тут-то и начинается самое интересное:

“Вы могли бы, очевидно, добавить кнопку в вашу HTML-форму, но это же старый, добрый 2001 год, не так ли?” – с этим малопонятным, но очевидно радостным восклицанием автор вешает вызов http-запроса – угадайте, куда? – на onChange каждого элемента формы!

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

“Представьте себе Web-форму, которая реагирует не только тогда, когда вы нажимаете кнопку, но и когда вы вводите данные в поле, когда выбираете вариант из списка вариантов и даже когда перемещаете курсор по экрану...” – восхищается автор цитируемой статьи.

Что же, последуем его совету и представим: на Ajax-сайт среднего туристического агенства, лежащий на виртуальном хостинге, приходит в поисках тура пресловутый Вася Пупкин, столяр высокой квалификации. “Пориж” – набирает он в форме. Потом, после мучительных размышлений, долбит по клавише “забой” и исправляет на “Париш”.

Давайте посмотрим, что при этом происходит. При каждом Васином нажатии (!) на любую клавишу на web-сервер отправляется http-запрос с данными: “П”, “По”, “Пор”...

Сервер, матерясь всеми регистрами, сбрасывает в своп задачи других, не столь продвинутых, как наш, виртуальных серверов. Вытаскивает из RAID-массива в оперативку новый экземпляр вашего скрипта (скриптовые языки реентерабельностью отродясь не отличались). Обрабатывает его, давая попутно запросы к серверу базы данных. И возвращает компьютеру Васи результат - некоторое кодовое обозначение ситуации: “фигня какая-то, нет такого города!”. Получив такой код, локальный скрипт радует Васю сообщением вроде: “по вашему запросу ничего не найдено”.

В результате имеем:

- десятикратно возросшую нагрузку на сервер,

- мегабайты белиберды в канале,

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

Надо сказать, что (может, потому, что подобные сайты провайдеры регулярно вышибали с хостннга, то ли потому, что Вася частенько добирался по назначению), но со временем появились два лобовых и топорных способа перевести ситуацию из разряда катастроф в категорию “с трудом, но терпимые”.

Во-первых, были введены ограничения – например, по таймеру и минимальной длине запроса. Понятно, что принципиально это не изменило ничего – мусор стал сыпаться реже, но не перестал быть мусором.

Во-вторых, стало практиковаться так называемое “упреждающее чтение”: в тот момент, когда Вася забил поле минимальной разрешенной длины, скажем, “Пар”, на сервер подается единственный http-запрос, в ответ на который сервер возвращает все возможные варианты с таким началом. После этого по мере продолжения ввода уже локальный скрипт на Васином компьютере просеивает полученный список.

Что дает такой способ? Конечно, он просто меняет направление мусоропровода: мегабайты ненужного хлама вытряхиваются теперь в web-сервер из базы данных и вываливаются оттуда на компьютер пользователя.

“Ну, хорошо”, – скажут, прочитав это, матерые кнопкофобы, - “Мы согласны, что такое решение не лишено крохотных недостатков. Но все-таки, факт остается фактом: раз мы асинхронно подаем запрос серверу, значит, и Вася получит результат раньше, чем в не настолько навороченном и передовом сайте. И тут уж нас автор с панталыку не собъет!”.

Да в том-то и дело, ребята, что не быстрее! Получить нужный ответ Вася сможет только тогда – и ни тиком раньше! – чем он полностью задаст вопрос, это раз. А два – на любом сервере существует ограничение на число одновременно выполняющихся процессов. И когда Вася напишет, в конце концов, “Париж”, web-сервер в это время будет занят обработкой предыдущей белиберды – и Васи, и его коллег. В результате этот единственно нужный запрос будет в лучшем случае поставлен в очередь, а в худшем – вообще получит от сервера отлуп.

Не балуйтесь с кнопками! Оставьте их Васе. О том, когда пользователь закончил заполнение формы, проверил свой ввод и готов отправить данные на сервер, знает не больше двух существ во Вселенной: сам пользователь и Господь Бог, если он существует и интересуется web-программированием. Вы не являетесь ни тем, ни другим, поэтому не пытайтесь присвоить их функции: это не даст ничего, кроме бессмысленной загрузки сервера, канала и компьютера клиента.

Вариант изложенного выше “современного” способа сайтостроения становится, увы, печальным стандартом в сети. Регистрируясь на множестве сайтов, часто мы видим, что каждое заполняемое поле формы тут же перегоняется на сервер, и в результате через неопределенное время рядом с ним всплывает или зеленая галочка, или красный крестик.

Это глупое решение. Глупое по трем причинам. Прежде всего, вам все равно нечего делать на сервере с недозаполненной формой: вы ведь не собираетесь создавать в базе наполовину пустую регистрационную запись? Кроме того, корректность вводимых данных нужно проверять не “быстро - потому, что асинхронно” на сервере, а на два порядка быстрее локальным java-скриптом – не нагружая сервер и канал и не радуя пользователя раздутыми счетами за интернет. И, наконец – элементарные соображения безопасности требуют, чтобы вы перепроверили окончательные значения полей перед занесением их в базу, то есть, вам придется делать двойную работу.

Разве что поле логина полезно проверить на сервере - на предмет занятости. Естественно, запрос надо при этом давать не по изменению состояния поля, а убедившись, что пользователь закончил его ввод: по потере им фокуса ввода (по получению текстового фокуса другим полем), предварительно проверив значение на формальную корректность локальным браузерным скриптом.

Тут же хочу сказать и о стандартной ошибке в дизайне подобных страниц. Когда поле потеряло фокус текстового ввода, это значит, что оно потеряло и фокус глаз пользователя! В это время человек занят уже другим полем и смотрит туда. Поэтому “крестиков-ноликов” рядом с заполненным полем недостаточно. Ошибки должны обязательно дезактивировать кнопку отсылки данных – ту самую кнопку, которую вы хотели умыкнуть у пользователя, но, надеюсь, оставите, прочитав эту статью. И краткое сообщение об ошибке должно появляться вблизи этой самой кнопки: туда перед нажатием посмотрит человек.

Вот, пожалуй, и все об этом. А теперь тех, кто не уснул за чтением первой части статьи, ждет большой сюрприз: второй основной аргумент в пользу Ajax звучит после всего сказанного, мягко говоря, неожиданно. К его рассмотрению мы и перейдем. Миф второй: “Сокращать трафик надо Ajax-ом”.

Да, именно так. Даже в ответ на статью на совершенно другую тему, кроме потока гневных обвинений в замшелой отсталости, невежестве и оппортунизме (как же, в ней вообще не был упомянут не только Ajax и нотация JSON, но даже – страшно подумать - XML!), я получил несколько серьезных комментариев вроде такого: “Кардинально убавить объем загружаемого можно с помощью ajax - перезаписывая только нужные части страницы а не релоадя все целиком”.

Давайте разберемся, о чем здесь идет речь. Раз мы имеем доступ к http-запросам и можем скачать с сервера произвольный файл, обработать полученные данные и вставить результат в произвольный узел DOM – значит, появляется еще один способ (“первый в истории и единственный способ”, как наивно считают Ajax’офаны) обновления фрагментов страницы без полной перезагрузки.

На первый взгляд, идея хороша. В самом деле, элементарное требование дизайна - выдержанность всех страниц в одном стиле: хотя бы для того, чтобы пользователь понимал, что он все еще на том же сайте. Страницы имеют одну и ту же шапку, подвал, боковые панели и т.д. Отличаются одна от другой они только телом. Да и внутри тела может быть несколько независимых блоков, изменяющихся независимо друг от друга. Так зачем каждый раз грузить заново повторяющиеся части?

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

Идея пришла нам в голову как нельзя более кстати: разъяренный Вася Пупкин к этому моменту уже выяснил наш адрес и ломится в дверь.

Успокаиваем нервного столяра и рассказываем ему о нашем озарении. Васе так нравится возможность создания легкого, быстро грузящегося сайта, что он тут же заказывает нам вэб-магазин по торговле табуретками. Лобзаемся с Васей. Пишем магазин. Получаем премию “лучший сайт всех времен и народов”. Хэппи-энд.

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

Спустя две недели Вася Пупкин вновь возникает у нас в конторе, и, вращая молотком над головой, начинает произносить в наш адрес разнообразные слова.

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

И только тут мы понимаем, что все, что мы сделали – на самом деле просто очередная реализация самой уродливой web-идеи. То есть, фреймов. В самом деле, раз мы загрузили основной документ один раз, то и адрес у него соответственно один. С точки зрения что поисковика, что браузера весь наш сайт представляет собой всего одну страницу.

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

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

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

Давайте посмотрим, что у нас получилось. Как и в первом варианте, все неизменные фрагменты передаются только один раз и потом берутся уже из кэша (конечно, если мы пропишем им подходящий “срок годности”). То есть, трафик ровно такой же, как в ajax-варианте. Загружаемые страницы имеют нормальные адреса (новая страница – новый документ), стало быть, нет проблем с закладками браузера. С поисковиками дело обстоит еще лучше: ведь теперь, например, html-страницы имеют полноценную head-часть и мы можем полностью задействовать механизм метатэгов.

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

Единственно, в чем мы проиграли: теперь при загрузке будет на какое-то время “подвисать” предыдущая страница в браузере. Но когда это происходит? Когда браузер уже начал, но еще не закончил получать (и одновременно интерпретировать) документ. Но так как наши страницы весят очень мало, время недоступности интерфейса будет от долей секунды до нескольких секунд.

Взвесьте сами недостатки одного и другого способа. Какой вы выберете? Ответ очевиден.

Конечно, второй имеет еще один неупомянутый минус: он не требует использования Ajax. Функции скриптов могут быть реализованы любым образом – вплоть до JavaScript 1.0. Стало быть, и подтверждать свой профессионализм придется более весомо, чем картинкой “Этот сайт написан на Ajax”. Эпилог

Конечно, специалист обязан назубок знать свои инструменты, в том числе появляющиеся новые, и уметь ими пользоваться - без этого он не специалист. Но понятие “владение инструментом” куда глубже, чем кажется на первый взгляд.

Если мы попросим Васю Пупкина, который уже отошел от злополучной истории с сайтом, объяснить нам, как он стал столяром высокой квалификации, и что это вообще такое – “квалификация”, то, если перевести Васин ответ на допустимый к печати язык, звучать он будет примерно так:

“Ясное дело, столяр должен уметь пользоваться молотком, а то какой же он столяр? Но даже тот, кто умеет забивать гвозди броском молотка с тридцати метров с завязанными глазами - это еще не столяр, это циркач. Настоящую табуретку так не сделать.

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

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

Ajax идеально подходит в тех случаях, когда страницы или их части действительно должны перегружаться в реальном времени (скажем, по таймеру), и при этом не должны каждый раз реиндексироваться поисковиками – например, встроенный в страницу чат или почтовый клиент логично сделать на Ajax.

Пользуйтесь этим и другими мощными инструментами только по назначению, не забывайте о том, что соблазнительное сокращение сложности разработки редко бывает этичным (так как, в конечном счете, почти всегда выполняется за счет времени, нервов и/или трафика конечного пользователя) - и будет вам счастье.

Удачного кодинга всем!

Источник: http://citkit.ru
загрузка...
Сторінки, близькі за змістом