Это сайт — моя персональная записная книжка. Интересна мне, по большей части, история, своя жизнь и немного программирование.

JS CSS в одном файле у меня на сайте

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

Особых трудностей не встретил, только убрал все комментарии из файлов с JavaScript руками и добавил удаление BOM из файлов, браузеры как-то нервно реагируют на них, встретив их не в начале файла, а мой редактор кода зачем-то их вставляет.

Схема, в общем-то, не изменилась — если файл .cssjs есть на диске, отдаём его средствами веб-сервера, если нет, собираем необходимое, кладём на диск и отдаём браузеру.

Вот ещё тонкость, обязательно нужно добавить новый mime-тип:

AddType */* .cssjs

Я-то думал, что он нужен только для FF 2.xx, ничего подобного, последние «Опера» и FF так же отказались работать без этого заголовка.

Оказалось, что последний «Хром» ни в какую не хочет рендерить CSS с таким типом, пришлось заменить на «text/css,*/*» на «text/css», предыдущий вариант не работал в IE9.

Надо посмотреть как отнесётся к этому второй FF, а пока, если у вас «Хром» или IE9 и показывает неправильно, обновите, пожалуйста, страницу, чтобы она не из кеша взялась, всё должно нормально отрендериться.

Посмотрим «в поле» насколько это стабильно работает.

33 комментария
Ivan Kataitsev 2011

Хром 12 под Маком не работает.

Сергей 2011

в последнем хроме так: http://imgur.com/XckVj

Евгений Степанищев (bolknote.ru) 2011

Спасибо, ребята, сейчас посмотрю!

Сергей 2011

json: «application/json, text/javascript»,«*»: «\x2A/*»}

Евгений Степанищев (bolknote.ru) 2011

Комментарий для Сергей:

К чему это, я не понял.

Евгений Степанищев (bolknote.ru) 2011

Ага, FF2.0 полёт нормальный: http://browsershots.org/screenshots/ccd190601b98bbcb24102aab29333ece

ЖЖитель (zhzhitel.livejournal.com) 2011

Chrome 14 — ОК.

Евгений Степанищев (bolknote.ru) 2011

Комментарий для zhzhitel.livejournal.com:

Я уже починил для «Хрома».

Евгений Степанищев (bolknote.ru) 2011

В Dillo какие-то проблемы: http://api.browsershots.org/png/original/41/41505e73a44fd9cd8299e0f391c6ae7f.png
Надо глянуть.

zabytki.in.ua/ru/ 2011

А я смотрю в FF3.6 и Хроумиме файл грузится дважды. Одновременно main.cssjs и main.cssjs#2. Первый за 31мс, второй за 287мс. В Опере — один раз.

Евгений Степанищев (bolknote.ru) 2011

Комментарий для zabytki.in.ua/ru/:

А я смотрю в FF3.6 и Хроумиме файл грузится дважды. Одновременно main.cssjs и main.cssjs#2. Первый за 31мс, второй за 287мс. В Опере — один раз.

Очень вряд ли. Один из них — попадание в кеш.

Alex 2011

IE9 — не работает вообще

Евгений Степанищев (bolknote.ru) 2011

Комментарий для Alex:

Спасибо! Сейчас попробую найти Windows.

IE8 работает: http://api.browsershots.org/png/original/a2/a298ed5a01e4eba48525c1a05bbef156.png

Евгений Степанищев (bolknote.ru) 2011

Комментарий для Alex:

Поправил.

Александр Карпинский 2011

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

Евгений Степанищев (bolknote.ru) 2011

Комментарий для Александр Карпинский:

То есть, к тому времени, когда JS понадобится, он уже будет загружен? Да, хорошее развитие идеи.

twitter.com/thenameisbusy 2011

Комментарий для Евгения Степанищева:

Евгений, а почему эту технику не протестировать на сайтах с большой посещаемостью?

У вас в Яндексе есть места где можно это сделать.

Например, так:

// /*
window.onload = function() {
var body = document.getElementsByTagName(’body’)[0];

var test = document.createElement(’div’);
test.innerHTML = ’ ’;
test.className = ’cssjs-test’;

body.appendChild(test);

if (test.offsetHeight !== 0) {
//fail, sending UA on server
}

body.removeChild(test);
}
«*/{»/*«}

{

display: none;
}
*/

Евгений Степанищев (bolknote.ru) 2011

Комментарий для http://twitter.com/thenameisbusy:

Потому что на серьёзных проектах не место для экспериментов над пользователями.

Евгений Степанищев (bolknote.ru) 2011

Комментарий для http://twitter.com/thenameisbusy:

А, я понял что имеется ввиду, когда прочитал внимательно.

Как я уже убедился, эта техника достаточно хрупкая, может поломаться в релизе какого-нибудь нового браузера. Что же тогда, все сервисы «Яндекса» переделать к этому релизу? Это очень ресурсоёмко.

twitter.com/thenameisbusy 2011

Комментарий для Евгения Степанищева:

Я имею ввиду не «сделать ее рабочей на серверах Яндекса», а просто грузить доп. файл для сбора статистики -​-​ кто прошел тест, а кто завалил.

Евгений Степанищев (bolknote.ru) 2011

Комментарий для http://twitter.com/thenameisbusy:

Предположим невероятное, что я сошёл с ума и использую какой-то топовый проект «Яндекса» в своих личных целях — захотелось мне, понимаешь, оттестировать какой-то сомнительный код на продакшне :) Не дай бог мне, конечно, дойти до такой степени отчаяния.

