Une page web, c'est d'abord du code HTML interprété par un navigateur.
Comme dans tout, il y a des normes établies. Même si les navigateurs du marché arrivent à se débrouiller à interpréter plus ou moins efficacement ce qu'on leur donne à manger, ils ne peuvent pas tout digérer non plus.
La qualité
C'est quoi la qualité ? Sur la partie HTML (et CSS), il s'agit d'éviter de faire « lire » inutilement un code qui ne correspond pas à ce qui est connu par un navigateur.
Ça n'a l'air de rien, mais tout ce qui n'est pas standard demande du travail, donc de la ressource, pour finalement ne rien en faire.
Par exemple, si on utilise un attribut qui n'est pas référencé, le navigateur doit l'ignorer. Mais pour l'ignorer, il doit d'abord le lire, lire sa valeur et se dire « ah non… je n'en fais rien ».
Ce calcul entre dans la catégorie du calcul du temps de travail du thread principal dans les Core Web Vitals.
Valider le code
Première option : sur un site en production, ce n'est pas compliqué. Le validateur en ligne fait le boulot.
Mais… il ne fait pas tout le boulot. Il se contente d'analyser le code brut, sans aucune interprétation du Javascript. Ce point est important, car il est probable qu'il y ait beaucoup de choses injectées côté client, et ça, le validateur n'en fait rien du tout.
Si une page déclenche des événements, ils ne seront pas pris en compte. Exemple typique : les modales.
Et ça, ce n'est utilisable que pour un site accessible par le validateur. Et c'est déjà trop tard !
Il est tout de même préférable de s'assurer d'avoir un code (presque) propre avant une mise en production. Non ? Si… Mais le validateur n'aura pas accès au code d'un poste de développement ou d'un serveur de recette.
Comment faire ?
Simplement en utilisant un raccourci qui va envoyer le code lu par le navigateur.
Il suffit d'un script à enregistrer dans les favoris (normalement, vous savez faire ça).
Le script
Version simple
Cette version envoie tout ce qui est dans la page.
javascript:(()=>{let form_=document.createElement('form'),addInput=(n,v)=>{let element_=document.createElement('textarea');element_.name=n;element_.value=v;form_.appendChild(element_);},markup,e=function(a){for(markup='',a=a.firstChild;a;){switch(a.nodeType){case Node.ELEMENT_NODE:markup+=a.outerHTML;break;case Node.TEXT_NODE:markup+=a.nodeValue;break;case Node.CDATA_SECTION_NODE:markup+=`<![CDATA[${a.nodeValue}]]\>`;break;case Node.COMMENT_NODE:markup+=`<!--${a.nodeValue}--\>`;break;case Node.DOCUMENT_TYPE_NODE:markup+=`<!DOCTYPE ${a.name}>\n`}a=a.nextSibling}return markup;}(document),options={'showoutline':true,'showsource':true,'showimagereport':false};form_.method='POST';form_.action='https://validator.w3.org/nu/';form_.enctype='multipart/form-data';form_.target='_blank';form_.acceptCharset='utf-8';for(let i in options){options[i] && addInput(i,'yes');}addInput('content',e);document.body.appendChild(form_);form_.submit();form_.remove();})();
Version allégée
Si le code source de la page à tester contient trop de données (SVG complet, styles, scripts injectés), le validateur peut ne pas parvenir à tout analyser.
Cette version du raccourci nettoie ces balises avant l'envoi.
javascript:(()=>{let cleanCode=(tag)=>{Array.prototype.slice.call(document.getElementsByTagName(tag)).forEach(function(item){item.remove();});};cleanCode('style');cleanCode('svg');cleanCode('script');let form_=document.createElement('form'),addInput=(n,v)=>{let element_=document.createElement('textarea');element_.name=n;element_.value=v;form_.appendChild(element_);},markup,e=function(a){for(markup='',a=a.firstChild;a;){switch(a.nodeType){case Node.ELEMENT_NODE:markup+=a.outerHTML;break;case Node.TEXT_NODE:markup+=a.nodeValue;break;case Node.CDATA_SECTION_NODE:markup+=`<![CDATA[${a.nodeValue}]]\>`;break;case Node.COMMENT_NODE:markup+=`<!--${a.nodeValue}--\>`;break;case Node.DOCUMENT_TYPE_NODE:markup+=`<!DOCTYPE ${a.name}>\n`}a=a.nextSibling}return markup;}(document),options={'showoutline':true,'showsource':true,'showimagereport':false};form_.method='POST';form_.action='https://validator.w3.org/nu/';form_.enctype='multipart/form-data';form_.target='_blank';form_.acceptCharset='utf-8';for(let i in options){options[i] && addInput(i,'yes');}addInput('content',e);document.body.appendChild(form_);form_.submit();form_.remove();})();
Utilisation
Une fois le favori ajouté, il n'y a plus qu'à cliquer dessus pour passer la page courante à la validation.
Ça prend 2 secondes !
Le script en détail
La version du script sans utiliser de raccourci, à appeler par un bouton ou dans la console.
/*
Variante par appel d'une fonction
*/
const validator = () => {
/*
Si le validateur ne parvient pas à parser le code envoyé,
c'est certainement parce qu'il contient trop de données type SVG inline,
JavaScript inline, CSS inline…
Utiliser cette fonction pour "nettoyer" avant le POST :
let cleanCode = (tag) => {
Array.prototype.slice.call(document.getElementsByTagName(tag)).forEach(
function (item) {
item.remove();
});
};
cleanCode('style');
cleanCode('svg');
cleanCode('script');
… ajouter des balises si nécessaires
*/
let form_ = document.createElement('form'),
addInput = (n, v) => {
let element_ = document.createElement('textarea');
element_.name = n;
element_.value = v;
form_.appendChild(element_);
},
markup,
e = function (a) {
for (markup = '', a = a.firstChild; a;) {
switch (a.nodeType) {
case Node.ELEMENT_NODE :
markup += a.outerHTML;
break;
case Node.TEXT_NODE :
markup += a.nodeValue;
break;
case Node.CDATA_SECTION_NODE :
markup += `<![CDATA[${a.nodeValue}]]\>`;
break;
case Node.COMMENT_NODE :
markup += `<!--${a.nodeValue}--\>`;
break;
case Node.DOCUMENT_TYPE_NODE :
markup += `<!DOCTYPE ${a.name}>\n`
}
a = a.nextSibling
}
return markup;
}(document),
options = {
/* afficher la structure de la page true/false */
'showoutline': true,
/* afficher le code source true/false */
'showsource': false,
/* afficher le rapport d'images true/false */
'showimagereport': false
};
form_.method = 'POST';
form_.action = 'https://validator.w3.org/nu/';
form_.enctype = 'multipart/form-data';
form_.target = '_blank';
form_.acceptCharset = 'utf-8';
for (let i in options) {
options[i] && addInput(i, 'yes');
}
addInput('content', e);
document.body.appendChild(form_);
form_.submit();
form_.remove();
};