In the digital age, the speed of website access has become one of the key indicators for measuring user experience and search engine rankings.[en] Images are often an important component of web page content and can also be a major factor affecting page loading speed.When a page contains a large number of high-definition images, the browser needs to load all image resources before rendering the page, which undoubtedly will greatly increase the user's waiting time.In order to solve this problem, the Lazy Loading technology emerged.
The core idea of lazy loading images is to defer loading images that are not within the current viewport (i.e., the area currently visible to the user on the screen).Only when the image is about to enter or has already entered the user's viewport, should the request and loading of its actual image resource begin.This strategy can significantly reduce the number of resource requests and data transfer volume during the first page load, thereby accelerating the page rendering speed, saving user bandwidth, and having an even more pronounced effect on improving the user experience for mobile devices. At the same time, it also helps to enhance the SEO performance of the website.
AnQiCMS as an efficient and customizable enterprise-level content management system, has fully considered website performance optimization from the very beginning.It provides flexible template engine syntax, allowing users to finely control the display of front-end content, which greatly facilitates our implementation of lazy loading for images.
AnQiCMS supports lazy loading of images in the content area
The template engine syntax of AnQiCMS is similar to Django templates, controlling content output through various tags.For the content area of the article detail page, AnQiCMS provides a very convenient built-in lazy loading mechanism.archiveDetailTagslazyparameters, allowing the system to automatically replace image properties in the contentsrcwith custom properties (such as)data-src), and insert a placeholdersrc.
In particular, when you are usingarchiveDetailtags to output document contentContentin the article detail page, you can write the template code like this:
{% archiveDetail articleContent with name="Content" lazy="data-src" %}
{{ articleContent|safe }}
{% endarchiveDetail %}
In this code,lazy="data-src"The parameter will indicate the AnQiCMS template engine to processarticleContentWhen looking for HTML content in a variable, it searches for all the<img>tags. Once found, it moves the originalsrcattribute values to an attribute nameddata-src, and willsrcThe property is set to a default blank placeholder image URL (usually a very small transparent GIF).
For example, if there was an image in the original content of your article<img src="https://en.anqicms.com/uploads/images/example.jpg" alt="示例图片">afterlazy="data-src"After processing, the HTML structure that may be output to the front-end page might be:
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" data-src="https://en.anqicms.com/uploads/images/example.jpg" alt="示例图片">
At this moment, the browser will only load that tiny placeholder GIF while rendering the page, without immediately loading the actualexample.jpg.
Extend lazy loading to other image elements
Although AnQiCMS provides built-in lazy loading for the article content area, the images on a website are not limited to just the article content. For example, the thumbnails on the article list page, the cover images on the product detail page, the Banner images on the category page, etc., they are usually througharchiveList/archiveDetail/pageDetail/categoryDetailRetrieve directly using tagsLogo/ThumborImagesfield to display. For these images output directly through template tags, we need to make some manual adjustments.
Implementing these general steps for lazy loading images includes:
Modify the image tags in the template:You need to find all images that are directly output (for example
Logo/Thumbfields) of<img>the tags, and manually change theirsrcThe attribute is changed to a placeholder, and the actual image address is stored indata-srcthe attribute. For example, a code that originally displays an article thumbnail might be:<img src="{{ item.Thumb }}" alt="{{ item.Title }}">You need to modify it to:
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" data-src="{{ item.Thumb }}" alt="{{ item.Title }}">Here are the
data:image/gif;base64,...It is a very small transparent GIF image used as a temporary placeholder while the browser is loading. You can also use other loading images or custom styles as placeholders.Introduce JavaScript lazy loading logic:The next step is to add JavaScript code to listen for these with
data-srcThe image of the property. When they enter the user's viewport, the script will assign.data-srcthe actual image address to.srcAn attribute, thus triggering the loading of the image. A simple and modern implementation is to useIntersection ObserverAPI, it can efficiently detect when elements enter or leave the viewport without the need for complex scroll event listeners. You can add the following JavaScript code to your template file (for example, usually inbase.htmlthe file</body>Before the tag, or in a separate JS file and through{% system with name="TemplateUrl" %}tag import):<script> document.addEventListener('DOMContentLoaded', function() { const lazyImages = document.querySelectorAll('img[data-src]'); if ('IntersectionObserver' in window) { let lazyImageObserver = new IntersectionObserver(function(entries, observer) { entries.forEach(function(entry) { if (entry.isIntersecting) { let lazyImage = entry.target; lazyImage.src = lazyImage.dataset.src; // 如果有 srcset 属性也需要处理 if (lazyImage.dataset.srcset) { lazyImage.srcset = lazyImage.dataset.srcset; } lazyImage.removeAttribute('data-src'); lazyImage.removeAttribute('data-srcset'); lazyImageObserver.unobserve(lazyImage); } }); }); lazyImages.forEach(function(lazyImage) { lazyImageObserver.observe(lazyImage); }); } else { // Fallback for browsers that do not support Intersection Observer lazyImages.forEach(function(lazyImage) { lazyImage.src = lazyImage.dataset.src; if (lazyImage.dataset.srcset) { lazyImage.srcset = lazyImage.dataset.srcset; } lazyImage.removeAttribute('data-src'); lazyImage.removeAttribute('data-srcset'); }); } }); </script>This script will be traversed after the page is loaded, all with
data-srcattributes<img>tags. If the browser supportsIntersection ObserverIt will create an observer to monitor these images. When the images enter the viewport, the observer's callback function willdata-srctosrcand stop observing the image. For images that do not supportIntersection Observer[The old and outdated browsers, all images will load immediately to ensure compatibility.][Optional CSS optimization:]To enhance the user experience, you can also add some CSS styles for lazy-loaded images.For example, set a minimum height for images to prevent the page content from jumping before the image is loaded, or add a background color/loading animation.
img[data-src] { display: block; /* 避免图片下方出现空白 */ min-height: 100px; /* 预设一个最小高度,防止页面跳动 */ background-color: #f0f0f0; /* 占位背景色 */ /* background-image: url('/public/static/images/loading.gif'); */ /* 也可以添加加载动画 */ background-repeat: no-repeat; background-position: center; }