Примечание: ниже находится перевод двух близких статей ("Delay loading your print CSS" и "JS includes — the saga continues") по оптимизации загрузки страницы при наличии нескольких файлов стилей или скриптов.
У вас есть два вызова 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.
onload
, затем onreadystatechange
. В Firefox'е ничего не происходит.onreadystatechange
. Firefox — для onload
. Оба сначала выполнят скрипт, а потом только выведут сообщение по событию.onload
и onreadystatechange
Прим.: лично мне этот способ кажется несколько искусственным и не настолько кросс-браузерным, как хотелось бы.
Это решение было описано позже в комментариях читателей. Они предложили просто добавить
@media print {}
в конец основного файла стилей. Таким образом, будет загружаться всегда только один файл (прим.: это и более элегантное решение с точки зрения уменьшения запросов к серверу).