Chociaż punkt 2 może być „łatwiejszy” dla Ciebie jako programisty, zapewnia jedynie indeksowanie w wyszukiwarkach. I tak, jeśli Google dowie się, że obsługujesz różne treści, możesz zostać ukarany (nie jestem w tym ekspertem, ale słyszałem, że tak się dzieje).
Zarówno SEO, jak i dostępność (nie tylko dla osoby niepełnosprawnej, ale także dostępność za pośrednictwem urządzeń mobilnych, urządzeń z ekranem dotykowym i innych niestandardowych platform komputerowych / internetowych) mają podobną filozofię: bogate semantycznie znaczniki, które są „dostępne” (tj. być dostępne, przeglądane, czytane, przetwarzane lub w inny sposób wykorzystywane) do wszystkich tych różnych przeglądarek. Czytnik ekranu, robot wyszukiwarki lub użytkownik z włączoną obsługą JavaScript powinni być w stanie bez problemu korzystać z / indeksować / rozumieć podstawowe funkcje witryny.
pushState
nie dodaje do tego ciężaru, z mojego doświadczenia. Dopiero to, co kiedyś było refleksją i „jeśli mamy czas”, znajduje się na czele tworzenia stron internetowych.
To, co opisujesz w opcji nr 1, jest zwykle najlepszym rozwiązaniem - ale, podobnie jak inne problemy z dostępnością i SEO, zrobienie tego pushState
w aplikacji z dużą ilością JavaScript wymaga planowania z góry lub stanie się znacznym obciążeniem. Powinien on być od początku zapieczętowany w architekturze strony i aplikacji - modernizacja jest bolesna i spowoduje więcej powielania niż jest to konieczne.
pushState
Ostatnio pracowałem z SEO dla kilku różnych aplikacji i znalazłem to, co uważam za dobre podejście. Zasadniczo podąża za Twoim elementem nr 1, ale uwzględnia brak powielania html / templates.
Większość informacji można znaleźć w tych dwóch postach na blogu:
http://lostechies.com/derickbailey/2011/09/06/test-driving-backbone-views-with-jquery-templates-the-jasmine-gem-and-jasmine-jquery/
i
http://lostechies.com/derickbailey/2011/06/22/rendering-a-rails-partial-as-a-jquery-template/
Istota tego polega na tym, że używam szablonów ERB lub HAML (z uruchomionym Ruby on Rails, Sinatra itp.) Do renderowania po stronie serwera i do tworzenia szablonów po stronie klienta, których może używać Backbone, a także do specyfikacji Jasmine JavaScript. Eliminuje to powielanie znaczników między stroną serwera i klienta.
Następnie musisz wykonać kilka dodatkowych kroków, aby JavaScript działał z kodem HTML renderowanym przez serwer - prawdziwe ulepszenie progresywne; biorąc dostarczony znacznik semantyczny i ulepszając go o JavaScript.
Na przykład tworzę aplikację galerii obrazów z pushState
. Jeśli zażądasz /images/1
od serwera, wyrenderuje całą galerię obrazów na serwerze i wyśle cały kod HTML, CSS i JavaScript do przeglądarki. Jeśli masz wyłączony JavaScript, będzie działać idealnie. Każda czynność, którą podejmiesz, zażąda innego adresu URL z serwera, a serwer wyrenderuje wszystkie znaczniki dla Twojej przeglądarki. Jeśli jednak masz włączony JavaScript, JavaScript pobierze już wyrenderowany kod HTML wraz z kilkoma zmiennymi wygenerowanymi przez serwer i przejmie stamtąd.
Oto przykład:
<form id="foo">
Name: <input id="name"><button id="say">Say My Name!</button>
</form>
Po wyrenderowaniu tego przez serwer, JavaScript powinien to odebrać (używając widoku Backbone.js w tym przykładzie)
FooView = Backbone.View.extend({
events: {
"change #name": "setName",
"click #say": "sayName"
},
setName: function(e){
var name = $(e.currentTarget).val();
this.model.set({name: name});
},
sayName: function(e){
e.preventDefault();
var name = this.model.get("name");
alert("Hello " + name);
},
render: function(){
}
});
$(function(){
var model = new MyModel();
var view = new FooView({
model: model,
el: $("#foo")
});
});
To bardzo prosty przykład, ale myślę, że ma sens.
Kiedy instantuję widok po załadowaniu strony, udostępniam istniejącą zawartość formularza, który został wyrenderowany przez serwer, do instancji widoku jako el
dla widoku. Nie wywołuję renderowania ani nie generuję widoku el
, gdy ładowany jest pierwszy widok. Mam dostępną metodę renderowania po uruchomieniu widoku, a cała strona jest w JavaScript. To pozwoli mi później wyrenderować widok, jeśli zajdzie taka potrzeba.
Kliknięcie przycisku „Say My Name” z włączoną obsługą JavaScript spowoduje wyświetlenie okna alertu. Bez JavaScript wysłałby z powrotem na serwer, a serwer mógłby renderować nazwę w jakimś elemencie html.
Edytować
Rozważ bardziej złożony przykład, w którym masz listę, którą należy załączyć (z komentarzy poniżej)
Powiedzmy, że masz listę użytkowników w <ul>
tagu. Ta lista została wyrenderowana przez serwer, gdy przeglądarka wysłała żądanie, a wynik wygląda mniej więcej tak:
<ul id="user-list">
<li data-id="1">Bob
<li data-id="2">Mary
<li data-id="3">Frank
<li data-id="4">Jane
</ul>
Teraz musisz przejrzeć tę listę i dołączyć widok i model szkieletu do każdego <li>
elementu. Za pomocą data-id
atrybutu można łatwo znaleźć model, z którego pochodzi każdy tag. Będziesz wtedy potrzebował widoku kolekcji i widoku elementów, który jest wystarczająco inteligentny, aby dołączyć się do tego kodu HTML.
UserListView = Backbone.View.extend({
attach: function(){
this.el = $("#user-list");
this.$("li").each(function(index){
var userEl = $(this);
var id = userEl.attr("data-id");
var user = this.collection.get(id);
new UserView({
model: user,
el: userEl
});
});
}
});
UserView = Backbone.View.extend({
initialize: function(){
this.model.bind("change:name", this.updateName, this);
},
updateName: function(model, val){
this.el.text(val);
}
});
var userData = {...};
var userList = new UserCollection(userData);
var userListView = new UserListView({collection: userList});
userListView.attach();
W tym przykładzie UserListView
pętla przejdzie przez wszystkie <li>
znaczniki i dołączy obiekt widoku z odpowiednim modelem dla każdego z nich. konfiguruje procedurę obsługi zdarzenia dla zdarzenia zmiany nazwy modelu i aktualizuje wyświetlany tekst elementu, gdy następuje zmiana.
Ten rodzaj procesu, polegający na przejęciu kodu HTML renderowanego przez serwer i przejęciu go przez JavaScript, jest świetnym sposobem na rozpoczęcie pracy z SEO, pushState
ułatwieniami dostępu i pomocą techniczną.
Mam nadzieję, że to pomoże.