Так кто мне позволит-то? :) У этих проектов есть свои авторы: разработчики, менеджеры, маркетологи и прочие ребята, которые за него болеют. А я тут собираюсь увеличить время загрузки страницы только из-за того, что мне так захотелось? :)

twitter.com/thenameisbusy 2011

Комментарий для Евгения Степанищева:

А вдруг разработчики некого сервиса Яндекса захотят (теоретически) добавить несколько невинных строчек кода на продакшн от которого, в принципе, никакого криминала не случится, а вот польза будет? Почему в личных целях, разве компания не заинтересована?

Евгений Степанищев (bolknote.ru) 2011

Комментарий для http://twitter.com/thenameisbusy:

Это сколько мне сервисов надо обойти? http://www.yandex.ru/all

Почему в личных целях, разве компания не заинтересована?

Нет, конечно. Я же говорю: технология потенциально глючная.

Александр Карпинский 2011

Комментарий для Евгения Степанищева:

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

Евгений Степанищев (bolknote.ru) 2011

Комментарий для Александр Карпинский:

Да, я идею понял. Хорошая идея.

Евгений Степанищев (bolknote.ru) 2011

Комментарий для Александр Карпинский:

Если проведёте какие-то эксперименты, киньте ссылку, не сочтите за труд.

Alex 2011

Евгений, IE9 заработал.

Евгений Степанищев (bolknote.ru) 2011

Комментарий для Alex:

Спасибо!

Александр Карпинский 2011

Комментарий для Евгения Степанищева:

В общем, способ работает, им действительно можно заставить грузить в Опере скрипты параллельно. Но, например в Хроме они начинают просто грузиться 2 раза, а в Фаерфоксе мало того, второй раз еще происходит последовательно :) Не как мне не удается их заставить закешировать файлы намертво и второй раз за ними не бегать.

Евгений Степанищев (bolknote.ru) 2011

Комментарий для Александр Карпинский:

Но, например в Хроме они начинают просто грузиться 2 раза, а в Фаерфоксе мало того, второй раз еще происходит последовательно :) Не как мне не удается их заставить закешировать файлы намертво и второй раз за ними не бегать.

Не факт, что они действительно грузятся второй раз. В FF надёжнее всего смотреть через livehttpheaders, а не через firebug. В «Хроме» хорошего способа не знаю.

Александр Карпинский 2011

Ошибки быть не может, я же загружаю js.php
http://pastie.org/2114550
Ну и результат замеряю незамысловато.
http://pastie.org/2114558

Евгений Степанищев (bolknote.ru) 2011

Комментарий для Александр Карпинский:

Для «Хрома», кстати, предназначен «#2» ( http://bolknote.ru/all/3185/ ).

Евгений Степанищев (bolknote.ru) 2011

Комментарий для Александр Карпинский:

Директивы «store» у Cache-control нет ( http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 ), есть «public».