Pull to refresh

Comments 136

Чем каждый раз «апдейтиться» проще использовать Google API и загружать оттуда библиотеки по мере необходимости. Например загрузка последней версии первой ветки Jquery + UI будет выглядеть так:

<script src="https://www.google.com/jsapi"></script><script>google.load("jquery", "1");google.load("jqueryui", "1");</script>
С одной стороны да, а с другой стороны, в каждой новой мажорной версии что-то становится deprecated, и если за этим не следит, поломает сайт.
Вот меня всегда интересовало, есть инструменты, которые могли бы проанализировать скрипты, и сказать заведутся ли они на «последней версии» jQ?

Очень не хочется возиться с кодом доствшимся в наследство
В общем случае — это невозможно (если не считать инструментом программиста, который будет за этим следить).
Все ок, только при нажатии ссылки слишком мельтишит перед глазами надпись «Пожалуйста, подождите немного, контент загружается», во-первых, не успеваешь прочитать ее, во-вторых она как мусор. Чтобы прочитать ее, я быстро 500тыщ раз нажимал на ссылку. Я бы выбросил ее. А так — сайт аккуратный получается. Это первое впечатление.
Согласен, надо будет убрать. Просто, до того как занялся оптимизацией, страницы дольше грузились :)
Ставьте отображение надписи/анимации по таймауту в 500мс
А лучше отображать только если грузится более 500мс
И это… домен «вайсгол» — это такая еврейская фамилия? :)
В зоне .com не особо большой выбор, пришлось фантазировать :)
У меня одно время была мысль сделать похожее поведение но немного иначе. Любая страница сайта имеет очень упрощенный HTML синтаксис только с основным контентом и навигацией. При загрузке страницы уже скриптом навешиваются все «фантики» типа слайдеров, сайдбаров, хидеров и футеров, т.е. весь неизменяемый декор-контент страницы строится скриптом. В этом случае нам по идее не нужно «выдирать» кусок страницы с контентом на сервере, а мы грузим всю страницу целиком — лишнего там ничего не должно быть и уже на стороне клиента встраиваем в интерфейс.
Поздравляю вы почти изобрели клиентский шаблонизатор :)
Не… шаблонизатор, как я понимаю (исправьте, если ошибаюсь), это все же ближе к методу формирования HTML из «сырых данных» типа JSON или XML. Идея немного в другом. Мы имеем на сервере нормальную HTML страницу, которую бот поисковой системы может нормально проиндексировать и пройти по указанным в ней ссылкам, однако в ней отсутствует вся та «визуальная шелуха», что мы обычно привыкли видеть на странице — шапка, футер, сайдбар — именно эти элементы и формируются скриптом. И когда мы переходим в браузере на такую страницу в первый раз она нормально загружается с сервера и инициализирует так называемый UI сайта, типа декорирует контент для нормального и привычного использования. А вот когда мы с этой страницы делаем переход на другую страницу этого же сайта, то мы грузим ту же страницу в HTML, но уже не инициализируем UI, а просто берем контент и встраиваем в уже готовый UI. Это более комплексная идея чем просто шаблонизатор. В этом случае нам не нужно нагружать сервер детектом, что это за запрос AJAX или нет и отдавать в зависимости от этого разный контент. Тут хватит и обычного статического сайта без всякой серверной логики.
Дело в том, что я старомоден и люблю статические сайты, а JavaScript и современные браузеры позволяют создавать решения, которые выглядят весьма современно. В процессе работы над второй версией WebProject-а у меня возникала идея сделать шаблон сайта с использованием этого принципа. Однако, чуть позже меня захватила идея другого продукта из этой же области, в котором я запланировал это сделать. Т.е. тут дело больше в моей привязанности и любви к статике.
Идея, несомненно, неплохая. По сути, вы предлагаете эмулировать дополнительный UI браузера.
Скорее не браузера, а UI сайта.
Который, в идеале, был бы UI браузера, как это стало со всякими плейсхолдерами и валидируемыми инпутами.
Да, соглашусь. Вообще говоря, это похоже на то как десктопное приложение строит UI вокруг модели реализующей основную логику. В логике приложения мы же не описываем интерфейс, это другая задача. Так и тут — оставляем в HTML основной контент страницы и ссылки для описания топологии сайта, а все остальное навешиваем скриптом.
Зачем параметр ajaxLoad если проще отслеживать заголовок ajax-запроса?
$_SERVER['HTTP_X_REQUESTED_WITH'] == 'xmlhttprequest'
Согласен, так будет лучше, почему-то даже не задумывался об этом…
Не все браузеры передают этот заголовок. Это ненадежно. Тот же ВК использует аналогичный метод навигации, и там передается параметр ajax=true
Какое отношение вообще имеют браузеры к этому заголовку? Его может ставить библиотека. Насколько я знаю, заголовки поддерживают все современные реализации AJAX (ага, и IE 6), потому это надежно, не нужно вводить людей в заблуждение.

Т.е. надежнее отсылать параметр, который может быть затерт другим и, по сути, является мусорным? Я ни разу не слышал, чтобы кто-то волновался насчет надежности x-requested-with;
А почему POST, а не GET используете для запроса страницы?.. Ну и, как выше уже сказали, ajaxLoad совершенно не нужен.
Семантика описана в спецификации HTTP. Они просто для разных целей предназначены. GET получает ресурс, а POST добавляет ресурс в коллекцию.
Учту это, и пожалуй соглашусь, что лучше использовать GET, но честно говоря, я не считаю, что использование определенного метода так принципиально, и на чем-то может отразиться.
Если следовать архитектурному стилю REST, 4 базовых функций при работе с хранилищами данных, известные под аббревиатурой CRUD, отображаются (с оговорками) на методы протокола HTTP следующим образом:

CREATE -> POST
READ -> GET
UPDATE -> PUT
DELETE -> DELETE.

