当前位置: 首页 > news >正文

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> 标签上的 asyncdefer 属性来实现异步加载。

  • 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 延迟加载的方法

延迟加载&#xff08;Lazy Loading&#xff09;是一种优化网页性能的技术&#xff0c;它允许资源&#xff08;如图片、脚本等&#xff09;在需要时才被加载&#xff0c;而不是在页面初次加载时全部加载。这可以减少初始页面加载时间&#xff0c;提升用户体验&#xff0c;特别是…...

xrdp连接闪退情况之一

错误核查 首先使用命令vim ~/.xsession-errors&#xff0c;当里面的报错信息为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&#xff0c;更重要的是数据分析思维。没有数据分析思维和业务知识&#xff0c;就算拿到一堆数据&#xff0c;也不知道如何下手。 推荐书本《数据分析思维——分析方法和业务知识》&#xff0c;本文内容就是提取…...

WebRTC 在视频联网平台中的应用:开启实时通信新篇章

在当今这个以数字化为显著特征的时代浪潮之下&#xff0c;实时通信已然稳稳扎根于人们生活与工作的方方面面&#xff0c;成为了其中不可或缺的关键一环。回首日常生活&#xff0c;远程办公场景中的视频会议让分散各地的团队成员能够跨越地理距离的鸿沟&#xff0c;齐聚一堂共商…...

Vue3(elementPlus) el-table替换/隐藏行箭头,点击整行展开

element文档链接&#xff1a; https://element-plus.org/zh-CN/component/form.html 一、el-table表格行展开关闭箭头替换成加减号 注&#xff1a;Vue3在样式中修改箭头图标无效&#xff0c;可能我设置不对&#xff0c;欢迎各位来交流指导 转变思路&#xff1a;隐藏箭头&…...

oracle闪回恢复数据:(闪回查询,闪回表,闪回库,回收站恢复)

oracle的闪回查询&#xff0c;可以查询提交在表空间的闪回数据&#xff0c;并可以还原所查询的数据&#xff0c;用于恢复短时间内的delele 或者 update 误操作&#xff0c;非常方便&#xff0c;缺点是只能恢复大概几小时内的数据。 文章目录 概要闪回查询恢复数据的主要方法包括…...

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.什么是统计量&#xff08;记忆即可&#xff09;8.矩估计量9.117页12题10.显著水平阿尔法&#xff08;背公式就完了&#xff09; 判断题11.事件…...

Python视频处理:噪声矩阵与并行计算的完美融合

噪声级别对视频质量有显著的影响&#xff0c;主要体现在以下几个方面&#xff1a; 1. 视觉质量 低噪声级别&#xff1a;当噪声级别较低时&#xff0c;视频的视觉质量较好。噪声对图像细节的干扰较小&#xff0c;画面看起来较为清晰和自然。观众可以更容易地识别图像中的细节和…...

如何使用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作为核心算法框架&#xff0c;结合PyQt5构建用户界面&#xff0c;使用Python3进行开发。YOLOv8以其高效的实时检测能力&#xff0c;在多个目标检测任务中展现出卓越性能。本研究针对人员跌倒目标数据集进行训练和优化&#xff0c;该数据集包含丰富人员跌倒图像样…...

QT-TCP-server

为了实现高性能的TCP通讯&#xff0c;以下是一个基于Qt的示例&#xff0c;展示如何利用多个线程、非阻塞I/O、数据分块和自定义协议进行优化。该示例以TCP服务器和客户端的形式展示&#xff0c;能够承受高负载并实现快速数据传输。 高性能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&#xff5e;简单实现&#xff08;10 /100&#xff09; 【Flutter&Dart】 拖动边界线改变列宽并且有边界高亮和鼠标效果&#xff08;12 /100&#xff09; 上效果&#xff1a; 这个在知乎里找到的效果&…...

R语言的循环实现

以R语言的循环实现 引言 R语言作为一种强大的统计分析和数据可视化工具&#xff0c;广泛应用于数据科学、统计学和机器学习等领域。在R语言中&#xff0c;循环是一个基本的控制结构&#xff0c;用于重复执行一段代码。循环不仅可以提高代码的可读性&#xff0c;还可以方便地处…...

Web应用安全-漏洞扫描器设计与实现

摘 要 随着Web2.0、社交网络、微博等一系列新型的互联网产品的诞生&#xff0c;基于Web环境的互联网应用越来越广泛&#xff0c;企业信息化的过程中各种应用都架设在Web平台上。Web应用的迅速发展也引起黑客们的强烈关注&#xff0c;接踵而至的就是Web安全威胁的凸显&#xff…...

视频生成Sora的全面解析:从AI绘画、ViT到ViViT、TECO、DiT、VDT、NaViT等

前言 真没想到&#xff0c;距离视频生成上一轮的集中爆发(详见《Sora之前的视频生成发展史&#xff1a;从Gen2、Emu Video到PixelDance、SVD、Pika 1.0》)才过去三个月&#xff0c;没想OpenAI一出手&#xff0c;该领域又直接变天了 自打2.16日OpenAI发布sora以来(其开发团队包…...

【已解决】如何让容器内的应用程序使用代理?

首先&#xff0c;按照这种配置方法&#xff0c;即通过在 /etc/systemd/system/docker.service.d/http-proxy.conf 中设置代理&#xff0c;它只会影响 Docker 守护进程本身&#xff0c;并不会自动影响 Docker 容器内部的软件或容器中的网络行为。 这意味着&#xff1a; Docker …...

DC/AC并网逆变器模型与仿真MATLAB

DC/AC并网逆变器是一种将直流电&#xff08;DC&#xff09;转化为交流电&#xff08;AC&#xff09;&#xff0c;并将其与电网并联的设备。它的核心功能是实现直流电源&#xff08;如光伏电池板或储能电池&#xff09;与电网的有效连接&#xff0c;同时保证输出电能质量满足电网…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

Qt 事件处理中 return 的深入解析

Qt 事件处理中 return 的深入解析 在 Qt 事件处理中&#xff0c;return 语句的使用是另一个关键概念&#xff0c;它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别&#xff1a;不同层级的事件处理 方…...

自然语言处理——文本分类

文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益&#xff08;IG&#xff09; 分类器设计贝叶斯理论&#xff1a;线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别&#xff0c; 有单标签多类别文本分类和多…...