Примечание: ниже находится перевод двух близких статей ("Delay loading
your print CSS" [http://www.phpied.com/delay-loading-your-print-css/] и
"JS includes — the saga continues…"
[http://www.phpied.com/javascript-include-ready-onload/]) по
оптимизации загрузки страницы при наличии нескольких файлов стилей или
скриптов.
У вас есть два вызова CSS-файлов на странице, например:
<link type="text/css" rel="stylesheet" href="screen.css" media="screen" /> <link type="text/css" rel="stylesheet" href="print.css" media="print" />
Где
первый используется для отображения страницы на экране монитора, а
второй — для предварительного просмотра и печати. Замечательно.
Проблема
в том, что когда дело касается производительности, то браузер не
отображает любую часть страницы (прим.: это не касается Opera, у нее
время этого отображения без полной загрузке файлов стилей задано по
умолчанию в настройках, посмотреть их можно следующим образом
'preferences' (ctrl-f12) -> 'advanced' -> 'browsing' ->
'loading' или 'инструменты' -> 'настройки' -> 'дополнительно'
-> 'перемещение' -> 'загрузка'), пока не загрузит все файлы
стилей. Это включает, в том числе, и файлы стилей, которые не
предназначены для того устройства, с помощью которого производится
отображение страницы. Другими словами, браузер не покажет страницу,
пока не загрузит и файл стилей для принтера, хотя он совсем и не
требуется для визуализации страницы. Это неправильно (that sucks), и
должно быть исправлено в следующих версиях браузеров.
Проверка Я
создал тестовую страницу для того, чтобы это проверить — print.php. Она
включает 2 файла стилей, первый умышленно «засыпает» (sleep()) на 5
секунд, а второй — на 10.
В результате и в Firefox, и в IE загрузка страницы идет 15 секунд до того, как страница отобразится. Ниже картинка Firebug'а:
В
Safari для Windows потребовалось только 10 секунд в первый раз, оба
файла стилей загружались параллельно. Отлично. Плохо, что после
перезагрузки первый CSS-файл не был даже запрошен с сервера. Я
попробовал еще несколько раз, иногда я получал ошибку «The error was:
"unknown error" ((null):10053)» (прим.: проверил в Safari — такой
ошибки не заметил, может быть, у автора была старая бета?).
Итак, решение первое Для
увеличения скорости отображения страницы в браузере нам, фактически, не
требуется загрузка всех файлов стилей. И они могут быть загружены уже
после загрузки и отображения страницы, в фоновом режиме. После того,
как пользователь увидит визуализированную страницу, с которой уже можно
что-либо делать, мы можем загружать дополнительные файлы стилей (и
JavaScript, если потребуется), используя DOM-методы подключения
скриптов и стилей.
Вкратце о методе: с помощью DOM-методов
создаются новые элементы style и script. Затем к ним добавляются
обработчики событий, onload и onreadystatechange, которые будут
сигнализировать, прошла загрузка успешно или нет. Тут демо-версия, а
ниже приведен листинг кода.
var css; function include_css(css_file) { var html_doc = document.getElementsByTagName('head')[0]; css = document.createElement('link'); css.setAttribute('rel', 'stylesheet'); css.setAttribute('type', 'text/css'); css.setAttribute('href', css_file); html_doc.appendChild(css);
// alert state change css.onreadystatechange = function () { if (css.readyState == 'complete') { alert('CSS onreadystatechange fired'); } } css.onload = function () { alert('CSS onload fired'); } return false; }
var js; function include_js(file) { var html_doc = document.getElementsByTagName('head')[0]; js = document.createElement('script'); js.setAttribute('type', 'text/javascript'); js.setAttribute('src', file); html_doc.appendChild(js);
js.onreadystatechange = function () { if (js.readyState == 'complete') { alert('JS onreadystate fired'); } }
js.onload = function () { alert('JS onload fired'); } return false; }
Результаты: как вы могли предположить, результаты различаются в IE и Firefox.
- Подключение CSS — IE выводит оба сообщения, сначала onload, затем onreadystatechange. В Firefox'е ничего не происходит.
- Подключение
JS — IE выводит сообщения для onreadystatechange. Firefox — для onload.
Оба сначала выполнят скрипт, а потом только выведут сообщение по
событию.
Выводы:
- По всей видимости, для
кросс-браузерного подключения файла скрипта необходимо добавлять оба
обработчика событий — onload и onreadystatechange
- В IE есть два способа сообщить о том, загрузился ли CSS-файл
Прим.: лично мне этот способ кажется несколько искусственным и не настолько кросс-браузерным, как хотелось бы.
Решение второе Это решение было описано позже в комментариях читателей. Они предложили просто добавить
@media print {…} в
конец основного файла стилей. Таким образом, будет загружаться всегда
только один файл (прим.: это и более элегантное решение с точки зрения
уменьшения запросов к серверу).
|