Такого рода соглашение помогает организовать полный согласованный доступ к ресурсам посредством протокола HTTP — то есть реализовать RESTful web API.
Не совсем.
PUT может использвоаться как для изменения ресурса, так и для его создания. Но URL, на котором будет ресурс определяется клиентом. Т.е. если послать PUT на url, на котором объекта нет (GET на этот url даст 404 ошибку), то после выполнения запроса там появится объект.
POST тоже может применяться для создания и для модификации. В случае создания, сервер вернет 201, созданный объект в теле, а также заголовок Link с rel=self и url, по которому доступен созданный ресурс. Но возможно и другое поведение: сервер может вернуть 200 и, например, дописать данные в конец текущего ресурса.

Также важный момент в том, что использование HTTP verbs не делает API RESTful. Это не самая важная деталь REST.
Я ж и говорю, с оговорками. Сам ознакомился со всеми этими принципами недавно, изучая ASP.NET Web API. Мне нравится, что после толпы технологий типа SOAP, XML-RPC и проч. теперь они говорят что-то вроде: «Это все пережитки прошлого, GET POST PUT DELETE можно сделать даже с калькулятора, они изменят вашу жизнь!»
А мне нравится то, что постепенно начинают использовать то, что было заложено в HTTP более 12 лет назад. :-)
http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
В соседних главах также можно посмотреть, какие требования предъявляются к архитектуре сетевых приложений, какие существуют подходы и почему был выбран именно REST.
UFO just landed and posted this here
Ну и добавлю ещё одно отличие: POST-запрос сам по себе тяжелее в обработке для веб-сервера (экономия на спичках)
Отчего же он тяжелее, если технически отличается от GET'а другой строкой в заголовке method и тем, что параметры записаны не в url, а в теле запроса, причем в том же самом виде.
Вот только GET запросы кешируются, а POST нет.
Вы сами ответили на свой вопрос: «тем, что параметры записаны не в url, а в теле запроса». Обработка происходит не только заголовков как в GET, но и тела запроса
Только обработка тела запроса стоит столько же, сколько разбор url'а у GET'а + стоимость проверки того, что content-type равен application/x- www-form-urlencoded. При этом, так как в url параметров уже нет, парсить нечего. Так что затраты одинаковы.
На одну букву меньше.

GET — получение данных с сервера
POST, PUT, DELETE — изменение.
UFO just landed and posted this here
POST-запросы не кэшируются браузером, что в вашем случае не приемлемо.
По сути Вы описали в точности pjax, насколько я понял?
UFO just landed and posted this here
PJAX — это конкретная библиотека, которая минимальными усилиями превращает практически любой работающий статически сайт в динамический, обрабатывая нажатия на ссылки и отправки форм. В итоге получается ровно то же, что и у вас. Она существует практически с момента появления pushState. Лично я чуть больше года назад разрабатывал адаптированную под реалии IE версию, которая работала и без History API — habrahabr.ru/post/123972/.

Кстати, я невнимательно просмотрел статью, или вы не обрабатываете формы?
UFO just landed and posted this here
Да, спутал. Но вопрос автору остался.

А название не имеет значения. Короткое, запоминающееся и self-explaining — вот и весь предел мечтаний. Встречный вопрос: а почему веб-технологии стремятся подражать именам героев древнегреческого эпоса? :) Ясон, Аякс…
UFO just landed and posted this here
«Asynchronous Javascript and XML» против «JavaScript Object Notation»

Думаю, вы неправильно оценили степень подгонки этих названий. AHTTPR ему суждено было именоваться.
UFO just landed and posted this here
Когда я думал о внедрении аякс в систему навигации, то не особо задумывался о существовании подобных библиотек, так как реализовать такой подход в моем случае было очень просто. Выходит создал велосипед :) но на моем сайте этот велосипед немного расширен, и вариант с PJAX мне бы не особо подошел.

В любом случае, думаю мой маленький скрипт лишним не будет.
Плюс за то что разобрались как реализовывать и сделали решение. Минус за то, что это велосипед не лучшего качества, и если бы вы потратили 10 минут на гугление, нашли бы готовые варианты (более архитектурно правильные и которые учитывают множество нюансов)
Моей целью не было предоставить какое-то инновационное решение, с учетом мелочей, которые не будут заметны пользователю (это я об архитектуре). Я лишь описал свой опыт и показал простой в реализации подход, который использовал на своем сайте, с небольшим количеством кода и необходимым мне функционалом, в надежде на то, что кому-то это поможет.
я делал немного по-другому. Создаем обычный сайт с обычными ссылками. Потом проходим по ссылкам скриптом и превращаем их href в хеши например так: /page/ -> #page/. При клике перехода не происходит, меняется хеш в адресной строке, заодно прописывается в историю браузера.
А за изменениями хеша следит событие hashchange (гуглится по этому названию или пишется следящая по setInrerval функция).
Хеш поменялся — берем его, откидываем # и грузим страницу по получившемуся адресу. Можно и целиком, потом выдрать из нее нужный кусок и вставить в контент (я ленивый так и сделал, можно и комбинировать с заголовком $_SERVER['HTTP_X_REQUESTED_WITH'] == 'xmlhttprequest').
Так работает роутер в jQuery Mobile.
Им и вдохновлялся)
неприятный недостаток в том, что если соединение пропало или сервер просто не успел ответить, то адрес у страницы пользователя уже поменяется, а страница так и останется такой же как и была, пользователь начинает тыкать по той же ссылке, что и раньше, но изменение хэша не происходит и поэтому не происходит ничего.
у меня так часто бывает с фейсбуком

