在数字时代,网站的访问速度已成为衡量用户体验和搜索引擎排名的关键指标之一。图片作为网页内容的重要组成部分,往往也是影响页面加载速度的主要因素。当一个页面包含大量高清图片时,浏览器在渲染页面前需要加载所有图片资源,这无疑会大大增加用户的等待时间。为了解决这一问题,图片懒加载(Lazy Loading)技术应运而生。
图片懒加载的核心思想是延迟加载非当前视口(即用户当前屏幕可见区域)内的图片。只有当图片即将进入或已经进入用户的视口时,才开始请求和加载其真实的图片资源。这种策略能够显著减少首次页面加载时的资源请求数量和数据传输量,从而加快页面渲染速度,节省用户带宽,尤其对于移动设备用户体验的提升效果更为明显,同时也有助于提升网站的SEO表现。
AnQiCMS 作为一款高效、可定制的企业级内容管理系统,在设计之初就充分考虑了网站性能优化。它提供了灵活的模板引擎语法,允许用户精细控制前端内容的展示,这为我们实现图片懒加载提供了极大的便利。
AnQiCMS 在内容区域的图片懒加载支持
AnQiCMS 的模板引擎语法类似 Django 模板,通过各种标签来控制内容的输出。对于文章详情页的内容区域,AnQiCMS 提供了一个非常便捷的内置懒加载机制。在显示文章内容时,我们可以利用 archiveDetail 标签的 lazy 参数,让系统自动将内容中图片的 src 属性替换为自定义的属性(例如 data-src),并插入一个占位符 src。
具体来说,当您在文章详情页使用 archiveDetail 标签来输出文档内容 Content 时,可以这样编写模板代码:
{% archiveDetail articleContent with name="Content" lazy="data-src" %}
{{ articleContent|safe }}
{% endarchiveDetail %}
在这段代码中,lazy="data-src" 参数会指示 AnQiCMS 模板引擎,在处理 articleContent 变量中的 HTML 内容时,查找所有的 <img> 标签。一旦找到,它会将原始的 src 属性值移动到一个名为 data-src 的属性中,并将 src 属性设置为一个默认的空白占位图片地址(通常是一个非常小的透明 GIF)。
例如,如果您的文章内容中原本有一张图片 <img src="https://www.anqicms.com/uploads/images/example.jpg" alt="示例图片">,经过 lazy="data-src" 处理后,输出到前端页面的 HTML 结构可能会变成:
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" data-src="https://www.anqicms.com/uploads/images/example.jpg" alt="示例图片">
此时,浏览器在渲染页面时只会加载那个极小的占位 GIF,而不会立即加载实际的 example.jpg。
扩展懒加载至其他图片元素
虽然 AnQiCMS 为文章内容区域提供了内置的懒加载处理,但一个网站的图片并不仅限于文章内容。例如,文章列表页的缩略图、产品详情页的封面图、分类页的 Banner 图片等,它们通常通过 archiveList、archiveDetail、pageDetail、categoryDetail 等标签直接获取 Logo、Thumb 或 Images 字段来显示。对于这些直接通过模板标签输出的图片,我们需要手动进行一些调整。
实现这些图片懒加载的通用步骤包括:
修改模板中的图片标签: 您需要找到所有直接输出图片(例如
Logo、Thumb字段)的<img>标签,手动将它们的src属性改为一个占位符,并将真实的图片地址存储到data-src属性中。 例如,一个原本显示文章缩略图的代码可能是:<img src="{{ item.Thumb }}" alt="{{ item.Title }}">您需要将其修改为:
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" data-src="{{ item.Thumb }}" alt="{{ item.Title }}">这里的
data:image/gif;base64,...是一个非常小的透明 GIF 图片,用作浏览器加载时的临时占位符。您也可以使用其他加载中的图片或自定义样式作为占位符。引入 JavaScript 懒加载逻辑: 下一步是添加 JavaScript 代码来监听这些带有
data-src属性的图片。当它们进入用户视口时,脚本会将data-src中的真实图片地址赋值给src属性,从而触发图片的加载。 一个简单且现代的实现方式是使用Intersection ObserverAPI,它能高效地检测元素何时进入或离开视口,而无需复杂的滚动事件监听。 您可以将以下 JavaScript 代码添加到您的模板文件(例如,通常在base.html文件的</body>标签之前,或者在单独的 JS 文件中并通过{% system with name="TemplateUrl" %}标签引入):<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>这段脚本会在页面加载完成后,遍历所有带有
data-src属性的<img>标签。如果浏览器支持Intersection Observer,它会创建一个观察器来监测这些图片。当图片进入视口时,观察器回调函数会将data-src的值赋给src,并停止观察该图片。对于不支持Intersection Observer的老旧浏览器,所有图片会立即加载,确保兼容性。可选的 CSS 优化: 为了更好地用户体验,您还可以为懒加载图片添加一些 CSS 样式。例如,给图片一个最小高度,防止图片加载前页面内容跳动,或添加一个背景色/加载动画。
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; }