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)
    {
        
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
{
    /// 
    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