ещё, понятно, нужно следить, не понатыкал ли пользователь по десятку ссылок и если понатыкал, то обрабатывать только последнее изменение хэша
Недавно сам написал похожее. Кстати, лучше бы сделать моментальную прокрутку страницы вверх после нажатия ссылки. Сейчас нажал ссылку где-то посередине страницы, контент загрузился, пришлось прокручивать страницу вверх.
MySQL Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') ORDER BY `type` ASC, `date` DESC' at line 3
Query: SELECT `supersearch`.* FROM `supersearch` WHERE `id` IN () ORDER BY `type` ASC, `date` DESC
А для чего это сделано? Вы подменяете стандартные функции броузера, добавляете костыли для поисковиков, ломаете привычный user-experience и отходите от стандартного HTTP. А взамен что? Экономия трафика за счет того, что страницы скачиваются без header и footer? Или в чем ваша цель?
Какие костыли для поисковиков? Какие стандартные функции браузера я ломаю? Вы вообще о чем, уважаемый?
Костыли для поисковиков в необходимости держать отдельную ветку алгоритма, чтобы отдавать «по старинке» полную версию страницы. Стандартные функции броузера — кеширование, история посещений, букмарки и т.д. Для всего этого вам пришлось писать дополнительный код. Возможно, вы достаточно хорошо свой код протестировали и он работает во всех без исключения броузерах так же, как работал бы стандартный HTTP/1.1.

Но все-таки, в чем была конечная цель?
Где вы увидели отдельную ветку алгоритма? Стоит отцепить всего один файл navigator.js, и сайт будет работать как обычно, так же видят сайт и поисковики. Все что происходит — перехватывается клик пользователя, и подменяет один метод, на другой.

В чем конечная цель? По-моему это очевидно — скорость, есть ещё несколько преимуществ. С этой же целью, такую систему внедрили себе facebook и vkontakte. Они наверное тоже идиоты, и просто ради забавы всунули ajax-навигацию :)
facebook и vkontakte делают мягко говоря значительно больше.

VK — часто передает компактный json, а HTML — как маленькую часть страницы, активно использует localStorage. По сути, это реализация кеширования результатов без необходимости держать кэш на сервере. Ну и переход по страницам без прерывания проигрывание музыки и видео, что для VK довольно важно.

И, кстати, я заметил, что переход на не закешированные страницы (без проигрывателя) у него через полную перезагрузку.

Так что у вас никакой не аналог VK, а так, чуть лучше чем pajax (так как не грузятся хедеры/футеры), но так или иначе для быстрой загрузки страниц на обычном сайте достаточно оптимизировать скорость отдачи страницы, сжимать и склеивать css и js и не напороть с заголовками. Ну или уже идти до конца и грузить часть сайта в JS, что бы ходить по этой части уже без каких-либо сетевых задержек, с асинхронными запросами на статистику и тому подобное.

Так удобно делать для магазинов: загружать первую страницу категории, а остальные товары подтягивать ajax-ом в json и потом уже фильтры и просмотры товаров из памяти в JS.

Но это для новых браузеров и не для смартфонов. Хотя на среднем компьютере на V8 все отлично и на 10 К товаров, но проблема в тормозах на клиентской стороне — это все-таки проблема, я даже думал как-то замерять производительность и использовать тот или иной способ в зависимости от результатов или экспериментировать в сторону IndexedDb/Web SQL. Хотя проблема даже в самом шаблонизаторе, а массивы данных, обычно, не такие большие. В общем, тут хватает тем для исследований и профит очевиден, в отличие от аналога pajax.
Зря Вы советуете клацать по ссылкам, когда у Вас при клике по этим ссылкам вылазит подобное:
MySQL Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
Query: UPDATE `notifier` SET `closed` = true WHERE `message` LIKE '%«type»:«friend»%' AND `user` =
Гостевой сеанс.
Я советовал клацать по ссылкам навигации и по странам только, и написал, что сайт в разработке. Я знаю про эти баги, но показать хотел просто работу навигационного меню.
Просто предупредил на всякий случай. :)
Спасибо, мне уже около 3 таких сообщений пришло в личку, только что поубирал все ошибки SQL)
Интересно, а как насчет гугл-аналитикс? Вижу что прикручен, но корректно ли он собирает статистику при таком подходе?

А так вообще нормально. Но всё же не хватает после клика анимации загружаемой страницы, тут получается либо вы все время спамите посетитя каким то объявлением о том что страница загружается, либо нет обратной связи — кликнул и тишина

Выключил JS, покликал — понял, что мне так удобнее все равно )) но наверно это моё личное
В моем случае гугл-аналитикс работает только тогда, когда на сайт заходят напрямую, так какподключается он в основном шаблоне, но нет никаких сложностей в том, чтобы исправить это, и просто подставлять на стороне сервера код для остальных шаблонов, хотя по-моему достаточно и статистики заходов)
А как реализовано устаревание кэша? Или его тут нет?
Устаревание кэша? А здесь-то это зачем нужно? Это кратковременный кэш истории, и хранится пока пользователь на сайте :)
Написал подобную систему в одном своем проекте. Тоже перехват ссылок через live, и тоже все работает при отключенном javascript. Но у меня сложнее получилось, чем у вас — делал под ie и до history.pushState. Поэтому пришлось бороться с хешами.

Еще у вас заменяется только основной контент. Кроме него в обвязке только меню, которое очень легкое. Поэтому в сумме прирост небольшой — что вы контент загрузите, что контент + шапку, разницы особой нет. У меня была соцсеть из кучи блоков, и прирост был существенный, поскольку многие действия жили внутри своего блока, и перегружался только он сам.

