Как стать автором
Обновить

Комментарии 50

зачем тут сессия?
Чтобы хранить информацию о том, что первый запрос был показан этому конкретному пользователю. Мы не можем передавать дополнительные GET параметры, URL должен оставаться неизменным чтобы браузер отправил заголовок HTTP_IF_MODIFIED_SINCE и HTTP_IF_NONE_MATCH. А при использовании мемкэша или файловой системы все равно придется как-то учитывать уникальность пользователя.
Впрочем я буду рад решению без сессии, если вы его предложите.
echo $timeStamp;
или даже echo microtime(1) запрос то в одну секунду прийти может
Cуперски! Я как-то не подумал про естественную смену содержимого — время. Внес изменения в пост, убрав сессии и используя microtime. Cпасибо
Я тогда и свои 5 копеек вставлю.

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

Я бы делал эти два запроса только для тех, у кого страница медленно сгенерировалась, т.е. пользователь ждал. Он мог ждать и из-за медленного интернета, и из-за лагов у вас на сервере, поэтому нужно проверить кеш ли тому виной.

Проверка: разница во времени между получением ДОМ модели документа, и получением всего контента (в частности статического).

В ф-ии allContentLoaded, если разница: time2 — time1 привысит какое-то пороговое число для вашего сайта. Делайте запросы для проверки кеша.

<html>
<head>
</head>
<body onload="allContentLoaded()">
<!-- Page's content here-->
<script>

var time1 = 0;
var time2 = 0;

function microtime(get_as_float) {
  var now = new Date().getTime() / 1000; 
  var s = parseInt(now); 
  return (get_as_float) ? now : (Math.round((now - s) * 1000) / 1000) + ' ' + s;
}

if (document.addEventListener) {
  document.addEventListener("DOMContentLoaded", DOMContentLoaded, false);
}

function allContentLoaded() {
  time2 = microtime(true);  
  res = parseFloat(time2 - time1).toFixed(3);
  alert(res);
}

function DOMContentLoaded() {
  time1 = microtime(true);
}
</script>
</body>
</html>


* This source code was highlighted with Source Code Highlighter.


ЗЫ. код набросал на коленке. Немного не кроссбраузерно, просто чтобы логику показать
В моем случае проверка происходит только при загрузке первой страницы с чекерами. Соглашусь, что ваш подход минимизирует лишние запросы, и должен быть применен, если мы хотим выполнять проверку на каждой странице.
Нужно только учитывать, что время загрузки — не надежный показатель, зависимый не только от проекта и канала связи, но еще и от параллельных процессов выполняемых на компьютере. Поэтому js напуганный большой разницой все равно будет переодически отправлять запросы на проверку кэша.
2 библиотеки
40 файлов скриптов

за такое руки нужно отрывать и накладывать пожизненный запрет на использование интернета.

да и даже после склейки, сразу две библиотеки использовать — рак мозга…

ну а идея проверки неплоха, да
Две библиотеки — это безусловно скверно. В рамках данного проекта это был результат плохой коммуникции распределенных комманд, каждая из которых считала, что у них-то яйца больше, и они-то знают как делать. Попытки стандартизировать UI и перевести всё на компоненты только одной библиотеки вызывали смятения в рядах влиятельных пользователей, которые привыкли именно к такому дереву или гриду…
вот и я о чем…
благо, хоть один там адекватный человек (вы) нашелся, который хотя бы скрипты склеил.
Экий вы восторженный и категоричный. Как пожарный.
Можете организовывать рукоотрывательный поход против разработчиков, использующих ExtJS, у которых на проект подключаемых файлов побольше раза в два-три. Пруф: Writing a Big Application in Ext.
Мил человек, на деве у вас может быть хоть 100500 файлов по 10 строчек, как вам будет удобнее.
На продакшене же всё ДОЛЖНО быть собрано и пожато, тем более, если там всего так много.

Это во-первых.

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

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

