Bien que le n ° 2 puisse être «plus facile» pour vous en tant que développeur, il ne fournit que l'exploration des moteurs de recherche. Et oui, si Google découvre que vous diffusez un contenu différent, vous pourriez être pénalisé (je ne suis pas un expert en la matière, mais j'en ai entendu parler).
Le référencement et l'accessibilité (pas seulement pour les personnes handicapées, mais aussi l'accessibilité via des appareils mobiles, des appareils à écran tactile et d'autres plates-formes informatiques / Internet non standard) ont tous deux une philosophie sous-jacente similaire: un balisage sémantiquement riche qui est «accessible» (c.-à-d. être consultés, consultés, lus, traités ou autrement utilisés) à tous ces différents navigateurs. Un lecteur d'écran, un robot d'exploration de moteur de recherche ou un utilisateur avec JavaScript activé, devraient tous être capables d'utiliser / indexer / comprendre les fonctionnalités de base de votre site sans problème.
pushState
n'ajoute pas à ce fardeau, d'après mon expérience. Cela ne fait qu'apporter ce qui était autrefois une réflexion après coup et "si nous en avons le temps" au premier plan du développement Web.
Ce que vous décrivez dans l'option n ° 1 est généralement la meilleure façon de procéder - mais, comme d'autres problèmes d'accessibilité et de référencement, le faire pushState
dans une application contenant beaucoup de JavaScript nécessite une planification préalable , sinon cela deviendra un fardeau important. Il doit être intégré à la page et à l'architecture de l'application dès le début - la mise à niveau est douloureuse et entraînera plus de duplication que nécessaire.
J'ai pushState
récemment travaillé avec et SEO pour quelques applications différentes, et j'ai trouvé ce que je pense être une bonne approche. Il suit essentiellement votre élément n ° 1, mais tient compte de la non duplication du HTML / des modèles.
La plupart des informations se trouvent dans ces deux articles de blog:
http://lostechies.com/derickbailey/2011/09/06/test-driving-backbone-views-with-jquery-templates-the-jasmine-gem-and-jasmine-jquery/
et
http://lostechies.com/derickbailey/2011/06/22/rendering-a-rails-partial-as-a-jquery-template/
L'essentiel est que j'utilise des modèles ERB ou HAML (exécutant Ruby on Rails, Sinatra, etc.) pour mon rendu côté serveur et pour créer les modèles côté client que Backbone peut utiliser, ainsi que pour mes spécifications JavaScript Jasmine. Cela supprime la duplication du balisage entre le côté serveur et le côté client.
À partir de là, vous devez prendre quelques étapes supplémentaires pour que votre JavaScript fonctionne avec le HTML rendu par le serveur - une véritable amélioration progressive; prendre le balisage sémantique qui a été livré et l'améliorer avec JavaScript.
Par exemple, je crée une application de galerie d'images avec pushState
. Si vous demandez /images/1
au serveur, il rendra toute la galerie d'images sur le serveur et enverra tout le HTML, CSS et JavaScript à votre navigateur. Si vous avez désactivé JavaScript, cela fonctionnera parfaitement. Chaque action que vous entreprenez demandera une URL différente au serveur et le serveur rendra tout le balisage pour votre navigateur. Si vous avez activé JavaScript, cependant, le JavaScript récupérera le HTML déjà rendu avec quelques variables générées par le serveur et prendra le relais à partir de là.
Voici un exemple:
<form id="foo">
Name: <input id="name"><button id="say">Say My Name!</button>
</form>
Une fois que le serveur a rendu cela, le JavaScript le récupère (en utilisant une vue Backbone.js dans cet exemple)
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")
});
});
C'est un exemple très simple, mais je pense qu'il fait passer le message.
Lorsque j'instante la vue après le chargement de la page, je fournis le contenu existant du formulaire rendu par le serveur, à l'instance de vue comme el
pour la vue. Je n'appelle pas render ou je ne demande pas à la vue de générer un el
pour moi, lorsque la première vue est chargée. J'ai une méthode de rendu disponible une fois que la vue est opérationnelle et que la page est entièrement en JavaScript. Cela me permet de restituer la vue plus tard si j'en ai besoin.
Cliquer sur le bouton "Dites mon nom" avec JavaScript activé provoquera une boîte d'alerte. Sans JavaScript, il serait posté sur le serveur et le serveur pourrait rendre le nom en un élément html quelque part.
Éditer
Prenons un exemple plus complexe, où vous avez une liste qui doit être jointe (à partir des commentaires ci-dessous)
Supposons que vous ayez une liste d'utilisateurs dans une <ul>
balise. Cette liste a été rendue par le serveur lorsque le navigateur a fait une demande, et le résultat ressemble à quelque chose comme:
<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>
Vous devez maintenant parcourir cette liste et attacher une vue et un modèle Backbone à chacun des <li>
éléments. Avec l'utilisation de l' data-id
attribut, vous pouvez trouver facilement le modèle dont provient chaque balise. Vous aurez alors besoin d'une vue de collection et d'une vue d'élément suffisamment intelligentes pour s'attacher à ce code 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();
Dans cet exemple, le UserListView
parcourt toutes les <li>
balises et attache un objet de vue avec le modèle correct pour chacun. il configure un gestionnaire d'événements pour l'événement de changement de nom du modèle et met à jour le texte affiché de l'élément lorsqu'une modification se produit.
Ce type de processus, pour prendre le html rendu par le serveur et faire prendre en charge mon JavaScript et l'exécuter, est un excellent moyen de faire avancer les choses pour le référencement, l'accessibilité et le pushState
support.
J'espère que cela pourra aider.
Je pense que vous en avez besoin: http://code.google.com/web/ajaxcrawling/
Vous pouvez également installer un backend spécial qui "rend" votre page en exécutant javascript sur le serveur, puis le sert à Google.
Combinez les deux choses et vous avez une solution sans programmer les choses deux fois. (Tant que votre application est entièrement contrôlable via des fragments d'ancrage.)
la source
Donc, il semble que la principale préoccupation est d'être SEC
<a href="https://stackoverflow.com/someotherpage">mylink</a>
, le serveur réécrit l'URL dans votre fichier d'application, la charge dans phantom.js et le code HTML résultant est envoyé au bot, etc. ..<a>
balises. Dans ce cas, la gestion de 404 est plus facile puisque vous pouvez simplement vérifier l'existence du fichier statique avec un nom contenant le chemin de l'url.Voici quelques exemples utilisant phantom.js pour le référencement:
http://backbonetutorials.com/seo-for-single-page-apps/
http://thedigitalself.com/blog/seo-and-javascript-with-phantomjs-server-side-rendering
la source
Si vous utilisez Rails, essayez poirot . C'est un bijou qui rend très simple la réutilisation des modèles de moustache ou de guidon côté client et serveur.
Créez un fichier dans vos vues comme
_some_thingy.html.mustache
.Rendu côté serveur:
Mettez le modèle dans votre tête pour une utilisation côté client:
Rendre côté client:
la source
Pour prendre un angle légèrement différent, votre deuxième solution serait la bonne en termes d' accessibilité ... vous fourniriez un contenu alternatif aux utilisateurs qui ne peuvent pas utiliser javascript (ceux qui ont des lecteurs d'écran, etc.).
Cela ajouterait automatiquement les avantages du référencement et, à mon avis, ne serait pas considéré comme une technique «coquine» par Google.
la source
Intéressant. J'ai cherché des solutions viables, mais cela semble assez problématique.
J'étais en fait davantage penché vers votre deuxième approche:
Voici mon point de vue sur la résolution du problème. Bien que son efficacité ne soit pas confirmée, elle peut fournir des informations ou des idées à d'autres développeurs.
Supposons que vous utilisez un framework JS qui prend en charge la fonctionnalité «push state» et que votre framework backend est Ruby on Rails. Vous avez un site de blog simple et vous aimeriez que les moteurs de recherche indexent tous vos articles
index
etshow
pages.Disons que vos itinéraires sont configurés comme ceci:
Assurez-vous que chaque contrôleur côté serveur restitue le même modèle que celui dont votre infrastructure côté client a besoin pour s'exécuter (html / css / javascript / etc). Si aucun des contrôleurs ne correspond à la demande (dans cet exemple, nous n'avons qu'un ensemble d'actions RESTful pour le
ArticlesController
), alors faites correspondre tout le reste et restituer simplement le modèle et laisser le framework côté client gérer le routage. La seule différence entre frapper un contrôleur et frapper la correspondance générique serait la possibilité de rendre le contenu en fonction de l'URL qui a été demandée aux appareils désactivés par JavaScript.D'après ce que je comprends, c'est une mauvaise idée de rendre un contenu qui n'est pas visible pour les navigateurs. Ainsi, lorsque Google l'indexe, les gens passent par Google pour visiter une page donnée et il n'y a pas de contenu, alors vous allez probablement être pénalisé. Ce qui me vient à l'esprit, c'est que vous rendez le contenu dans un
div
nœud que vousdisplay: none
en CSS.Cependant, je suis presque sûr que cela n'a pas d'importance si vous faites simplement ceci:
Et puis en utilisant JavaScript, qui ne s'exécute pas lorsqu'un appareil désactivé par JavaScript ouvre la page:
De cette façon, pour Google, et pour toute personne disposant d'appareils JavaScript désactivés, ils verraient le contenu brut / statique. Ainsi, le contenu est physiquement là et est visible par toute personne disposant d'appareils JavaScript désactivés.
Mais, lorsqu'un utilisateur visite la même page et que JavaScript est activé, le
#no-js
nœud sera supprimé pour ne pas encombrer votre application. Ensuite, votre infrastructure côté client traitera la demande via son routeur et affichera ce qu'un utilisateur devrait voir lorsque JavaScript est activé.Je pense que cela pourrait être une technique valide et assez facile à utiliser. Bien que cela puisse dépendre de la complexité de votre site Web / application.
Cependant, veuillez me corriger si ce n'est pas le cas. Je pensais juste partager mes pensées.
la source
Utilisez NodeJS côté serveur, naviguez votre code côté client et acheminez chaque uri de requête http (à l'exception des ressources http statiques) via un client côté serveur pour fournir le premier 'bootsnap' (un instantané de la page dans son état). Utilisez quelque chose comme jsdom pour gérer les dom-ops jquery sur le serveur. Après le retour du bootnap, configurez la connexion websocket. Il est probablement préférable de faire la différence entre un client websocket et un client côté serveur en établissant une sorte de connexion wrapper côté client (le client côté serveur peut communiquer directement avec le serveur). J'ai travaillé sur quelque chose comme ça: https://github.com/jvanveen/rnet/
la source
Utilisez le modèle de fermeture Google pour afficher les pages. Il se compile en javascript ou en java, il est donc facile de rendre la page côté client ou côté serveur. Lors de la première rencontre avec chaque client, rendez le html et ajoutez javascript comme lien dans l'en-tête. Le robot lira uniquement le code HTML mais le navigateur exécutera votre script. Toutes les demandes ultérieures du navigateur peuvent être effectuées contre l'API pour minimiser le trafic.
la source