Но там пришлось писать довольно объемный код. Блоки допускали вложения друг в друга. Ясное дело, что грузить аяксом один блок, потом понимать, что в него вложены другие, и делать следующие ajax-запросы, никуда не годится. Нужно грузить все сразу. Т.е. если в блок вложены другие, нужно на сервере это понимать и за раз отдавать все что вложено. А что и во что вложено — само собой указано для javascript-а в тегах. Короче пришлось на сервере написать небольшой html-парсер.
Помнится лет 5 назад писал сайт c полноценным редактированием контента в ajax (админка) и полной навигации на ajax, все с помощью jquery. Если отрою скину сюда код
Думается мне, 5-летний код в условиях веб уже не актуален. Вот если бы вы какими-нибудь научными расчетами занимались… Большинство физиков до сих пор на Фортране'70 переваривают древние программы :)
Ок, отрыл, кидать не буду :)
Вы не обрабатываете ошибки. Контент в браузере должен обновляться только по ajax#success
Сайт работает классно. Только учтите, что .live() — это .on в новых версиях jquery. Сейчас live deprecated, а кто знает, будет ли эта функция после обновления?
Все классно, но кэш работает только для кнопок вперед и назад. Если же просто перейти на посещенную ссылку, контент запрашивается с сервера заново. Хотя это можно было бы обойти и выдавать уже ранее закэшированный ответ.
Если содержимое страницы изменилось, как это отслеживается?
 $('.navigation-menu').live("click", function(){	
      setPage($(this).attr('href'));
      return false;
  })

Я конечно плохо разбираюсь в jquery так как пишу на чистом JS и если я буду не прав поправьте меня.
Но как я понял код выше вешает обработчик на каждую ссылку на странице, что является маразмом (ИМХО), со стороны производительности лучше использовать делегирование .
К примеру так:
$("body").on('click', onLinkClick);
      
      function onLinkClick(e) {
      
       var target  = e.target;
        
       if(target.className != "navigation-menu") return;
        
     alert($(target).html())
        
      return false;
      }   
live как раз так и работает, через делигирование, в отличик от .bind, который цепляется конкретно к элементам, существующим на момент вызова.
1. для получения данных нужно использовать GET, а не POST, но не потому что CRUD, REST или ещё какая аббревиатура, а потому что кэширование. советую почитать про заголовок Cache-Control. При этом урл является ключём кэша.

2. параметр в урле лучше, чем просто http-заголовок. потому что ответы сервера разные. а урл является ключём кэша. как вариант можно в ответе прописать «Vary: X-Rrequested-With», чтобы этот заголовок тоже попал в ключ, но зачем, если есть возможность изменить сам урл? ещё и в логах сервера аяксовые и обычные запросы будут отличаться урлами, и не надо будет шаманить с добавлением заголовка и туда.

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

4. добиться высокой скорости можно гораздо более простыми и стандартными способами. освойте http-кеширование и грузите по отдельности те данные, что имеют разную степень актуальности. например, навигацию(если она большая конечно) нужно грузить отдельно от содержимого страницы. и не нужно никаких костылей.
1. для получения данных нужно использовать GET, а не POST, но не потому что CRUD, REST или ещё какая аббревиатура, а потому что кэширование. советую почитать про заголовок Cache-Control. При этом урл является ключём кэша.

Вы подменили следствие и причину. Надо использовать GET потому, что у него семантика немодифицирующего запроса. Это то, о чем говорит REST и CRUD. А возможность кэширования — следствие этой семантики.
2. параметр в урле лучше, чем просто http-заголовок. потому что ответы сервера разные. а урл является ключём кэша. как вариант можно в ответе прописать «Vary: X-Rrequested-With», чтобы этот заголовок тоже попал в ключ, но зачем, если есть возможность изменить сам урл? ещё и в логах сервера аяксовые и обычные запросы будут отличаться урлами, и не надо будет шаманить с добавлением заголовка и туда.

Про заголовок Vary замечание ценное, он действительно необходим для того, чтобы кэширование работало правильно. А вот вывод сделан неправильный. Размещать объекты на одном url или на разных зависит только от их семантики. Если это один и тот же ресурс, просто в разных представлениях, то только на одном URL. В этом случае работает HTTP content negotiation. Если же смысл разный, то на разных url. Иначе писать серверное ПО становится сложно.
Отступление от этого правила может оправдываться только отсталосью клиентского ПО в виде неполной поддержки протокола HTTP. Например, если ресурс доступен на нескольких языках, то все переводы должны быть на одном и том же URL, но ни один браузер на текущий момент не умеет определять, на каких языках доступен ресурс и переключаться между ними. Приходится усложнять логику сервера и реализовывать выбор языка на серверной стороне.

По остальным пунктам возражений не имею.
это ты путаешь курицу и яичницу) семантика GETкак раз и введена для того, чтобы можно было кэшировать ответ сервера, а не ломиться на него каждый раз. а CRUD — это вообще о другом. CRUD — абстракция над реляционной моделью, которая сильно проще сетевой. в частности, не хватает таких методов как HEAD, MOVE, COPY, LINK и других.

это только в сферическом вакууме возможен прямой маппинг ресурсов на модели с указанием отображения в заголовках. но эта абстракция сразу начинает течь, попав в реальный мир:
1. отсылка одной формы должна быть произведена за один запрос к одному ресурсу, а не за десять к десяти, не смотря на то, что фактически она изменяет не один ресурс, а десять.
2. нужно предоставлять пользователю возможность получать данные в разных представлениях. требовать от браузера поддержки всех возможных на всех сайтах видов представлений — наивно и глупо. например, диаграмма может быть представлена в виде разноцветного отрезка (нужно указать ещё и его длину), может ввиде круга (нужно указать диаметр или габариты), а может ввиде цилиндра (тут надо указать углы поворота в 3д, степень удаления и габариты области просмотра). а задачей content negotiation является обеспечение доступности, а не предоставление выбора. в примере с диаграммами — для цилиндра выбор между jpeg растром и vrml моделью. но как ты заметил, современные html технологии плохо для этого предназначены.
это ты путаешь курицу и яичницу) семантика GETкак раз и введена для того, чтобы можно было кэшировать ответ сервера, а не ломиться на него каждый раз.

Кажется вы не в теме. Попробуйте почитать литературу. Для начала сравните спецификацию на HTTP 1.0
www.w3.org/Protocols/HTTP/1.0/spec.html#GET
И спецификацию HTTP 1.1
www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3
Обратите внимание, что в версии 1.0 кэширование почти не описано. Не успели проработать. Зато оно подробно описано в 1.1. Теперь посмотрите на список авторов стандарта. Найдите там автора вот этой докторской диссертации:
http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
А также сравните даты публикации. Эта диссертация по сути описывает то, как разрабатывался HTTP, какие соображения при этом применялись и как он должен работать.
HTTP — описание протокола
REST — описание, как использовать HTTP