Не у всех вэбкит, который легко проглатывает тонны скриптов.
Не у всех 4х-ядерные процы.
И не все держат браузер с одной вкладкой и больше ничего не открывают.
Пользовательские ресурсы нужно щадить.
Ext.JS прекрасно работает на базе jQuery, что уменьшает оверхед.
и что?? это повод загружать пользователю столько лишнего?
Только что скачал экстджеэс. ext-all.js — 664КБ! (и это сжатый)
Плюс к этому — джейквери.
Плюс к этому куча плугинов и скриптов (40 штук!)
Это в общей сложности получится около метра скриптов. Сотни и сотни функций, большая часть из которых, к слову, друг друга дублируют.
Браузеру нужно распарсить этот мегабайт кода, загрузить в память хренову тучу переменных и при каждом чихе ворочать всю эту кучу скриптов.
Ау, народ, вы издеваетесь??
Где оптимизация?? Где быстрые скрипты?? Вы что, в конец обленились?
Понятно, что писать без либ вообще — слишком затратно по времени да и баги потом ловить задолбешься, но такое наворачивать зачем?

Читаю и просто поражаюсь. во подход же…
Странный Вы.

Например, мой самый популярный проект последних трёх лет скачивает 2.3Mb скриптов. У этого проекта полно фанатов. За 16 часов 23000 визитов. Каждый визит — на минут 20 минимум.

что за проект такой?
это не показатель.
на рынке масса кривых и глючных продуктов, которыми пользуются сотни тысяч и миллионы.
просто самому, как разработчику, должно быть стыдно.
Ты (это абстрактное обращение) же делаешь продукт, который выпускаешь в массы. Это — твое лицо. Так делай же его хорошо! Так, чтобы было чувство удовлетворения, что выжал максимум, что сделал лучше других, что ты достиг чего-то большего, чем раньше.

Понятно, что когда речь идет о каких-то скороспелках/дешевых заказах/какой-то ерунде — там можно особо не париться.
Но если ты делаешь что-то серьезное, или тем более собственный проект — имей же уважение к себе, сделай продукт по-настоящему качественным во всех отношениях…

Печально…
Ага, причем многоуважаемый битрикс в рядах кривых, устаревших и т.п., но благодаря интеграции с 1с — довольно популярен… Жаль.
Если все считают мой продукт эталоном, и конкуренты вымерли, то всё хорошо.

Используйте кэширование и сжатие, и всё будет ОК )
Closure compiler поможет избавиться от тонны не используемых функций в продакшене
Если конечно код хорошо и правильно написан :)
увы, он не на столько хорош, как хотелось бы.
тестил, пробовал.
скорее всего это связано с тем, что библиотеки сами по себе перелинкованы внутри и вот так взять и удалить какую-то функцию — нельзя.
По крайней мере я точно помню, что после экстремального сжатия джейквери + тестовый крохотный скрипт компайлером, итоговый скрипт весит больше, чем скачанный с сайта уже минимизированный джейквери + тот самый тестовый скрипт.

