Задать вопрос

Каков секрет правильного ajax?

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

Подключать ajax на сайт получилось всего в несколько строк (перехватываем нажатие на ссылки, пару проверок и ):
history.pushState({}, "", $this.attr('href'));
var reload = $('#reload');


Работает, окей.

Предположим на первой странице у нас есть слайдер, или галерея, или select2 или еще что. Когда мы попадаем на эту страницу через ajax, нам нужно подгрузить скрипты этих самих виджетов. За счет чего появляются блики. Это не самое страшное, самое страшное, что вместе с html возвращаются js и css скрипты. И если их можно отфильтровать и не подключать по 20 раз, то в сам дом они всеравно попадают.

Я попробовал их вырезать регуляркой, перед обновление контента:
request = request.replace(/<script(.*)<\/script>/g,'');
            request = request.replace(/<link(.*?)>/g,'');
            reload.html(request);


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

Отсюда несколько вопросов:
1) Как правильно подгружать контент через ajax, который имеется собственные плагины, которые нет никакого смысла грузить всегда (а даже если и грузить всегда, представьте 20 плагинов, которые нужно постоянно рефрешить) ?

2) Даже если вести учет подключенных скриптов и не подключать дубли, всеравно в дом попадают копии этих же скриптов и стилей. На сколько это плохо ? (как я заметил, если их вырезать появляются проблемы, так вообще технически не мешают, но мысль о них не дает спать)
  • Вопрос задан
  • 931 просмотр
Подписаться 10 Оценить 6 комментариев
Пригласить эксперта
Ответы на вопрос 5
@Fellowship
Очень понравился вариант от DarkHole, но я бы вам на сервере, еще посоветовал, изучить GULP и просто миницифировать и собрать все css и js скрипты в один.
Пользователь, зайдя на страницу всего лишь один раз скачает все CSS и JS, а вы дальше по варианту DarkHole просто подмените body.

Это не самый лучший способ для очень крупных и разносторонних сайтов, но для небольших сайтов, где пользователь пройдя по 3-5 страниц и так скачает 80% всех стилей и скриптов, это просто сэкономит и вам время разработки и внешне сайт будет открываться быстрее, так как все уже будет лежать в кеше.
Ответ написан
VIKINGVyksa
@VIKINGVyksa
front-end developer
Вообще если вы делаите приложение на AJAX, то ваша архитектура должна быть похожа на SPA. А в нём первый запрос к серверу загружает приложение, которое настраивает себя, вешает все обработчики и тд. То есть вы подгружаите критический css и js просто как теги ("app.js и стили с лоудерами и главной страницей") а остальные просто ленивой подгрузкой в фоне. Так получаеться что пользователь быстро получает страницу которую хотел, но все зависимости подгружаються и для других страниц в фоне. В итоге когда вы будите переходить по страницам у вас будет меняться лишь контент.

Тот же самый backbone.js. В нём ваше приложение скачиваеться, создаёт модели(делает AJAX к серверу), передаёт во View и отрисовывает сраницу. Все нужные для работы приложения зависимости просто добавлены как теги(пока они не загрузяться ничего не сработает дальше). А расширения для контента, типа плагина для графиков, видео какое-то вы можите в фоновом режиме просто подгрузить. Ведь это одностраничное приложение, смысл постоянно перезагружать расширения.

Вы можите просто добавить проверку типа:
if(window.$){
 //если у нас есть jQuery
// то приложение идёт дальше работать

}else{
 //вызываем какую-то функцию установщик
loadExtension('jquery.js')
}

У вас может быть просто массив зависимостей, которые вы можите подгрузить в фоне. Но когда у вас запрашивается страница /home/about требующая графиков например, вы пререндером на сервере можите запросто добавить этот плагин как просто тег script, а приложение когда будет бегать по зависимостям через if проверит есть он или нет, т.к. вы его подгрузили уже,то он проигнорируеться и у вас не будет дуближей.
Ответ написан
abyrkov
@abyrkov
JavaScripter
Не очень понял вопрос. Можно загрузить документ, потом, с помощью $('script:not css:not') выдернуть содержимое не скриптов и не стилей и вставить в body. Что касается дублей, ничего умнее, чем массив из src скриптов и стилей(отдельных конечно) и проверки, есть ли элемент скрипта/стиля с таким src. Есть - удаляем из массива. Остается только проверить массивы после проверки и добавить нужные скрпиты
Ответ написан
@kirick
Я давно решил для себя этот вопрос — и описал его здесь: https://kirick.me/blog/how-to-ajax-sites
Вкратце: сервер отдаёт страницы "как есть" и ничего не знает, что он, оказывается, аякс-сайт. То есть при открытии сайта с нуля он грузится как обычный. А вот потом при переходе по ссылкам контент грузится через аякс, и клиентский скрипт препарирует получаемый контент:
1. вычленяет оттуда <body> и заменяет им содержимое страницы;
2. достаёт из <head> тэг <title>;
3. достаёт из <head> все скрипты и стили и добавляет в <head> страницы только те, которых там ещё нет.
Асинхронная подгрузка ресурсов, несомненно, нужна, но это отдельная тема, используйте плагин по вкусу. И, например, пусть этот аякс-загрузчик не вставляет скрипты и стили в страницу, а скармливает их этому плагину, а он уже разбирается.
И ещё один момент — если на загруженной аяксом странице требуется подключить дополнительный файл стилей, то будет некоторое время каша из элементов, пока стиль подключается. Но решение простое — вставить критические для отображения стили в тэг <style> прямо в страницу — и HTTP-запрос сэкономите, и время загрузки.
Ответ написан
Комментировать
Valonix
@Valonix
Back end / Front end developer
Делал как-то подобное, на сервере был Cake PHP на клиенте чистое jquery + handlebars. Все слайдеры и прочие штуки делал с помощью handlebars. Получилось SPA без всяких ангуляров:)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
22 дек. 2024, в 20:40
10000 руб./за проект
22 дек. 2024, в 20:34
3000 руб./за проект
22 дек. 2024, в 20:12
10000 руб./за проект