Разрешение на кеширование запроса GET является следствием того, что он не изменяет состояние сервера.
1. отсылка одной формы должна быть произведена за один запрос к одному ресурсу, а не за десять к десяти, не смотря на то, что фактически она изменяет не один ресурс, а десять.

Значит вы неправильно выделили сущности, сделали их слишком мелкими. Ресурсы веб-сервера не обязаны совпадать с ресурсами в БД.

нужно предоставлять пользователю возможность получать данные в разных представлениях. требовать от браузера поддержки всех возможных на всех сайтах видов представлений — наивно и глупо. например, диаграмма может быть представлена в виде разноцветного отрезка (нужно указать ещё и его длину), может ввиде круга (нужно указать диаметр или габариты), а может ввиде цилиндра (тут надо указать углы поворота в 3д, степень удаления и габариты области просмотра).

А теперь самое главное, скажите, откуда эта куча представлений? Вы хотите сами выбирать нужное представление или предоставить такую возможность пользователю. Если первое, то это разные, не взаимозаменяемые ресурсы, у них разная семантика, а значит разные URL. Если же выбор должен делать клиент, то для этого предназначен content negotiation. И он уже частично поддерживается браузерами. Кстати, обратите внимание на HTTP код «300 Multiple Choices».
А задачей content negotiation является обеспечение доступности, а не предоставление выбора.

RTFM!
www.w3.org/Protocols/rfc2616/rfc2616-sec12.html#sec12

P.S. Также обратите внимание, что браузеры — не единственныйе HTTP клиенты. И. если речь идет про HTTP API, то требовать от клиентов полноценной поддержки HTTP вполне можно.
ох… ну давай читать спеки вместе…

www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.1

The requested resource corresponds to any one of a set of representations, each with its own specific location, and agent- driven negotiation information (section 12) is being provided so that the user (or user agent) can select a preferred representation and redirect its request to that location.

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

далее, совершенно не важно в какой стпени в каких спеках описано кэширование. да хоть оно вообще нигде не было бы описано — совершенно не важно. важно то, что введение ограничения «немодифицирующие запросы, надо помечать специальным словом GET или HEAD, если BODY не нужен» введено ИСКЛЮЧИТЕЛЬНО для того, чтобы можно было легко и быстро определять что можно кэшировать, а что не стоит. если бы не эта причина, формулировка была бы куда проще: get — просто получение данных, будь там хоть рандомайзер.

а при чём тут бд? допустим я хочу сделать обновление ресурсов сайта посредством посылки архива с исходниками на определённый ресурс. посылаю на один — изменяются многие другие. в вебе это повсеместное явление. или мисье теоретик?)

не хочу я чтобы рсс читался у меня спрашивала не только ссылку на поток, но и список необходимых заголовков, чтобы получить именно поток, а не хтмл страницу. и не надо говорить про стандартизацию, с ней всё очень плохо в современном вебе.
Юох… ну давайте читать спеки вместе…

Я люблю читать спеки вместе. Давайте.
www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.1

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

Может вместо того, чтобы писать домыслы, стоит прочитать определение ресурса из секции 1.3?
www.w3.org/Protocols/rfc2616/rfc2616-sec1.html#sec1.3
Там сказано, что ресурс идентифицируется своим URI. Кроме того, я вам дал ссылку на первоисточник — диссертацию Роя Филдинга. Там понятие ресурса дано более строго. Кажется, вы её так и не прочитали.

То же, что написано в секции 10.3.1 — данность истории. Нельзя так просто ввести в HTTP 1.1 понятие content negotiation и сразу же сказать, что то, как было раньше — неправильно.

это только в сферическом вакууме возможен прямой маппинг ресурсов на модели с указанием отображения в заголовках. но эта абстракция сразу начинает течь, попав в реальный мир:
1. отсылка одной формы должна быть произведена за один запрос к одному ресурсу, а не за десять к десяти, не смотря на то, что фактически она изменяет не один ресурс, а десять.

Значит вы неправильно выделили сущности, сделали их слишком мелкими. Ресурсы веб-сервера не обязаны совпадать с ресурсами в БД.

а при чём тут бд? допустим я хочу сделать обновление ресурсов сайта посредством посылки архива с исходниками на определённый ресурс. посылаю на один — изменяются многие другие. в вебе это повсеместное явление. или мисье теоретик?)

Чтобы ответить на этот вопрос нужно восстановить контекст обсуждения. Вы утверждали, что при «прямом маппинге ресурсов на модели с указанием отображения в заголовках» для многих дейтсивй нужно будет выполнять много запросов, вместо одного. Такая ситуаций говорит о том, что список объектов предметной области был плохо продуман и вы ооперируете слишком мелкими объектами. Надо было объединить их в более крупные. БД тут при том, что базы данных заточены под оперирование мелкими объектами и, если переносить объектную модель БД в объектную модель HTTP API, как раз получатся мелкие объекты.

И тут вы вдруг говорите: «допустим я хочу сделать обновление ресурсов сайта посредством посылки архива с исходниками на определённый ресурс». Бинго. Вы выделили крупный ресурс «коллекция ресурсов сайта», определили для него PUT запрос (который имеет право обновлять, а не замещать ресурс) и у вас получился простой HTTP API. Поздравляю, вы выделили сущности, соответсвуюшие вашим потребностям.

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

Логично, что вы этого не хотите. Где сказано, что должно быть иначе? Заголовки — это не из предметной области пользователя, поэтому их спрашивать никто не будет.
рсс читалка… список необходимых заголовков, чтобы получить именно поток, а не хтмл

