AJAX Заявки с кеширане

Миналата седмица написах урок как можем да подобрим user experience-а на нашия сайт, като зареждаме новото съдържание на страниците с JavaScript без презареждане. Тази седмица ще направим промени по кода си, така че да кешираме заредената информация и да не пращаме нови заявки към сървъра, ако не се налага.

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

В този урок ще правим промени директно по кода от предния път.

Кеш обект

Нека като за начало да си добавим променлива (обект), в която ще съхраняваме кешираната информация.

jQuery(function ($) {
	var cache = {};
	
	$(document).on('click', 'nav a', function (e) {
		e.preventDefault(); var link = $(this);
		
		$.get(link.attr('href'), function (data, status, XHR) {
			if (status == 'success') {
					cache[link.attr('href')] = data; $('section[role="main"]').html($(data).find('section[role="main"]').html()); $('title').html($(data).filter('title').html());
					
					$('header').html($(data).find('header').html());
				} else {
					// tell the user we could not connect to the server
				}
			});
	});
});

За по-лесен достъп до текущия линк запазвам стойността му в променлива link в click handler-а.

Дефинираме променливата във функцията, която извикваме при DOM Content Loaded. По този начин можем да я достъпваме навсякъде в тази функция, но не и извън нея.

Забележете и начина, по който записваме в този обект информацията, която сме получили при резултат със статус success при нашата get заявка — cache[link.attr('href')] = data;.

Достъпване на белег на обект чрез квадратни скоби

Използвайки квадратни скоби можем да достъпим property на обект. Ако в квадратните скоби напишем просто string би било същото, като това да използваме и dot notation syntax (синтаксис с употреба на точки):

object = { prop1: 'value' };
console.log(object.prop1); // извежда "value" в конзолата

object['prop1'] = 'new-value';
console.log(object.prop1); // извежда "new-value"

for (var i = 1; i < 2; i++) {
	object['prop' + i] = 'third-value';
}

console.log(object.prop1); // извежда "third-value"

Предимството при този синтаксис е, че така можем да създаваме динамично имената на белезите с помощта на променливи. В примера виждате как чрез i динамично генерирам името на property-то "prop1". Подобно нещо не може да се направи с dot notation syntax.

Това предимство използваме и при кеширането. Там задаваме стойност на property, като самото property зависи от адреса на линка. Така можем да генерираме толкова property-та колкото линка имаме. Същевременно запазваме и самия JavaScript независим от адресите на страниците.

Проверка за наличен кеш

Сега следва при клик на линк да направим проверка дали вече нямаме резултата кеширан. Така ще правим AJAX заявка само по веднъж за един и същ адрес.

jQuery(function ($) {
	var cache = {};
	
	$(document).on('click', 'nav a', function (e) {
		e.preventDefault();
		
		var link = $(this);
		
		if (typeof(cache[link.attr('href')]) != 'undefined') {
			// show cached content
		} else {
			$.get(link.attr('href'), function (data, status, XHR) {
				if (status == 'success') {
					cache[link.attr('href')] = data; $('section[role="main"]').html($(data).find('section[role="main"]').html()); $('title').html($(data).filter('title').html());
					
					$('header').html($(data).find('header').html());
				} else {
					// tell the user we could not connect to the server
				}
			});
		}
	});
});

Проверката я правим чрез typeof(cache[link.attr('href')) != 'undefined'. Проверка за типа на дадена променлива сме правили и в предишни уроци. Тук отново проверяваме дали типът е различен от “undefined”. Дали променливата, която в случая е във вида на property на обект, съществува.

Ако съществува — значи вече имаме дадения адрес кеширан. Тогава не трябва да правим нова заявка, а само да покажем информацията. Бихме могли просто да копираме функционалността, с която заменяме съдържанието в callback функцията на заявката. Но това ще доведе до повтаряне на код.

Избягване на повторения в кода

По-добрият начин би бил да извършим това чрез функция. И да викаме в двата случая:

jQuery(function ($) {
	var cache = {};
	
	function showPageContent(data) {
		$('section[role="main"]').html($(data).find('section[role="main"]').html());
		$('title').html($(data).filter('title').html());
		$('header').html($(data).find('header').html());
	}
	
	$(document).on('click', 'nav a', function (e) {
		e.preventDefault();
		
		var link = $(this);
		
		if (typeof(cache[link.attr('href')]) != 'undefined') {
			showPageContent(cache[link.attr('href')]);
		} else {
			$.get(link.attr('href'), function (data, status, XHR) {
				if (status == 'success') {
					cache[link.attr('href')] = data;
					showPageContent(data);
				} else {
					// tell the user we could not connect to the server
				}
			});
		}
	});
}); 

Можете да видите крайния резултат на https://magadanski.com/demo/ajax-requests-cached/

Тъй като в случая използваме статични страници, сървърите указват на браузъра, че промяна в скоро време може и да не се забележи. Затова самите браузъри кешират нашите заявки. Кодът, който добавихме в този урок, би бил уместен в случай, че страниците ни са генерирани динамично (например с PHP).

Вашият коментар

Вашият имейл адрес няма да бъде публикуван. Задължителните полета са отбелязани с *

Този сайт използва Akismet за намаляване на спама. Научете как се обработват данните ви за коментари.