Једностранична апликација (енгл. Single-page application (SPA)), такође позната као једностранични интерфејс (енгл. Single-page interface (SPI)), је веб-апликација или веб-сајт смештен у оквиру једне веб-странице са циљем пружања лакше интеракције, сличне оној на рачунарима без интернет конекције.
У једностраничним апликацијама сав потребан кôд - HTML, JavaScript и CSS - се преузима у оквиру учитавања једне странице[1], или се одговарајући ресурси учитавају динамички и по потреби додају страници, обично као последица неке акције од стране корисника. Страница се не учитава поновно ни у једној тачки процеса, нити се пребацује на неку другу страницу. Међутим, новије веб-технологије (које су укључене у HTML5) пружају могућност перцепције и навигације кроз више логичких страница у оквиру исте апликације. Интеракција са једностраном апликацијом често укључује динамичку комуникацију са веб-сервером у позадини.
Термин једностранична апликација сковао је Стив Јен (енгл. Steve Yen) 2005. године, иако је о самом концепту дискутовано још 2003.[2]
Технички приступ
Постоје различите технике (методи) које омогућавају веб-прегледачима да преузму и задрже страницу, чак и онда када апликација захтева комуникацију са сервером.
AJAX
Требутно најкоришћенија техника је AJAX.[1] Претежно се користи XMLHttpRequest објекат JavaScript језика. Други AJAX приступи укључују коришћење IFRAME или script елементе HTML језика. AJAX метод популаризовале су библиотеке као што је jQuery, које нормализују понашање AJAX-а на веб-прегледачима различитих произвођача.
Node.js/SignalR
Асинхрони позиви серверу могу се остварити коришћењем Node.js или SignalR заједно са Socket.IO.
Прикључци прегледача
Асинхрони позиви серверу такође могу бити остварени коришћењем прикључака (енгл. plug-in) као што су Silverlight, Flash или Java аплета.
Транспорт података (XML, JSON и AJAX)
Захтеви серверу обично резултују враћањем или сирових података (на пример XML или JSON) или новог HTML документа. У случају када сервер враћа HTML документ, JavaScript са клијентске стране ажурира део DOM-а (Објектни модел документа - Document Object Model). Када сервер врати сирове податке, често се на клијентској страни користи JavaScript XML/(XSL) процес (и шаблон (енгл. template) у случају JSON-а) да преведе сирове податке у HTML, који се даље користи за ажурирање DOM-а.
Архитектура лаких сервера
Једностранична апликација пребацује логику са сервера на клијента. Резултат овога је да улога веб-сервера прераста у чист АПИ података или веб-сервис. Оваква промена архитектуре се, у неким круговима, назива „Танка архитектура сервера“ (енгл. „Thin server architecture“).[3]
Архитекрура тешких сервера
Сервер чува неопходно стање у меморији стања клијентске странице. На тај начин, када се било који захтев шаље серверу (обично нека акција корисника, на пример клик мишем итд.), сервер шаље назад одговарајући HTML и/или JavaScript са конкретним променама које доводе клијента до новог жељеног стања (обично додавање/брисање/ажурирање клијентског DOM-а). У исто време се ажурира стање на серверу. Већи део логике се извршава на серверу, па се обично и HTML формира у серверу. На неки начин сервфер симулира веб-прегледач, прихвата догађаје (на пример клик мишем) и извршава промене у стању сервера које аутоматски пропагира клијенту. Овакав приступ захтева више меморије и обраде на серверу, али предност је поједностављени модел развоја јер:
- Апликација је обично у потпуности кодирана на серверској страни.
- Подаци и У/И стање на серверу деле исти меморијски простор, па нема потребе за посебним клијент/сервер комуникационим мостовима.
Локално извршавање
Неке једностраничне апликације се могу извршити из локалне датотеке користећи URI схеме датотеке (енгл. file URI scheme). Ово пружа кориснику могућност да преузме апликацију са сервера и да је покрене на локалној машини без даље комуникације са сервером.
Уколико таква апликација жели да смести или ажурира неке податке, мора имати могућност да промени саму себе, тј. апликација мора бити способна да сама себе упише на диск, укључујући и репрезентацију стања које ће се променити. Овакве апликације користе предности које доноси HTML5, посебно веб складиштење података (енгл. Web storage)
Изазови SPA модела
Једностраничне апликације еволуцијски напредније од апликација које не чувају стање већ сваки пут поново учитавају страницу. Веб-прегледачи су у почетку прављени за другу врсту претходно наведених модела апликација, па па су се појавили неки нови изазови. Сваки од ових проблема има ефективно решење[4]:
- JavaScript библиотеке на клијентској страни за различите врсте проблема.
- Веб-оквири (енгл. web frameworks) на серверској страни специјализовани за SPA модел.[5][6][7][8]
- Еволуција прегледача и HTML5.
Оптимизација претраживачких машина
Због недостатка JavaScript извршавања на пописивачима (енгл. web crawler) код већине претраживачких машина (енгл. web web search engines), оптимизација претраживачких машина је увек представљала проблем за јавне веб-сајтове који су желели да примене SPA модел.
Гугл тренутно пописује URL-ове који садрже хеш-фрагменте који почињу са #!,.[9] Ово допушта коришћење хеш-фрагмената унутар појединачног URL-а неке једностраничне апликације. Посебно понашање мора се имплементирати од стане SPA веб-сајта да би се допустило извлачење битних мета-података од стране пописивача претраживачке машине. За претраживачке машине које не подржавају ову URL хеш-схему, хеширани URL једностраничне апликације остаје невидљив.
Алтернативно, апликације могу извршити учитавање прве странице на серверу, а ажурирање следеће странице на клијентској страни. Овакав приступ је доста тежак, јер постоји могућност да кôд превођења мора бити писан на различитом језику и оквиру на клијентској и серверској страни. Међу-компајлирање из једног језика у други и коришћење истог језика на серверској и клијентској страни може повећати количину кода који може се дели.
Један од начина да се повећа количина кода који може да се дели између сервера и клијената је коришћење шаблонских језика као што су Mustache и Handlebars. Такви шаблони се могу извући из различитих хост-језика, као што су Ruby за сервере и JavaScript за клијенте. Међутим, само дељење шаблона обично захтева дуплирање бизнис-логике (алгоритми који врше размену података између базе података и корисничког интерфејса) која одређује одговарајуће шаблоне и попуњава их подацима. Обрада шаблона може имати негативне ефекте на перформансе када се ажурира само мали део шаблона - рецимо вредност текстуалног улаза у оквиру великог шаблона. Замена целог шаблона такође може пореметити положај курсора или неки избор корисника, док само ажурирање промењене вредности не мора имати такве последице. Да би се избегли овакви проблеми, апликације могу манипулисати DOM-стаблом тако да се ажурирају одређени делови странице уместо поновног формирања целих шаблона.
Други приступ коришћен од стране серверски оријентисаних оквира (енгл. web frameworks), као што је ItsNat базиран на Javi, је да се обради сваки хипер-текст на серверу коришћењем истог језика и технике формирања шаблона. По овом приступу сервер зна тачно стање клијентовог DOM-а. Свака тражена промена странице, велика или мала, се генерише на серверу и преко AJAX-а се преноси тачан JavaScript кôд који мења клијентску страницу у ново стање извршавајући DOM методе. Програмери могу да одлуче које стање странице је видњиво за пописиваче претраживачких машина. Апликација мора бити способна да генерише такво стање за време које је потребно за учитавање странице, и то чист HTML уместо JavaScript-а. У случају ItsNat оквира ово се врши аутоматски, јер ItsNat чува клијентово DOM-стабло на серверу као Java W3C DOM-стабло. Обрада овог DOM-стабла на серверу генерише чист HTML за време учитавања странице, а Java W3C DOM одређује акције за AJAX захтеве. Овај дуалитет је веома битан за оптимизацију претраживачких машина, јер програмери могу да користе Java кôд и шаблоне базиране на чистом HTML-у за конструисање жељеног стања DOM-стабла на серверу, а за време учитавања странице ItsNat генерише конвенционални HTML и тако чини овај DOM компатибилним за оптимизацију претраживачких машина (енгл. Search engine optimization (SEO)).
Пошто SEO-компитабилност није тривијална ствар код једностраничних апликација, оне се често користе када индексирање претраживачких машина није неопходно или пожељно.
Историја прегледача
Пошто су једностраничне апликације по дефиницији садржане у једној страници, њихов модел се коси са дизајном историје прегледача (енгл. Browser history) који користе дугмад типа Претходна/Следећа страница за навигацију кроз историју сурфовања. Ово представља сметњу када корисник притисне дугме „Претходна страница“, очекујући да се на екрану прикаже претходно стање у оквиру апликације, а уместо тога прегледач учитава претходно посећену страницу из историје прегледача.
Традиционално решење за једностраничне апликације је да се мења хеш-фрагмент идентификатор URL-а у складу са тренутним стањем екрана. Ово се постиже коришћењем JavaScript-а, тако што се гради историја URL догађаја унутар прегледача. Задржава се очекивано понашање дугмета „Претходна страница“, док год је апликација способна да произведе исто стање на екрану по информацијама садржаним унутар URL хеш-а.
За даље информације о овој теми, читаоци се упућују на HTML5 спецификацију овде и овде где могу да се информишу о приступу садржају URL-а и историји прегледача.
Животни циклус странице
Једностранична апликација се у потпуности учитава у иницијалном учитавању странице, а онда се делови странице по захтеву мењају и ажурирају новим фрагментима учитаним са сервера. Да би се избегло прекомерно преузимање неискоришћених функција, апликација ће често постепено преузимати нове функције када оне буду потребне.
На овај начин постоји аналогија између „стања“ код једностраничних апликација и „страница“ код класичних веб-сајтова, јер навигација кроз стања на неким страницама одговара навигацији кроз странице на неком сајту. У теорији, било који веб-сајт базиран на страницама може се конвертовати у једностраничну апликацију, тако што ће се на једној страници, при „преласку“ на другу мењати само они делови који се разликују.
Reference
Спољашње везе