А разве RSS читалка не будет запрашивать с сервера именно RSS или atom feed? Она же ничего другого отображать не умеет. Вам не надо ничего дополнительного указывать. И язык вашей системы она и так знает, передаст Accept-Language: RU-ru, ru,q=0.9, en=0.8. Сервер выдаст страницу на русском языке. Более того, в atom feed может быть информация о том, что он доступен на других языках. Хорошая читалка должна бы ненавязчиво предложить выбор. Вас же не смущают ссылки на другие языки на многоязычных сайтах? Это же не ручное указание заголовков?

далее, совершенно не важно в какой стпени в каких спеках описано кэширование. да хоть оно вообще нигде не было бы описано — совершенно не важно. важно то, что введение ограничения «немодифицирующие запросы, надо помечать специальным словом GET или HEAD, если BODY не нужен» введено ИСКЛЮЧИТЕЛЬНО для того, чтобы можно было легко и быстро определять что можно кэшировать, а что не стоит. если бы не эта причина, формулировка была бы куда проще: get — просто получение данных, будь там хоть рандомайзер.

Кажется тут именно так и написано:
www.w3.org/Protocols/HTTP/1.0/spec.html#GET
А кэширование появилось уже в 1.1.
С айпада в сафари все работает нормально, в меркури — невозможно войти гостевой сессией.
Идея класс, сайт работает быстро даже на дохлом канале.

В восьмом IE в анонимной сессии вылетают ошибки.
> Сайт на аякс работает в разы быстрее любого обыкновенного сайта, и даже если учитывать кэш браузера, это заметно.

Голословное, ничем не подтвержденное утверждение. Особенно, если учесть, что ajax — это те же HTTP-запросы, с какого перепугу сайт должен быть в разы бытсрее, неизвестно.
Это толкьо если мы говорим о субъективном восприятии. Говорил ли о нем автор топика?
Субъективное восприятие — одна из главных характеристик интерфейсов вообще, и сайтов в частности. Но, кроме субъективного ускорения ajax дает возможности и для объективного.

С обычной навигацией по страницам все стандартно — отображается пустая страница (или предзагруженная в сафари), бежит прогресс-бар, идет отображение страницы. Это может быть сильно заметно на медленных соединениях. Из средств ускорения только prefetch/prerender (снова не во всех браузерах). С аяксом же сайт может более гибко управлять кэшем и предзагрузкой, показывать красивые карусельки пока соединение тупит, и т.д. И работать это уже будет в большинстве браузеров.
Боже, какая каша в голове.

Но, кроме субъективного ускорения ajax дает возможности и для объективного…

отображается пустая страница (или предзагруженная в сафари), бежит прогресс-бар, идет отображение страницы… С аяксом же сайт может… показывать красивые карусельки пока соединение тупит


Это, извините, полный аут.

> С аяксом же сайт может более гибко управлять кэшем и предзагрузкой

Что именно вы называете «управление кэшем и предзагрузкой»? А то я аж даже уже боюсь представить
Под «управлением кэшем и предзагрузкой» я подразумеваю (сюрприз!) кэширование данных и их загрузку до необходимости отображения пользователю.

Поясню на примере интерфейса gmail:

1). Кэширование: список сообщений в папке загружается (и заставляет пользователя ждать) один раз. Если Вы откроете другую папку, а потом решите вернуться в предыдущую — она мгновенно откроется из кэша.

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

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

О, уже теплее

> Если Вы откроете другую папку, а потом решите вернуться в предыдущую — она мгновенно откроется из кэша.

То есть, по вашему, если я открою 10 папок, ПЬфшд будет держать в памяти список для 10 папок?

> При клике на любое письмо из списка открывается заранее загруженная цепочка писем.

То есть, по вашему, для каждого отображенного в списке письма GMail сразу загружает всю цепочку писем?

> С радостью помогу выйти из аута и упорядочить кашу в голове.

Каша не у меня в голове, совсем не у меня.
То есть, по вашему, если я открою 10 папок, ПЬфшд будет держать в памяти список для 10 папок?


Будет. Для современных компьютеров список из пары сотен элементов не проблема.

То есть, по вашему, для каждого отображенного в списке письма GMail сразу загружает всю цепочку писем?


Обычно полностью загружаются последнее письмо, а также отправленные и короткие письма. Для остальных грузится только краткая информация. В целом, там немного более хитрый алгоритм оптимизации загрузки.

И это все не по-моему, а на самом деле. Можете открыть gmail и попробовать, на медленном соединении это особенно заметно.
> Можете открыть gmail и попробовать, на медленном соединении это особенно заметно.

Заметно может быть и будет, но точно не в разы.

Открытие папки — http-запрос
Полностью загружаемое письмо — http-запрос
Загружаемые отправленные — http-запрос
И т.п.

Чудес не бывает, а ajax — не магия.
Заметно может быть и будет, но точно не в разы.

Вы не видели медленного интернета. На 3G разница в разы, на 2G — на порядок.

Открытие папки — http-запрос
Полностью загружаемое письмо — http-запрос
Загружаемые отправленные — http-запрос
И т.п.

Чудес не бывает, а ajax — не магия.

Никто и не обещал единорогов с радугой. И тем не менее, запросов и трафика меньше, чем в классической версии по двум причинам:

1. Не грузится вся страница — нет необходимости в передаче разметки документа и запросе стилей и скриптов. А каждый внешний файл на странице — отдельный HTTP-запрос, даже если сервер вернет 304.

2. Запросы можно склеивать. 3 предложенных Вами запроса можно упаковать в один, и получать и список писем, и цепочки за меньшее время.
> Вы не видели медленного интернета. На 3G разница в разы, на 2G — на порядок.

Понятно. Цифр не будет, будет демагогия.

> Никто и не обещал единорогов с радугой.

Да неужели? «разница в разы, разница на порядок»

> А каждый внешний файл на странице — отдельный HTTP-запрос, даже если сервер вернет 304.

И снова повторю: марш за парту, учить cache-control

