Meskipun # 2 mungkin "lebih mudah" bagi Anda sebagai pengembang, itu hanya menyediakan perayapan mesin pencari. Dan ya, jika Google mengetahui bahwa Anda menyajikan konten yang berbeda, Anda mungkin akan dihukum (saya bukan ahli dalam hal itu, tetapi saya pernah mendengarnya terjadi).
Baik SEO dan aksesibilitas (tidak hanya untuk penyandang cacat, tetapi aksesibilitas melalui perangkat seluler, perangkat layar sentuh, dan platform berkemampuan internet / non-standar lainnya) keduanya memiliki filosofi mendasar yang serupa: peningkatan kaya semantik yang "dapat diakses" (yaitu dapat diakses, dilihat, dibaca, diproses, atau digunakan) untuk semua browser yang berbeda ini. Pembaca layar, perayap mesin pencari, atau pengguna dengan JavaScript diaktifkan, semuanya harus dapat menggunakan / mengindeks / memahami fungsi inti situs Anda tanpa masalah.
pushState
tidak menambah beban ini, dalam pengalaman saya. Ini hanya membawa apa yang dulunya menjadi renungan dan "jika kita punya waktu" ke garis depan pengembangan web.
Apa yang Anda gambarkan dalam opsi # 1 biasanya merupakan cara terbaik - tetapi, seperti masalah aksesibilitas dan SEO lainnya, melakukan hal ini dengan pushState
aplikasi JavaScript yang berat memerlukan perencanaan di muka atau akan menjadi beban yang signifikan. Itu harus dimasukkan ke dalam halaman dan arsitektur aplikasi dari awal - perkuatan sulit dan akan menyebabkan lebih banyak duplikasi daripada yang diperlukan.
Saya telah bekerja dengan pushState
dan SEO baru-baru ini untuk beberapa aplikasi yang berbeda, dan saya menemukan apa yang saya pikir merupakan pendekatan yang baik. Ini pada dasarnya mengikuti item Anda # 1, tetapi akun untuk tidak menduplikasi html / templat.
Sebagian besar info dapat ditemukan di dua posting blog ini:
http://lostechies.com/derickbailey/2011/09/06/test-driving-backbone-views-with-jquery-templates-the-jasmine-gem-and-jasmine-jquery/
dan
http://lostechies.com/derickbailey/2011/06/22/rendering-a-rails-partial-as-a-jquery-template/
Intinya adalah saya menggunakan templat ERB atau HAML (menjalankan Ruby on Rails, Sinatra, dll) untuk render sisi server saya dan untuk membuat templat sisi klien yang dapat digunakan Backbone, serta untuk spesifikasi JavaScript Jasmine saya. Ini memotong duplikasi markup antara sisi server dan sisi klien.
Dari sana, Anda perlu mengambil beberapa langkah tambahan agar JavaScript Anda berfungsi dengan HTML yang diberikan oleh server - peningkatan progresif yang sebenarnya; mengambil markup semantik yang dikirimkan dan menyempurnakannya dengan JavaScript.
Misalnya, saya sedang membangun aplikasi galeri gambar dengan pushState
. Jika Anda meminta /images/1
dari server, itu akan merender seluruh galeri gambar di server dan mengirim semua HTML, CSS, dan JavaScript ke browser Anda. Jika Anda menonaktifkan JavaScript, itu akan berfungsi dengan baik. Setiap tindakan yang Anda lakukan akan meminta URL yang berbeda dari server dan server akan membuat semua markup untuk browser Anda. Jika Anda mengaktifkan JavaScript, JavaScript akan mengambil HTML yang sudah diberikan bersama dengan beberapa variabel yang dihasilkan oleh server dan mengambil alih dari sana.
Ini sebuah contoh:
<form id="foo">
Name: <input id="name"><button id="say">Say My Name!</button>
</form>
Setelah server membuat ini, JavaScript akan mengambilnya (menggunakan tampilan Backbone.js dalam contoh ini)
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(){
// do some rendering here, for when this is just running JavaScript
}
});
$(function(){
var model = new MyModel();
var view = new FooView({
model: model,
el: $("#foo")
});
});
Ini adalah contoh yang sangat sederhana, tapi saya pikir ini benar.
Ketika saya membuat tampilan setelah halaman dimuat, saya memberikan konten yang ada dari formulir yang diberikan oleh server, ke tampilan contoh sebagai el
untuk tampilan. Saya tidak memanggil render atau membuat view menghasilkan el
bagi saya, ketika tampilan pertama dimuat. Saya memiliki metode render yang tersedia untuk setelah tampilan dan berjalan dan halaman semua JavaScript. Ini memungkinkan saya merender ulang tampilan nanti jika perlu.
Mengklik tombol "Say My Name" dengan JavaScript diaktifkan akan menyebabkan kotak peringatan. Tanpa JavaScript, itu akan dikirim kembali ke server dan server dapat membuat nama ke elemen html di suatu tempat.
Edit
Pertimbangkan contoh yang lebih kompleks, di mana Anda memiliki daftar yang perlu dilampirkan (dari komentar di bawah ini)
Katakanlah Anda memiliki daftar pengguna dalam sebuah <ul>
tag. Daftar ini diberikan oleh server ketika browser membuat permintaan, dan hasilnya terlihat seperti:
<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>
Sekarang Anda perlu mengulang daftar ini dan melampirkan tampilan dan model Backbone untuk masing-masing <li>
item. Dengan penggunaan data-id
atribut, Anda dapat menemukan model yang berasal dari setiap tag dengan mudah. Anda kemudian akan memerlukan tampilan koleksi dan tampilan item yang cukup pintar untuk melampirkan dirinya ke html ini.
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();
Dalam contoh ini, UserListView
kehendak akan melewati semua <li>
tag dan melampirkan objek tampilan dengan model yang benar untuk masing-masing. itu mengatur pengendali acara untuk acara perubahan nama model dan memperbarui teks elemen yang ditampilkan ketika perubahan terjadi.
Proses semacam ini, untuk mengambil html yang diberikan server dan membuat JavaScript saya mengambil alih dan menjalankannya, adalah cara yang bagus untuk membuat semuanya bergulir untuk SEO, Aksesibilitas, dan pushState
dukungan.
Semoga itu bisa membantu.