Mặc dù # 2 có thể là "dễ dàng hơn" đối với bạn với tư cách là nhà phát triển, nhưng nó chỉ cung cấp khả năng thu thập dữ liệu của công cụ tìm kiếm. Và vâng, nếu Google phát hiện ra nội dung phục vụ khác nhau của bạn, bạn có thể bị phạt (Tôi không phải là chuyên gia về vấn đề đó, nhưng tôi đã nghe nói về việc đó xảy ra).
Cả SEO và khả năng truy cập (không chỉ dành cho người khuyết tật, mà cả khả năng truy cập qua thiết bị di động, thiết bị màn hình cảm ứng và các nền tảng hỗ trợ máy tính / internet không chuẩn khác) đều có một triết lý cơ bản tương tự: đánh dấu giàu ngữ nghĩa là "có thể truy cập" (nghĩa là có thể được truy cập, xem, đọc, xử lý hoặc sử dụng theo cách khác) cho tất cả các trình duyệt khác nhau này. Trình đọc màn hình, trình thu thập công cụ tìm kiếm hoặc người dùng đã bật JavaScript, tất cả đều có thể sử dụng / lập chỉ mục / hiểu chức năng cốt lõi của trang web của bạn mà không gặp sự cố.
pushState
không thêm vào gánh nặng này, theo kinh nghiệm của tôi. Nó chỉ đưa những gì từng là một suy nghĩ và "nếu chúng ta có thời gian" đi đầu trong phát triển web.
Những gì bạn mô tả trong tùy chọn # 1 thường là cách tốt nhất - nhưng, giống như các vấn đề về khả năng truy cập và SEO khác, thực hiện điều này với pushState
một ứng dụng nặng JavaScript đòi hỏi phải lập kế hoạch trước hoặc nó sẽ trở thành gánh nặng đáng kể. Nó nên được đưa vào trang và kiến trúc ứng dụng ngay từ đầu - trang bị thêm là đau đớn và sẽ gây ra nhiều sự trùng lặp hơn mức cần thiết.
pushState
Gần đây tôi đã làm việc và SEO cho một vài ứng dụng khác nhau và tôi thấy những gì tôi nghĩ là một cách tiếp cận tốt. Về cơ bản, nó tuân theo mục số 1 của bạn, nhưng tài khoản không sao chép html / mẫu.
Hầu hết các thông tin có thể được tìm thấy trong hai bài viết trên blog này:
http://lostechies.com/derickbailey/2011/09/06/test-dishing-backbone-view-with-jquery-temsheet-the-jasmine-gem-and-jasmine-jquery/
và
http://lostechies.com/derickbailey/2011/06/22/rendering-a-rails-partial-as-a-jquery-template/
Điểm chính của nó là tôi sử dụng các mẫu ERB hoặc HAML (chạy Ruby on Rails, Sinatra, v.v.) để kết xuất phía máy chủ của tôi và để tạo các mẫu phía máy khách mà Backbone có thể sử dụng, cũng như cho các thông số JavaScript Jasmine của tôi. Điều này cắt bỏ sự trùng lặp đánh dấu giữa phía máy chủ và phía máy khách.
Từ đó, bạn cần thực hiện thêm một số bước để JavaScript của bạn hoạt động với HTML được máy chủ kết xuất - tăng cường tiến bộ thực sự; lấy đánh dấu ngữ nghĩa đã được phân phối và nâng cao nó bằng JavaScript.
Ví dụ: tôi đang xây dựng một ứng dụng thư viện ảnh pushState
. Nếu bạn yêu cầu /images/1
từ máy chủ, nó sẽ hiển thị toàn bộ thư viện hình ảnh trên máy chủ và gửi tất cả HTML, CSS và JavaScript xuống trình duyệt của bạn. Nếu bạn đã tắt JavaScript, nó sẽ hoạt động hoàn toàn tốt. Mỗi hành động bạn thực hiện sẽ yêu cầu một URL khác từ máy chủ và máy chủ sẽ hiển thị tất cả các đánh dấu cho trình duyệt của bạn. Tuy nhiên, nếu bạn đã bật JavaScript, JavaScript sẽ chọn HTML đã được kết xuất cùng với một vài biến được tạo bởi máy chủ và tiếp quản từ đó.
Đây là một ví dụ:
<form id="foo">
Name: <input id="name"><button id="say">Say My Name!</button>
</form>
Sau khi máy chủ kết xuất lại, JavaScript sẽ chọn nó (sử dụng chế độ xem Backbone.js trong ví dụ này)
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")
});
});
Đây là một ví dụ rất đơn giản, nhưng tôi nghĩ rằng nó có điểm.
Khi tôi mở chế độ xem sau khi tải trang, tôi sẽ cung cấp nội dung hiện có của biểu mẫu được máy chủ hiển thị, cho phiên bản xem như là el
cho chế độ xem. Tôi không gọi render hoặc có chế độ xem tạo ra el
cho tôi, khi chế độ xem đầu tiên được tải. Tôi có một phương thức kết xuất có sẵn sau khi chế độ xem được bật và chạy và trang là tất cả JavaScript. Điều này cho phép tôi hiển thị lại chế độ xem sau nếu tôi cần.
Nhấp vào nút "Nói tên tôi" với JavaScript được bật sẽ gây ra hộp cảnh báo. Nếu không có JavaScript, nó sẽ đăng lại máy chủ và máy chủ có thể hiển thị tên thành phần tử html ở đâu đó.
Biên tập
Hãy xem xét một ví dụ phức tạp hơn, nơi bạn có một danh sách cần được đính kèm (từ các bình luận bên dưới này)
Giả sử bạn có một danh sách người dùng trong một <ul>
thẻ. Danh sách này được máy chủ hiển thị khi trình duyệt đưa ra yêu cầu và kết quả trông giống như:
<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>
Bây giờ bạn cần lặp qua danh sách này và đính kèm một khung nhìn và mô hình xương sống cho mỗi <li>
mục. Với việc sử dụng data-id
thuộc tính, bạn có thể tìm thấy mô hình mà mỗi thẻ xuất phát dễ dàng. Sau đó, bạn sẽ cần một chế độ xem bộ sưu tập và chế độ xem mục đủ thông minh để tự đính kèm vào html này.
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();
Trong ví dụ này, UserListView
vòng lặp sẽ lặp qua tất cả các <li>
thẻ và đính kèm một đối tượng khung nhìn với mô hình chính xác cho từng thẻ. nó thiết lập một trình xử lý sự kiện cho sự kiện thay đổi tên của mô hình và cập nhật văn bản được hiển thị của phần tử khi có thay đổi xảy ra.
Kiểu quy trình này, để lấy html mà máy chủ kết xuất và có JavaScript của tôi tiếp quản và chạy nó, là một cách tuyệt vời để khiến mọi thứ trở nên thuận lợi cho SEO, Trợ năng và pushState
Hỗ trợ.
Mong rằng sẽ giúp.