Когда в очередной раз пользователи начали жаловаться на «странную» работу некоторых функций корпоративного сайта, мне пришлось вникнуть в проблему. Она оказалась очень простой: 1) после загрузки страницы javascript находит некоторые элементы по id и связывает эти элементы с событиями; 2) функция javascript, которая должна инициализировать элементы, не срабатывает, потому что страница не загрузилась до конца. Причём, всё честно: браузер крутит около указателя мышки песочные часы, идут минуты, Опера показывает «20 элементов из 21»...
Выяснить, что это за 21-й элемент, оказалось несложно: этот элемент и на вид выглядел бледно. Это был счётчик mail.ru, и он оказался без картинки. Через пару нажатий F5 счётчик «проявился» (всё-таки у mail.ru достаточно крутой сервер :-)), но теперь (уже фатально!) завис информер погоды. А если бы там ещё какой-нибудь Бегун был, или «Расчёт расстояния между городами»? Риск потерять javascript растёт в геометрической прогрессии.
Как всё (загрузка javascript) устроено на странице? На событие window.onload навешена функция, какая-нибудь init(). Эта функция как раз и производит инициализацию всех элементов и других функций, подрисовывает при необходимости, например, круглые уголки или удаляет ссылки на текущую страницу. Но событие window.onload очень «строгое» – оно наступает после загрузки всего содержимого во всех фреймах, и всех javascript во всех фреймах... Я сразу заподозрил, что информер Гисметео связан с какой-то лажей и поместил его на всякий случай в отдельный фрейм. Но это было зря, как слону дробина: window всё равно ждёт, пока Гисметео в своём фрейме завершит свой гнусный javascript.
Не зря Илья Кантор предупреждал о «тяжести» window.onload! Ну, я немного изучил предлагаемую им альтернативу – domContentLoaded, и она мне как-то не очень понравилась из-за всяких костылей (не-кроссбраузерности). Понадеялся на авось. Не прокатило. И теперь вот пришлось изобретать собственный костыль.
Идея достаточно очевидна: загружать все счётчики и информеры после отработки основных функций сайта. Самое простое здесь, казалось бы, – расположить все включения javascript на странице в порядке необходимости: повыше – свои, пониже – информеры. Но это порождает другую сложность: часть элементов не будет загружено; document.body не будет ещё загружено! В таких условиях «свои» функции быстро начнут обрастать просто невероятным количеством костылей. Поэтому в основе я решил оставить всё, как было: главная функция инициализации должна срабатывать по событию window.onload.
А на месте всех счётчиков и информеров просто поставил затычки: если это фрейм – <iframe name="pogoda" src="about:blank", если набор html-javascript для счётчика – пустой именованный элемент (<p id="rating_mail_ru"></p>). А в конце функции init(), после всей основной работы на странице, добавил по нескольку строк на каждый «отложенный» элемент:
Настоящее решение, отсекающее все лишние сущности, находится на этот раз на стороне пользователя, а не программиста. Ничто так не раздражает грамотного пользователя (например, меня), как 10 http-запросов на 10 разных сайтов при открытии одной несчастной страницы. Обычно я захожу на любимый форум по астрологии не для того, чтобы посмотреть погоду или курсы валют (или сообщить на counter.mail.ru о своём посещении). Так какого же хрена я должен пережидать все эти ненужные загрузки? Да ещё Бегуны всякие с Директами без конца трутся!
Начал я (грамотный пользователь) с того, что терпеливо стал заносить все адреса счётчиков и информеров в файл hosts, привязывая их к адресу 127.0.0.1. Терпения хватило ненадолго. Счётчиков (и компьютеров, где приходится работать!) много, а я один. До какой-то степени это, конечно, помогало. Но потом я встретил идеальное решение – плагин для Firefox noScript от Giorgio Maone. Автор просит добровольных пожертвований с рекомендованной суммой 15 баксов. У меня нет лишних 15-ти баксов, но я зато сейчас этот плагин разрекламирую. Вот что про этот плагин, в частности, написано:
"Белый список, базирующийся на принципе упреждающего блокирования, позволяет предотвратить использование уязвимостей (известных и ещё не известных!) без потери функциональности..."
Уязвимости (для грамотного пользователя) – фигня. Но как растёт скорость загрузки! И как радуется глаз отсутствию всякой рекламы! После установки в Firefox плагина noSript при открытии любой новой страницы весь javascript по умолчанию отключён. Вы видите внизу страницы строку «JavaScript'ы запрещены на странице ...». Потом, если оно вам надо, нажимаете кнопку «Настройки» справа и выбираете «Разрешить localhost». И радуетесь своим (только своим!) скриптам:
Если захотите погоду – выбираете «Разрешить временно gismeteo». И радуетесь погоде. И никто уже не сможет без вашего разрешения залезть без мыла на ваш компьютер и следить за каждым движением вашей мышки (как это делает какой-нибудь вебвизор). И никаких Бегунов, Гугладвордсов и Директов!
Остаётся ещё, правда, реклама на флэше, но её как раз отключить гораздо проще, чем javascript. Тут и масса плагинов noFlash или FlashBlock для разных браузеров, и простые, топорные средства. К последним относится, например, упорное нежелание (в течение некоторого времени) грамотного пользователя (меня) установить упорно навязываемый браузером adobe flash player. Но это, конечно, уже совсем последнее дело – состязаться в упорстве с роботом. Достаточно небольшого проявления человеческой гибкости (как в дзю-до), и робот упадёт: adobe flash player (или что там ещё браузер захочет) установить надо, но потом ведь можно просто отключить это дополнение (или плагин)! Вот как это выглядит в Firefox:
Вот как это выглядит в Гугл Хроме:
Ну, а любители Оперы или IE сами найдут, где там что отключить надо для полного счастья.