хотя я возлагал на него большие надежды :(
Ну я же пояснил, если код хорошо и правильно написан. jQuery по началу даже не работал с компайлером. Ясно конечно что там завязано все внутри настолько жестко, что удалить мало что получается. Это большой минус jQuery.
По jQuery — можно собрать избранные модули, а не все.
jQueryUI — можно
jQuery core — увы, нельзя
Вы ошибаетесь. Сам jQuery как минимум с версии 1.4 уже модулен по структуре своей. Читайте форум разработчиков, спрашивайте…
нда? надо будет покурить исходники.
но тогда удивительно почему:
1. не сделали выбор компонентов для скачивания, как в jQueryUI
2. Closure compiler не выкидывает неиспользуемые функции (а ведь он проверяет, вызывается ли данная функция хоть где-то и если нет — удаляет. в тесте с простейшим скриптом в пару строк под jQuery — все равно ядро остается в полном сборе)

вообще, после беглого взгляда на исходники я тоже подумал что его разобрали на модули, но вот вышеуказанные пункты остановили от дальнейших «раскопок»…
Был я когда-то велосипедостроителем, но понял, что везде тоже не дураки сидят…
Лет 15-20 назад я слышал немало криков на счет того, что программировать на Pascal и даже C++ это все дурной тон. Ведь после компиляции генерируется столько избыточного кода. И этот код не оптимален. А все серьезные вещи должны писаться исключительно на ассемблере.
Согласен, на ассемблере код получается компактнее и быстрее (при условии весьма высокой квалификации программиста). Но вот соотношение цены/качества такого кода никуда не годиться.

Тоже самое и здесь. Мы тащим кучу дублирующего и ненужного кода подключая кучу библиотек. Но это позволяет быстрее сделать проект. Да используем разнородные библиотеки, но это позволяет использовать опыт разных участников команды.

Если очень надо сделать супероптимизированный проект, можно и все с нуля написать на голом Javascript, только вот окупиться ли он? И вообще, я считаю что оптимизацией надо заниматься только тогда, когда в этом действительно возникает необходимость, а иначе это педантство и растрата рабочих часов. Меня умиляет когда потратив пару недель люди оптимизируют скорость работы web GUI в 10 раз сократив время отклика с 100мс до 10мс. Это что, сильно заметно для пользователя? Или добиваются уменьшения нагрузки на сервер сайта на которым дай бог 100 посетителей в день.
А почему *отключенный* кеш мог стать проблемой в принципе? Может, вы где-то баг сделали, а вместо его фикса решили юзеру сообщение выводить?
Проблемой я называю неоправданно долгую загрузку страниц сайта. Разработчики браузеров предоставили возможность сохранять часть содержимого страницы, и тем самым увеличить скорость загрузки. Отключенный кэш браузера — этой возможности лишает. В этом и заключается проблема.
зачем тут нужна обработка «304 Not Modified»?
Нажмите F5 — браузер будет делать запрос игнорируя expires полученые от первого ajax запроса
Впрочем, я вновь буду только рад, если вы предложите решение без 304 Not Modified
то есть он сделает два запроса независимо от поддержки кэширования? думаю тогда он посылает заголовки типа «Cache-Control: max-age=0» — тогда стоит всегда отдавать одинаковое значение
Если мы будет отдавать всегда одинаковое значение, то как разобраться — одинковые они из-за кэша или нет…
ну да, при отключённом кэше он не будет посылать заголовков позволяющих 304…
А что будет, если второй асинхронный $.get() запрос отработает быстрее первого? :-)
И что будет, если первый и второй запросы придут в разные секунды? Тогда @strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $timeStamp не выполнится
Это я к тому, почему бы проверяемый таймштамп не брать из строки запроса?
Но выполнится HTTP_IF_NONE_MATCH
Это если он передаётся. Если вы полагаетесь только на HTTP_IF_NONE_MATCH — тогда зачем вообще пляски с HTTP_IF_MODIFIED_SINCE?
И напоследок: если 2 запроса $.get() асинхронные и выполняются долго, тогда как во втором появится етаг или иф_модифед_синс, если второй был запущен ДО ТОГО как результаты первого запроса упали в кэш
В теории можно представить себе такую ситацию. Если вы считаете ее достаточно вероятной, то можно вызывать второй запрос из callback'а первого или использовать для этого возможности js фреймворка. В mootools к примеру есть оция link:'chain', которая решает эту проблемму mootools.net/docs/core/Request/Request
не можно, а нужно.
Добавил изменения в пост. Спасибо
Всё равно — мои замечания выше, в случае если они справедливы (а я почти уверен, что так и есть), указывают на серьёзные недочёты в реализации (я про запрос в разные секунды — для этого не обязательно запросу выполняться дольше 1 секунды)
а вот я к примеру попробовал код в своей Opera.
результат чередование сообщений. То кэш доступен то кэш надо включить.
не очень понял результат моей проверки…
Похоже, что это баг. В том проекте, где я это применил использовались только IE и FF.
Я сейчас протестировал в других браузерах. Сhrome — работает, а вот Opera и Safari, похоже не хотят. Друзья, буду рад вашим комментариям, касательно того, как можно добавить поддежку этих двух браузеров.
При выключенном кеше FF не отправляет заголовок If-Modified-Since в запросе к серверу. Теоретически это можно обыграть и ограничиться одним запросом на проверку, вместо двух.
Первый запрос тоже не отправляет if-modified-since даже при включенном кэше, мы ведь еще не получали этого контента раньше
Да, вы правы :)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации