JavaScript 延迟加载的方法
延迟加载(Lazy Loading)是一种优化网页性能的技术,它允许资源(如图片、脚本等)在需要时才被加载,而不是在页面初次加载时全部加载。这可以减少初始页面加载时间,提升用户体验,特别是在移动设备或网络条件不佳的情况下。以下是几种常见的 JavaScript 延迟加载方法:
1. 图片的延迟加载
使用 loading 属性
现代浏览器支持原生的图片延迟加载功能,通过为 <img> 标签添加 loading="lazy" 属性即可实现。
<img src="image.jpg" alt="Description of image" loading="lazy">
这种方法简单易用,且不需要额外的 JavaScript 代码。
自定义 JavaScript 实现
如果需要更复杂的控制或者兼容性考虑,可以使用 JavaScript 来检测元素是否进入视口,并在适当的时候加载图片。
示例代码:
function lazyLoadImages() {const images = document.querySelectorAll('img[data-src]');const config = {rootMargin: '0px',threshold: 0.1 // 当图片底部有10%进入视口时开始加载};let observer;function preloadImage(img) {const source = img.getAttribute('data-src');if (!source) return;img.src = source;img.removeAttribute('data-src');}function handleIntersect(entries, observer) {entries.forEach(entry => {if (entry.isIntersecting) {preloadImage(entry.target);observer.unobserve(entry.target);}});}if ('IntersectionObserver' in window) {observer = new IntersectionObserver(handleIntersect, config);images.forEach(image => {observer.observe(image);});} else {// Fallback for browsers that do not support IntersectionObserverimages.forEach(image => {preloadImage(image);});}
}// Call the function on page load or when needed
document.addEventListener('DOMContentLoaded', lazyLoadImages);
2. 脚本的延迟加载
使用 async 和 defer 属性
对于外部 JavaScript 文件,可以通过设置 <script> 标签上的 async 或 defer 属性来实现异步加载。
async:尽可能早地下载脚本并在下载完成后立即执行,不会阻塞 DOM 解析。defer:脚本会在 HTML 文档解析完成后但DOMContentLoaded事件触发前按顺序执行。
<script src="script.js" async></script>
<script src="another-script.js" defer></script>
动态插入脚本
另一种方法是通过 JavaScript 动态创建并插入 <script> 元素,从而实现更灵活的控制。
示例代码:
function loadScript(src, callback) {const script = document.createElement('script');script.src = src;script.onload = () => callback && callback();document.body.appendChild(script);
}// Usage example
loadScript('https://example.com/script.js', () => {console.log('External script loaded and executed.');
});
3. 框架和库
利用现有的前端框架(如 Vue.js、React 等)提供的组件懒加载机制,可以在路由切换或其他特定条件下加载组件及其依赖项。此外,还有专门用于处理资源延迟加载的第三方库,例如 Lozad.js 或 lazysizes。
4. CSS 资源的延迟加载
虽然 CSS 通常不是延迟加载的重点,但在某些情况下也可以考虑延迟加载非关键路径上的样式表。一种方式是将这些样式表放在媒体查询中,只有当满足特定条件时才会加载。
<link rel="stylesheet" href="print.css" media="print">
<link rel="stylesheet" href="mobile.css" media="(max-width: 768px)">
5. Intersection Observer API
虽然之前已经提到过 Intersection Observer API 可以用来实现图片的懒加载,但它的应用远不止于此。它也可以用于监听任何 DOM 元素何时进入或离开视口,并根据这个事件触发相应的操作。
示例:延迟加载视频
const videos = document.querySelectorAll('video[data-src]');if ('IntersectionObserver' in window) {const videoObserver = new IntersectionObserver((entries, observer) => {entries.forEach(entry => {if (entry.isIntersecting) {const video = entry.target;video.src = video.getAttribute('data-src');video.play();observer.unobserve(video);}});});videos.forEach(video => {videoObserver.observe(video);});
}
6. Link Prefetching 和 Preloading
-
Prefetch:通过
<link rel="prefetch">提前下载用户可能需要的资源,例如下一个页面的 HTML、CSS 或 JavaScript 文件。这可以在后台悄悄进行,当用户导航到该页面时,资源已经准备好。 -
Preload:使用
<link rel="preload">强制浏览器优先加载指定资源,确保它们尽早可用。这对于关键路径上的资源特别有用,比如字体或重要的样式表。
<!-- Prefetch -->
<link rel="prefetch" href="/next-page.html"><!-- Preload -->
<link rel="preload" href="critical-font.woff2" as="font" type="font/woff2" crossorigin>
7. 动态导入(Dynamic Imports)
动态导入允许你按需加载模块,而不是在应用程序启动时全部加载。这对于大型单页应用(SPA)尤其重要,因为它可以帮助减少初始加载时间。
示例代码:
// Traditional import
import('./module.js').then(module => {// Use the imported module
});// Conditional dynamic import
if (condition) {import('./optional-module.js').then(optionalModule => {// Do something with optionalModule});
}// In a function or event handler
function loadFeature() {return import('./feature.js');
}document.getElementById('featureButton').addEventListener('click', () => {loadFeature().then(feature => {feature.init();});
});
8. Code Splitting
对于使用打包工具(如 Webpack)构建的应用程序,可以通过代码分割(Code Splitting)来将应用程序拆分为多个小块,只在需要时加载特定的部分。这样不仅可以减小初始加载量,还能提高缓存效率。
- Webpack 动态导入:结合
import()语法和 Webpack 的魔法注释(magic comments),可以精确控制哪些部分应该被打包在一起以及如何异步加载。
// Webpack magic comment for splitting chunks
const moduleA = 'module-a';
import(/* webpackChunkName: "chunk-name" */ `./${moduleA}`).then(({ default: mod }) => {console.log(mod);
});
9. 骨架屏(Skeleton Screens)
不是传统意义上的“延迟加载”,但骨架屏是一种用户体验设计模式,它在实际内容加载之前显示一个简化版的界面布局。这种方法可以让用户感觉页面加载速度更快,即使实际上数据还在加载中。
<div class="skeleton"><div class="skeleton__image"></div><div class="skeleton__text"></div>
</div><script>
// Replace skeleton screen with actual content once loaded
fetch('/content').then(response => response.json()).then(data => {document.querySelector('.skeleton').innerHTML = `<img src="${data.imageUrl}" alt="Image"><p>${data.text}</p>`;});
</script>
10. Service Workers
服务工作者(Service Workers)是运行在浏览器后台进程中的脚本,它们可以在没有网络连接的情况下提供离线访问功能。通过预缓存静态资源并在请求时从缓存中提供这些资源,可以有效减少对服务器的压力并加速页面加载。
注册 Service Worker 并缓存资源:
if ('serviceWorker' in navigator) {window.addEventListener('load', () => {navigator.serviceWorker.register('/sw.js').then(registration => {console.log('Service Worker registered with scope:', registration.scope);}).catch(error => {console.log('Service Worker registration failed:', error);});});
}
在 Service Worker 文件 (sw.js) 中定义缓存逻辑:
const CACHE_NAME = 'my-site-cache-v1';
const urlsToCache = ['/','/styles/main.css','/script/app.js'
];self.addEventListener('install', event => {event.waitUntil(caches.open(CACHE_NAME).then(cache => cache.addAll(urlsToCache)));
});self.addEventListener('fetch', event => {event.respondWith(caches.match(event.request).then(response => response || fetch(event.request)));
});
总结
延迟加载不仅仅局限于图片和脚本,还可以应用于各种类型的资源和场景。利用现代浏览器提供的新特性(如 Intersection Observer、动态导入等),结合传统的优化手段(如 Prefetch 和 Preload),可以构建出更加高效且响应迅速的 Web 应用。此外,考虑到用户体验,采用骨架屏或 Service Workers 等技术也能为用户提供更好的浏览体验。
相关文章:
JavaScript 延迟加载的方法
延迟加载(Lazy Loading)是一种优化网页性能的技术,它允许资源(如图片、脚本等)在需要时才被加载,而不是在页面初次加载时全部加载。这可以减少初始页面加载时间,提升用户体验,特别是…...
xrdp连接闪退情况之一
错误核查 首先使用命令vim ~/.xsession-errors,当里面的报错信息为WARNING **: Could not make bus activated clients aware of XDG_CURRENT_DESKTOPGNOME environment variable:Failed to execute child process “dbus-launch” (No such file or directory)&am…...
数据分析思维(八):分析方法——RFM分析方法
数据分析并非只是简单的数据分析工具三板斧——Excel、SQL、Python,更重要的是数据分析思维。没有数据分析思维和业务知识,就算拿到一堆数据,也不知道如何下手。 推荐书本《数据分析思维——分析方法和业务知识》,本文内容就是提取…...
WebRTC 在视频联网平台中的应用:开启实时通信新篇章
在当今这个以数字化为显著特征的时代浪潮之下,实时通信已然稳稳扎根于人们生活与工作的方方面面,成为了其中不可或缺的关键一环。回首日常生活,远程办公场景中的视频会议让分散各地的团队成员能够跨越地理距离的鸿沟,齐聚一堂共商…...
Vue3(elementPlus) el-table替换/隐藏行箭头,点击整行展开
element文档链接: https://element-plus.org/zh-CN/component/form.html 一、el-table表格行展开关闭箭头替换成加减号 注:Vue3在样式中修改箭头图标无效,可能我设置不对,欢迎各位来交流指导 转变思路:隐藏箭头&…...
oracle闪回恢复数据:(闪回查询,闪回表,闪回库,回收站恢复)
oracle的闪回查询,可以查询提交在表空间的闪回数据,并可以还原所查询的数据,用于恢复短时间内的delele 或者 update 误操作,非常方便,缺点是只能恢复大概几小时内的数据。 文章目录 概要闪回查询恢复数据的主要方法包括…...
C语言——结构体,位段,枚举和联合
目录 前言 结构体 1含义 2语法 3匿名结构体 4结构体自引用 5结构体的定义与初始化 6内存对齐 7修改对齐数 8结构体传参 位段 1含义 2位段的内存分配 编辑3位段的问题 4位段的应用 枚举 1含义 2定义 3枚举优点 4枚举使用 联合 1含义 2定义 3特点 4计…...
期末概率论总结提纲(仅适用于本校,看文中说明)
文章目录 说明A选择题1.硬币2.两个事件的关系 与或非3.概率和为14.概率密度 均匀分布5.联合分布率求未知参数6.联合分布率求未知参数7.什么是统计量(记忆即可)8.矩估计量9.117页12题10.显著水平阿尔法(背公式就完了) 判断题11.事件…...
Python视频处理:噪声矩阵与并行计算的完美融合
噪声级别对视频质量有显著的影响,主要体现在以下几个方面: 1. 视觉质量 低噪声级别:当噪声级别较低时,视频的视觉质量较好。噪声对图像细节的干扰较小,画面看起来较为清晰和自然。观众可以更容易地识别图像中的细节和…...
如何使用SparkSql
一、SparkSql的前世今生 Hive->Shark->Spark SQL 二、SparkSql依赖 <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-sql_2.11</artifactId> <version>2.1.2</version> </dependency> 三、…...
YOLOv8实战人员跌倒检测
本文采用YOLOv8作为核心算法框架,结合PyQt5构建用户界面,使用Python3进行开发。YOLOv8以其高效的实时检测能力,在多个目标检测任务中展现出卓越性能。本研究针对人员跌倒目标数据集进行训练和优化,该数据集包含丰富人员跌倒图像样…...
QT-TCP-server
为了实现高性能的TCP通讯,以下是一个基于Qt的示例,展示如何利用多个线程、非阻塞I/O、数据分块和自定义协议进行优化。该示例以TCP服务器和客户端的形式展示,能够承受高负载并实现快速数据传输。 高性能TCP Server示例 #include <QTcpSe…...
【STM32+QT项目】基于STM32与QT的智慧粮仓环境监测与管理系统设计(完整工程资料源码)
视频演示: 基于STM32与QT的智慧粮仓环境监测与管理系统设计 目录: 目录 视频演示: 目录: 前言:...
robot 仿真环境安装测试 [持续更新]
将持续更新各种robot simulation环境的安装过程. RLBench 安装CoppeliaSim、PyRep、RLBench git: https://github.com/stepjam/RLBench/tree/master (1)CoppeliaSim sudo gedit ~/.bashrc设置环境变量 export COPPELIASIM_ROOT=${HOME}/CoppeliaSim export LD_LIBRARY_…...
【FlutterDart】 拖动边界线改变列宽类似 vscode 那种拖动改变编辑框窗口大小(11 /100)
【Flutter&Dart】 拖动改变 widget 的窗口尺寸大小GestureDetector~简单实现(10 /100) 【Flutter&Dart】 拖动边界线改变列宽并且有边界高亮和鼠标效果(12 /100) 上效果: 这个在知乎里找到的效果&…...
R语言的循环实现
以R语言的循环实现 引言 R语言作为一种强大的统计分析和数据可视化工具,广泛应用于数据科学、统计学和机器学习等领域。在R语言中,循环是一个基本的控制结构,用于重复执行一段代码。循环不仅可以提高代码的可读性,还可以方便地处…...
Web应用安全-漏洞扫描器设计与实现
摘 要 随着Web2.0、社交网络、微博等一系列新型的互联网产品的诞生,基于Web环境的互联网应用越来越广泛,企业信息化的过程中各种应用都架设在Web平台上。Web应用的迅速发展也引起黑客们的强烈关注,接踵而至的就是Web安全威胁的凸显ÿ…...
视频生成Sora的全面解析:从AI绘画、ViT到ViViT、TECO、DiT、VDT、NaViT等
前言 真没想到,距离视频生成上一轮的集中爆发(详见《Sora之前的视频生成发展史:从Gen2、Emu Video到PixelDance、SVD、Pika 1.0》)才过去三个月,没想OpenAI一出手,该领域又直接变天了 自打2.16日OpenAI发布sora以来(其开发团队包…...
【已解决】如何让容器内的应用程序使用代理?
首先,按照这种配置方法,即通过在 /etc/systemd/system/docker.service.d/http-proxy.conf 中设置代理,它只会影响 Docker 守护进程本身,并不会自动影响 Docker 容器内部的软件或容器中的网络行为。 这意味着: Docker …...
DC/AC并网逆变器模型与仿真MATLAB
DC/AC并网逆变器是一种将直流电(DC)转化为交流电(AC),并将其与电网并联的设备。它的核心功能是实现直流电源(如光伏电池板或储能电池)与电网的有效连接,同时保证输出电能质量满足电网…...
51单片机波形发生器DIY:从DAC0832到LM358,手把手教你输出四种标准波形
51单片机波形发生器实战:从芯片选型到信号调理的全链路解析 在电子设计领域,波形发生器是验证电路性能的基础工具。市售成品动辄上千元的价格让许多爱好者望而却步,而基于51单片机的DIY方案不仅成本可控,更能深入理解数字到模拟转…...
3分钟搞定Axure中文界面:免费汉化终极指南
3分钟搞定Axure中文界面:免费汉化终极指南 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP的英文界面…...
如何快速配置AI文献助手:5步完成智能学术管理
如何快速配置AI文献助手:5步完成智能学术管理 【免费下载链接】zotero-gpt GPT Meet Zotero. 项目地址: https://gitcode.com/gh_mirrors/zo/zotero-gpt 在当今数字化学术研究环境中,Zotero-GPT插件通过深度集成OpenAI的GPT模型,为学术…...
Windows更新修复神器:Reset Windows Update Tool智能诊断与深度修复全攻略
Windows更新修复神器:Reset Windows Update Tool智能诊断与深度修复全攻略 【免费下载链接】Reset-Windows-Update-Tool Troubleshooting Tool with Windows Updates (Developed in Dev-C). 项目地址: https://gitcode.com/gh_mirrors/re/Reset-Windows-Update-To…...
SAP ME21N采购订单增强报错?手把手教你调试ME_PROCESS_PO_CUST(附完整代码)
SAP ME21N采购订单增强报错全流程诊断指南 当SAP系统中的ME21N采购订单增强突然报错时,那种面对红色错误消息却无从下手的挫败感,每个ABAP开发者都深有体会。不同于普通的程序错误,ME_PROCESS_PO_CUST这类标准增强点的报错往往涉及采购订单核…...
电力行业新手必看:645协议与698协议的区别及实际应用场景解析
电力行业通信协议实战指南:645与698协议的核心差异与应用解析 刚入行的电力系统工程师们,是否曾被各种通信协议搞得晕头转向?面对DL/T645和698协议时,是否疑惑过它们究竟有什么区别,又该在什么场景下使用?今…...
Krita AI Diffusion插件企业级部署与运维指南:从零搭建稳定AI绘画工作流
Krita AI Diffusion插件企业级部署与运维指南:从零搭建稳定AI绘画工作流 【免费下载链接】krita-ai-diffusion Streamlined interface for generating images with AI in Krita. Inpaint and outpaint with optional text prompt, no tweaking required. 项目地址…...
TensorFlow 2.x与Keras完美融合:构建深度学习模型的终极教程
TensorFlow 2.x与Keras完美融合:构建深度学习模型的终极教程 【免费下载链接】TensorFlow Project containig related material for my TensorFlow articles 项目地址: https://gitcode.com/gh_mirrors/ten/TensorFlow 想要快速掌握TensorFlow 2.x与Keras的完…...
LangGraph从入门到精通(二)——构建你的第一个有状态智能体
1. 环境准备与基础概念回顾 在开始构建有状态智能体之前,我们需要先确保开发环境就绪。我推荐使用Python 3.10版本,这个版本在稳定性和新特性支持上达到了很好的平衡。安装LangGraph非常简单,只需要一条命令: pip install langgra…...
终极热键侦探指南:3分钟找出Windows快捷键冲突元凶 [特殊字符]️♂️
终极热键侦探指南:3分钟找出Windows快捷键冲突元凶 🕵️♂️ 【免费下载链接】hotkey-detective A small program for investigating stolen key combinations under Windows 7 and later. 项目地址: https://gitcode.com/gh_mirrors/ho/hotkey-detect…...