> предложенных Вами запроса можно упаковать в один, и получать и список писем, и цепочки за меньшее время.

Итак, вы считаете, что упаквка ненужных запросов (цеопчки + отправленные + короткие) в один каким-то образом уменьшит количество передаваемых данных и увеличит скорость работы на порядок?

Нуну
И снова повторю: марш за парту, учить cache-control

Со сверстниками своими так разговаривайте. И учитесь думать, когда можно все кэшировать, а когда нет.

Итак, вы считаете, что упаквка ненужных запросов (цеопчки + отправленные + короткие) в один каким-то образом уменьшит количество передаваемых данных и увеличит скорость работы на порядок?

Учитывайте, что на 2G время пинга может быть секунда и более. Не представляете, как упаковка уменьшает трафик — читайте как работают JSON и gzip. В общем, курите доки до полного просветления.
> Со сверстниками своими так разговаривайте.

1. Возраст !== ум
2. Возраст !== автоматическое уважение
3. Аппелировать к возрасту в интернете?

> И учитесь думать, когда можно все кэшировать, а когда нет.

Я прекрасно знаю, когда и что можно кэшировать

> Не представляете, как упаковка уменьшает трафик — читайте как работают JSON и gzip.

Я прекрасно заню про упаковку. Это вы про нее не имеете представления, видимо. Толко что вы предложили на заведомо медленном соединении подгрузить человеку дикое количество ненужной ему (на медленной связи особенно) информации. И рассказываете сказки про «на порядок более быструю работу». Нуну.

Зависит от того, какой подход выбрать. Разумеется, если перезагружать страницу полностью — толку ноль, но с помощью аякса можно грузить лишь нужную часть контента, а не весь контент. И как бы кто не старался, добиться того же, с полной перезагрузкой страницы нельзя, и никакие танцы с бубном в nginx и т. д. не помогут.

Этого можно добиться, только если страница не будет грузить ни картинок, ни скриптов ни стилей.
Пойдите выучите, что такое Cache-Control Headers, наконец, а? Все скрипты, картинки и CSS спокойно будут взяты браузером из кэша. Никакого «в разы» в ajax'е не будет. По банальной причине, что ajax — это точно такие же HTTP-запросы и reflow/rerender страницы.

Весь этот «в разы» — это всего лишь субъективное восприятие, которое, безусловно, важно, но к технической стороне вопроса имеет мало отношения.
Все идиоты кроме вас. Программисты Facebook зачем-то внедрили аякс-навигацию, наверное ради развлечения, или разработчиков занять не было чем. Вконтакте с той же целью это сделал. Зачем-то и Google последовал их примеру. Просто их разработчики, не понимают что такое Cache-Control Headers, посоветуйте им тоже выучить, вы ведь умнее, нас смертных.

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

Нет. Идиоты — те, кто кидаются громкими бездоказательными заявлениями. И те, кто вместо того, чтобы взять и что-то почитать или попытаться привести хоть какой-то аргумент в защиту такого заявления, начинают размахивать фейсбуками и какими-то абстрактными сайтами.

Еще раз повторю:
— Пойдите выучите, что такое Cache-Control Headers
— ajax — это точно такие же HTTP-запросы и reflow/rerender страницы.

Все остальное — это субъективное восприятие.
Никого не защищаю, но советую отыскать доклад разработчика vkontakte Игоря Илларионова на прошлом Highload. Он подробно объяснял про их загрузку страниц и систему навигации, зачем они сделали так, как сделали, для чего, что делали до этого, как в итоге работает сейчас (это конечно не ajax).
К сожалению, ссылку дать не могу, статья в закрытом доступе.
Если сможете найти открытую ссылку, поделитесь, пожалуйста.
> Он подробно объяснял про их загрузку страниц и систему навигации, зачем они сделали так, как сделали, для чего, что делали до этого, как в итоге работает сейчас

Ну, я примерно представляю, о чем они говорят, потому что их проблемы такие же, как у, например, фейсбука. Но найти их презентацию таки стоит, спасибо за совет
А, ну и да. Если вы считаете, что для ajax'а не нужны те же Cache-Control и прочие HTTP-приемы, то вы еще больший школьник, чем я предполагал.

Хотя, судя по этому комментарию
Забавно, вы не привели ещё ни единого логичного довода, зато успели назвать безосновательно меня школьником и идиотом (не прямо, но намёки были ясными). После этого у меня ещё меньше желания продолжать с вами разговор, но да ладно, чёрт с ним.

Напомните мне, когда я говорил, что Cache-Control — это плохо? Что-то я не припоминаю. Я говорил, что даже кэш браузера не может сравниться с подгрузкой части контента.

Мне куда интереснее, как можно так гибко кэшировать полнофункциональный динамический сайт, который обновляется каждую минуту, что это сравнится со скоростью подгрузки небольшой части контента с помощью аякс? Просветите меня, о великий!
> Забавно, вы не привели ещё ни единого логичного довода

Если вы неспособны понять, что ajax-запрос == обычный HTTP-запрос, и неспособны даже выяснить для себя, что такое cache control, redraw/reflow, то извините…

> Мне куда интереснее, как можно так гибко кэшировать полнофункциональный динамический сайт, который обновляется каждую минуту, что это сравнится со скоростью подгрузки небольшой части контента с помощью аякс?

1. Что именно меняется в сайте каждую минуту
2. Вы уже привели хоть одну цифру, подтверждающую свое голословное утверждение:
Меня всегда интересовало, почему при разработке сайтов, так редко в системе навигации используется Ajax? Ведь преимущества по-моему очевидны! Сайт на аякс работает в разы быстрее любого обыкновенного сайта

?
Нельзя кэшировать динамический регулярно обновляемый сайт целиком. Может обновиться список друзей, количество новых сообщений, добавлена новость или ещё что-то. Как вы себе представляете кэширование всего этого, когда сайт, меняется постоянно и в разных местах? На таких сайтах кэшировать можно без последствий только статику.

