Différer les images hors écran dans Episerver

Le chargement paresseux d'images est une technique pour les développeurs Web modernes où vous demandez au navigateur du client de télécharger uniquement les images en fonction de ses besoins. Cela conduit à d'énormes améliorations de performances, car les périphériques clients ne gaspillent pas de bande passante en téléchargeant des actifs qui ne sont pas rendus. Pour ce faire, nous utiliserons certains mécanismes côté client de css-tricks.com et les prendrons en charge avec le balisage approprié du CMS Episerver.
Images de premier plan et images d'arrière-plan
Quand on parle d'imagerie utilisées sur les sites Web, nous devons réfléchir aux façons dont ces images sont réellement utilisées. Une image de premier plan est votre balise d'image traditionnelle
que vous apprenez en HTML 101. Il s'agit de la manière standard dont une image est rendue à l'écran.
L'imagerie d'arrière-plan, cependant, est une image qui est chargée via CSS et appliquée par le style. Pensez à une balise
background-image
insérée dessus. Ceci est généralement utilisé pour les images de grandes bannières avec des superpositions de texte.Dans les deux cas, ce que nous devons faire est de créer notre réponse HTML provenant du serveur pour prendre en charge une technique de traitement d'image paresseuse en Javascript.
Front- end Mechanics
La manière standard dont vous serviriez une image sur votre site Web serait d'implémenter une balise
comme ceci:
La triste réalité derrière cette balise d'image, c'est que dès que le client est le navigateur le voit – il tentera de charger l'actif à l'attribut src
. Même si cette image se trouve dans le pied de page d'une longue page, elle sera téléchargée immédiatement.
Pour empêcher ce téléchargement, ce que nous pouvons faire est de sortir le balisage d'une manière différente du côté serveur:
Remarque dans ce cas où nous n'avons pas produit du tout une propriété src. Au lieu de cela, nous sortons data-src. Le navigateur ne sait pas comment gérer cela et affiche généralement cette balise img sous la forme d'une "miniature cassée" (si nous l'avons autorisé). Parce que nous mettons une classe CSS de .lazy
sur l'image, nous pouvons styliser cette image pour qu'elle soit cachée au cas où quelqu'un la ferait défiler sans Javascript.
] Dans la section Head de votre document, ajoutez ceci à votre CSS critique:
Maintenant vient la partie amusante – nous devons exécuter un peu de Javascript côté client pour traiter nos images et tromper le navigateur en les chargeant à mesure qu'elles défilent dans la vue. Pour ce faire, utilisez un extrait de code comme celui-ci:
function lazyload () { if (lazyloadThrottleTimeout) { clearTimeout (lazyloadThrottleTimeout); } lazyloadThrottleTimeout = setTimeout (function () { var lazyElements = document.querySelectorAll (". lazy"); var scrollTop = window.pageYOffset; Array.prototype.forEach.call (lazyElements, function (elem) { // à moins de 100 pixels du bas de l'écran if (elem.offsetTop - 100 <(window.innerHeight + scrollTop)) { if (elem.dataset.src) { // trouve n'importe quel data-src et le change en src elem.src = elem.dataset.src; } elem.classList.remove ("paresseux"); } }); if (lazyElements.length == 0) { document.removeEventListener ("scroll", lazyload); window.removeEventListener ("redimensionner", lazyload); window.removeEventListener ("orientationChange", lazyload); } }, 20); } document.addEventListener ("scroll", lazyload); window.addEventListener ("redimensionner", lazyload); window.addEventListener ("orientationChange", lazyload); lazyload (); // allez-y et invoquez au chargement de la page
Dans ce cas, nous définissons une fonction lazyload ()
qui est utilisée comme rappel pour le scroll
resize
et orientationChange
événements. Nous invoquons également directement cette fonction lors du chargement de la page, juste au cas où des images différées se trouveraient au-dessus du pli. Tout ce que Javascript fait est une boucle à travers le DOM et trouve chaque élément avec une classe de paresseux
. Pour chaque objet trouvé, s'il se trouve dans la fenêtre, la classe lazy
est supprimée et data-src
est échangé contre src
. C'est le cœur des images de chargement paresseux, et à partir de maintenant, nous devons simplement élaborer nos réponses côté serveur en conséquence. En guise de note latérale intéressante, il peut être extrêmement difficile de déterminer la fenêtre d'affichage du périphérique client du côté serveur, je recommande donc uniquement les images à chargement paresseux situées après les premiers ~ 1000 pixels de la hauteur de l'écran.
Notez également que pour nos images de fond c'est la même technique. Nous devons prendre ce balisage:
et à la place, rendez-le ainsi:
Avec le CSS que nous avons inséré dans la tête de nos documents, la classe .lazy
prévaudra et forcera la propriété d'image d'arrière-plan à aucun! Important;
. 19659002] Techniques d'Episerver Back-end
Jusqu'à ce point, nous avons parlé de la façon de faire fonctionner le chargement paresseux sur le front-end. Cette technique s'applique à une grande variété de technologies Web et peut être réalisée avec une multitude de plates-formes. Tout ce que nous avons à faire est d'obtenir le back-end pour rendre le balisage en conséquence.
Heureusement dans Episerver, contrôler la manière dont les images sont rendues est incroyablement facile. Tout d'abord, nous devons nous assurer que nous avons créé un DisplayTemplate pour nos fichiers image: ~ / Views / Shared / DispalyTemplates / Image.cshtml
. Ce fichier indiquera à Episerver comment rendre le balisage d'une image. Dans mon cas, Image.cshtml
ressemble à ceci ( en supposant que nous suivons Alloy… ):
@using EPiServer.Editor @model ImageViewModel @if (Modèle! = null) { var lazy = ViewBag.lazy ?? vrai; if (PageEditing.PageIsInEditMode ||! lazy) {} autre {
} }
L'élément critique ici est que je passe un drapeau "paresseux" dans le ViewBag pour contrôler si l'image doit être chargée paresseusement ou non. Ceci est important pour les éléments tels que Heroes, où ils sont toujours présents au-dessus du pli et que vous voulez qu'ils se chargent aussi vite que possible.
Voici comment vous pouvez l'utiliser:
@ * Ne sera pas paresseux chargé ... * @ @ Html.PropertyFor (x => x.CriticalImage, new {lazy = false}) @ * Sera chargé paresseusement ... * @ @ Html.PropertyFor (x => x.LazyImage)
Correction du texte enrichi Episerver
Une chose à noter: l'éditeur Episerver Rich Text TinyMCE n'utilise pas les modèles d'affichage pour le rendu des images. Il a ses propres mécanismes internes pour ce faire. Heureusement, nous pouvons contourner ce problème en appliquant une technique similaire: création d'un modèle d'affichage pour les types de propriété XhtmlString
.
Create ~ / Views / Shared / DispalyTemplates / XhtmlString.cshtml
to prenez le contrôle de la façon dont le texte enrichi est rendu et ajoutez du code similaire à celui-ci:
@using EPiServer.Core @model XhtmlString @ Html.Raw (Model.FormatRichText (ViewContext))
À partir d'ici, notre méthode d'extension FormatRichText ()
peut gérer le rendu du balisage, saisir le résultat et l'ajuster avant de l'envoyer au client . J'utilise HtmlAgilityPack pour analyser le résultat HTML. Voici ma méthode d'extension:
classe statique publique XhtmlStringExtensions { ////// Analyse le XhtmlString pour les balises Image et les définit sur lazy load /// chaîne statique publique FormatRichText (ce XhtmlString html, contexte ViewContext) { // html est nul lorsque le TinyMce n'est pas initialisé (création d'un nouveau bloc, etc.) if (html == null) return string.Empty; // Chargez HtmlHelper d'Epi et demandez-lui de rendre les résultats var hh = new HtmlHelper (contexte, nouveau ViewPage ()); string epiRenderingResult; en utilisant (var writer = new StringWriter ()) { hh.ViewContext.Writer = écrivain; hh.RenderXhtmlString (html); écrivain.Flush (); epiRenderingResult = writer.ToString (); } if (PageEditing.PageIsInEditMode) return epiRenderingResult; // une fois les résultats rendus, chargez HtmlAgilityPack et faites-le analyser les résultats var doc = nouveau HtmlDocument (); doc.LoadHtml (epiRenderingResult); // trouve toutes les balises d'image, s'il n'y en a pas, retourne simplement - sinon nous devons les ajuster var imgs = doc.DocumentNode.SelectNodes ("// img"); si (imgs == null) return epiRenderingResult; // pour chaque image, remplacez src par data-src et lancez la classe "paresseuse" dessus foreach (var img dans imgs) { var src = img.Attributes ["src"] ?. Value; if (! string.IsNullOrEmpty (src)) { // pour prendre en charge le chargement paresseux, nous devons échanger src pour data-src // et injecter une classe de "paresseux". Javascript le prendra à partir de là img.SetAttributeValue ("données-src", src); img.Attributes.Remove ("src"); var css = img.Attributes ["class"] ?. Valeur; img.SetAttributeValue ("classe", $ "lazy {css}". Trim ()); } } var externalHtml = doc.DocumentNode.OuterHtml; return externalHtml; // retourne le nouveau HTML résultant } }
Enjoy 🙂
Source link