当前位置: 首页 > 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;同时保证输出电能质量满足电网…...

C++进阶--C++11--智能指针(重点)

文章目录 C进阶--智能指针&#xff08;重点&#xff09;智能指针使用的场景RAII和智能指针的设计思路C标准库智能指针的使用定制删除器智能指针的原理shared_ptr和weak_ptr循环引用&#xff08;容易考&#xff09;weak_ptr 其他知识扩展(类型转换)总结个人学习心得结语 很高兴和…...

免费批量PDF转Word工具

免费批量PDF转Word工具 工具简介 这是一款简单易用的批量PDF转Word工具&#xff0c;支持&#xff1a; 批量转换多个PDF文件保留原始格式和布局快速高效的转换速度完全免费使用 工具地址 下载链接 网盘下载地址&#xff1a;点击下载 提取码&#xff1a;8888 功能特点 ✅…...

Unity的日志管理类

脚本功能&#xff1a; 1&#xff0c;打印日志到控制台 2&#xff0c;显示日志到UI Text 3&#xff0c;将日志写入本地文件 这对unity开发安卓平台来说很有用 using System; using System.IO; using System.Text; using UnityEngine; using UnityEngine.UI;public class FileLo…...

PyTorch——损失函数与反向传播(8)

Loss Functions 越小越好 L1loss MSELoss 损失函数 CrossEntyopyLoss 损失函数 import torch from torch.nn import L1Loss from torch import nn# 创建输入和目标张量&#xff0c;用于后续的损失计算 inputs torch.tensor([1,2,3],dtypetorch.float32) targets torch.tenso…...

Go语言--语法基础5--基本数据类型--输入输出(1)

I : input 输入操作 格式化输入 scanf O &#xff1a; output 输出操作 格式化输出 printf 标准输入 》键盘设备 》 Stdin 标准输出 》显示器终端 》 Stdout 异常输出 》显示器终端 》 Stderr 1 、输入语句 Go 语言的标准输出流在打印到屏幕时有些参数跟别的语言…...

关于GitHub action云编译openwrt

特别声明:此教程仅你有成功离线编译的经验后,使用下列教程更佳 不建议没有任何成功经验的人进行云编译 1、准备工作 使用GitHub云编译模板 GitHub - jxjxcw/build_openwrt: 利用Actions在线云编译openwrt固件,适合官方源码,lede,lienol和immortalwrt源码,支持X86,电…...

Python训练营-Day22-Titanic - Machine Learning from Disaster

Description linkkeyboard_arrow_up &#x1f44b;&#x1f6f3;️ Ahoy, welcome to Kaggle! You’re in the right place. This is the legendary Titanic ML competition – the best, first challenge for you to dive into ML competitions and familiarize yourself w…...

Web前端基础:JavaScript

1.JS核心语法 1.1 JS引入方式 第一种方式&#xff1a;内部脚本&#xff0c;将JS代码定义在HTML页面中 JavaScript代码必须位于<script></script>标签之间在HTML文档中&#xff0c;可以在任意地方&#xff0c;放置任意数量的<script></script>一般会把…...

Bugku-CTF-Web安全最佳刷题路线

曾经的我也是CTF六项全能&#xff0c;Web安全&#xff0c;密码学&#xff0c;杂项&#xff0c;Pwn&#xff0c;逆向&#xff0c;安卓样样都会。明明感觉这样很酷&#xff0c;却为何还是沦为社畜。Bugku-CTF-Web安全最佳刷题路线&#xff0c;我已经整理好了&#xff0c;干就完了…...

MongoDB检查慢查询db.system.profile.find 分析各参数的作用

db.system.profile.find() 是分析 MongoDB 性能的关键工具,其返回的文档包含丰富的性能指标。下面是对各参数的详细解释和优化建议: {"op": "query", // 操作类型(query/update/remove)"ns": "test.users", // 命名…...