Да, можно сунуть полное кэширование на сайт-визитку, которая вообще никогда не обновляется, или небольшой блог, хотя даже блог кэшировать получится лишь отчасти, но так просто сунуть в кэш «живой сайт» нельзя, и все равно перезагрузка страницы будет тащить много ненужного — именно того, чего аякс тащить за собой не будет в любом случае. Это и есть преимущество в скорости.
> На таких сайтах кэшировать можно без последствий только статику.

Уже ближе. Дальше что?

Как из этого следует ваше голословное «работает в разы быстрее»?
В каком смысле «дальше что»? Перечитайте ещё раз комментарий, не знаю, что дальше.

Или вам нужны аналитические рассчеты? По-моему здесь все очевидно, и тот факт, что основной шаблон не загружается при использовании аякс (а в нем больше всего кода), уже говорит об уменьшении скорости загрузки. Не забывайте, что этот шаблон в сайте без аякса, грузится при каждом последующем переходе на иную страницу.
> В каком смысле «дальше что»? Перечитайте ещё раз комментарий, не знаю, что дальше.

> Или вам нужны аналитические рассчеты?

Мне нужно банальное подтверждение голословного утверждения

> По-моему здесь все очевидно

Нет, не очевидно. Банальная проверка цифрами покажет, что нет, не очевидно.

> что основной шаблон не загружается при использовании аякс (а в нем больше всего кода), уже говорит об уменьшении скорости загрузки.

В разы? На порядок? На сколько?

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

И?
Ах, да. Совсем забыл.

> Забавно, вы не привели ещё ни единого логичного довода

Вы имеете в виду доводы типа
Программисты Facebook зачем-то внедрили аякс-навигацию, наверное ради развлечения, или разработчиков занять не было чем. Вконтакте с той же целью это сделал. Зачем-то и Google последовал их примеру.


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

Извините, это — уровень ясельной группы дет. сада. Если вы неспособны этого понять, что вы делаете в программировании?
Какие к черту цифры? Как вы предлагаете измерить здесь что-то цифрами? Тут стоит рассуждать логично, и просто элементарно сравнить визуально, пусть это будет и субъективный взгляд.
> Какие к черту цифры? Как вы предлагаете измерить здесь что-то цифрами?

Просто. Вы же предлагаете заменить не-ajax на ajax. Все инструменты у вас есть — Firebug/Chrome Dev. Tools (которые даже показывают процесс отрисовки).

> Тут стоит рассуждать логично

Так рассуждайте. Пока что у вас детский сад в рассуждениях. «Очевидно» и «facebook так делает» — не логичные рассуждения.

Ajax-запрос является HTTP-запросом, он так же вызывает redraw/reflow страницы, статика и так кэшируется, а разница между 8 кб текста и 10 кб текста при передаче с включенным gzip'ом не будет заметна, основная проблема — это субъективное восприятие при перерисовке всей страницы — это логические рассуждения.
Кстати. Напомнило. Есть у меня сайт, erlanger.ru/ По данным Google PageSpeed оценка 90 из 100. Самое медленное на странице… Ajax! Подгружающий данные и вызывающий reflow страницы.
Пара ньансов:
— github загрузка контента таким же образом происходит практически мгновенно, как они этого добились? Или это просто так кажется из-за анимации переворачивания страницы?
— на больших страницах загрузка не через ajax визуально бывает быстрее, за счёт того что часть страницы начинает отображаться не дожидаясь полной загрузки страницы. Через ajax в таких случаях ожидание дольше, и может быть только одно решение — загрузка не в div а в видимый iframe. Но тут другая проблема — получить размер iframe по вертикали можно будет только после полной его загрузки, поэтому выходом тут может быть overflow hidden и iframe на 1200px, далее его динамический ресайз до реальных размеров (и дальнейшее отслеживание изменений).

Предлагаемый здесь вариант кэширование статических шапок и футеров в js тоже хорош, и я его использую на разных проектах, но у него есть недостаток — дёрганье страницы при перезагрузке, то есть сначала показывается белое меню, и только потом оно заполняет контентом, либо небольшое замедление рендеринга всей страницы если отображать меню по событию ready(), и в этом случае тоже бывает краткий рефреш страницы на белое полотно.
Кстати есть оказывается способ парсить загружаемые данные и динамически отображать их по мере загрузки через ajax — voracity.org/well/2011-06/progressive-rendering/, но там нет примера использования, и для загрузки используется скрытый iframe.
Парочка моих аналогичных разработок, но тут была строгая необхожимость не перезагружать страницу, т.к. воспроизведение музыки не должно прерываться. ( oplayer.org, lovi.fm, yugic.com )
В последнем проекте ( cherrysound.ru ) нужно было еще обновлять блоки из сайдбара, решилось сборкой всего html кода с определенными delimeter-ами, в которых зашифрованы ключи (айдишки блоков, которые нужно обновить и значения — html код блока).
И вместо доп. параметра (ajaxLoad) на сервере можно просто проверить или это ajax-запрос или нет.
А почему для всего этого не использовать логичный и понятный backbone.js например? Иначе, если задача немного усложнится, придется поддерживать тучу лапши-кода.
«Я решил ограничиться только History API и версией без аякса»

"$.post(page..."
блблблблблimage
Я решил ограничиться только History API и версией без аякса, чтобы не создавать для себя лишних проблем.
Ну если нужен аякс в ослике, это можно легко реализовать мною написанной библиотекой: habrahabr.ru/post/144071/
Не увидел писали ли выше об этом, но есть же очевидный баг
Если походить по сайту, насобирать историю в кэш и потом обновить страницу, то навигация кнопками назад/вперед естественно не работает
И live режет глаз конечно
      if (NavigationCache[event.state.page].length>0) {

хром сообщает об ошибке в яваскрипте Cannot read property 'page' of null

Может стоит и вовсе удалить этот if? Или он всё таки для чего то да нужен?
Sign up to leave a comment.

Articles