2. 圖片性能優化

圖片性能優化

圖片懶加載

  1. 如何判斷圖片出現在了當前視口 (即如何判斷我們能夠看到圖片)
  2. 如何控制圖片的加載

原生實現

<img src="shanyue.jpg" loading="lazy" />

loading="lazy" 延遲加載圖像,直到它和視口接近到一個計算得到的距離(由瀏覽器定義)。目的是在需要圖像之前,避免加載圖像所需要的網絡和存儲帶寬。這通常會提高大多數典型用場景中內容的性能。

  • lazy:對資源進行延遲加載。
  • eager:立即加載資源。
  • auto:瀏覽器自行判斷決定是否延遲加載資源。

通過相對計算獲取元素位置

圖片頂部到文檔頂部的距離 > 瀏覽器可視窗口高度 + 滾動條滾過的高度,此時的圖片就是不可見的,如果圖片頂部到文檔頂部的距離 < 瀏覽器可視窗口高度 + 滾動條滾過的高度那么該圖片就應該出現在可視區域內了。

但你還記得我們前面提到的注意事項嗎?如果用戶直接滑到頁面底部,那么這個判斷條件對所有的圖片都為真,還是會造成性能問題。所以我們要再加上一條判斷條件 圖片的高度 + 圖片頂部到文檔頂部的距離 > 滾動條滾過的高度,以確保圖片確實在可視區域內,而不只是被滑過。

  • 待加載圖片的高度:img.clientHeight
  • 圖片頂部到文檔頂部的距離:img.offsetTop
  • 瀏覽器窗口滾動過的距離:document.documentElement.scrollTopdocument.body.scrollTop
  • 瀏覽器可視窗口高度:document.documentElement.clientHeightwindow.innerHeight
const imgs = document.querySelectorAll('img')
function lazyLoad(imgs) {console.log('lazyLoad')// 瀏覽器可視窗口的高度const windowHeight = window.innerHeight// 可視窗口滾動過的距離const scrollHeight = document.documentElement.scrollTopfor (let i = 0; i < imgs.length; i++) {if (windowHeight + scrollHeight > imgs[i].offsetTop && imgs[i].clientHeight + imgs[i].offsetTop > document.documentElement.scrollTop && !imgs[i].src) {imgs[i].src = imgs[i].dataset.src}}
}
// 進入頁面時執行一次加載
lazyLoad(imgs)
// 監聽滾動事件,當滾動到可視區域時加載圖片
// 此處可以添加防抖/節流優化 window.onscroll = throttle(lazyLoad, 500)
window.onscroll = function () {lazyLoad(imgs)
}

Element.getBoundingClientRect()

getBoundingClientRect 返回值是一個 DOMRect 對象,這個對象是由該元素的 getClientRects() 方法返回的一組矩形的集合, 即:是與該元素相關的 CSS 邊框集合 。DOMRect 對象包含了一組用于描述邊框的只讀屬性——left、top、right 和 bottom,單位為像素。除了 width 和 height 外的屬性都是相對于視口的左上角位置而言的。

有了這個 API 后我們很同意獲取圖片的 top 值,當 top 值小于可視區的高度的時候就可以任何圖片進入了可視區,直接加載圖片即可。

document.addEventListener('DOMContentLoaded', () => {const lazyImages = document.querySelectorAll('img.lazyload')const lazyLoad = () => {lazyImages.forEach((img) => {if (img.getBoundingClientRect().top <= window.innerHeight && img.getBoundingClientRect().bottom >= 0 && getComputedStyle(img).display !== 'none') {img.src = img.dataset.srcimg.classList.remove('lazyload')}})if (lazyImages.length === 0) {document.removeEventListener('scroll', lazyLoad)window.removeEventListener('resize', lazyLoad)window.removeEventListener('orientationchange', lazyLoad)}}document.addEventListener('scroll', lazyLoad)window.addEventListener('resize', lazyLoad)window.addEventListener('orientationchange', lazyLoad)
})

使用 IntersectionObserver

<img data-src="xxx.jpg" class="lazyload" /><script>document.addEventListener('DOMContentLoaded', () => {const lazyImages = document.querySelectorAll('img.lazyload')if ('IntersectionObserver' in window) {const observer = new IntersectionObserver((entries, observer) => {entries.forEach((entry) => {if (entry.isIntersecting) {const image = entry.targetimage.src = image.dataset.srcimg.classList.remove('lazyload')observer.unobserve(image)}})})lazyImages.forEach((img) => {observer.observe(img)})} else {lazyImages.forEach((img) => {img.src = img.dataset.src})}})
</script>

監聽元素的重疊度 IntersectionObserver

var observer = new IntersectionObserver(callback[, options]); 

IntersectionObserverdisconnect()方法終止對所有目標元素可見性變化的觀察。

IntersectionObserverobserve() 方法向 IntersectionObserver
對象觀察的目標集合添加一個元素。一個觀察者有一組閾值和一個根(root),但是可以監視多個目標元素的可見性變化(遵循閾值和根的設置)。

IntersectionObservertakeRecords() 方法返回一個IntersectionObserverEntry 對象數組,每個對象包含目標元素自上次相交檢查以來所經歷的相交狀態變化——可以顯式地通過調用此方法或隱式地通過觀察器的回調獲得。

IntersectionObserverunobserve() 方法命令 IntersectionObserver停止對一個元素的觀察。

const ob = new IntersectionObserver( (entries) => {const entry = entries[0]if (entry.isIntersecting) {console.log('加載更多')}  },   {// root 監聽元素的祖先元素Element對象,其邊界盒將被視作視口。目標在根的可見區域的任何不可見部分都會被視為不可見。root: null,// rootMargin 一個在計算交叉值時添加至根的邊界盒 (bounding_box) 中的一組偏移量,類型為字符串 (string) ,可以有效的縮小或擴大根的判定范圍從而滿足計算需要。語法大致和 CSS 中的margin 屬性等同; 可以參考 intersection root 和 root margin 來深入了解 margin 的工作原理及其語法。默認值是"0px 0px 0px 0px"。// threshold 規定了一個監聽目標與邊界盒交叉區域的比例值,可以是一個具體的數值或是一組 0.0 到 1.0 之間的數組。若指定值為 0.0,則意味著監聽元素即使與根有 1 像素交叉,此元素也會被視為可見。若指定值為
1.0,則意味著整個元素都在可見范圍內時才算可見。threshold: 0   })const dom = document.querySelector('.loading') 
ob.observe(dom) 

使用庫

lazysizes、lazyload

圖片預加載

const images = ['https://picsum.photos/id/237/400/400.jpg?grayscale&blur=2','https://picsum.photos/id/238/400/400.jpg?grayscale&blur=2'
]function preloadImages(max = 3) {const _images = [...images]function loadImage() {const src = _images.shift()return new Promise((resolve, reject) => {const link = document.createElement('link')link.rel = 'preload'link.as = 'image'link.href = srcdocument.head.appendChild(link)link.onload = resolvelink.onerror = rejectsetTimeout(reject, 10000)})}function _loadImage() {loadImage().finally(() => {if (_images.length) {loadImage()}})}for (let i = 0; i < max; i++) {_loadImage()}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/895656.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/895656.shtml
英文地址,請注明出處:http://en.pswp.cn/news/895656.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

sql盲注腳本

在sqli-labs中的第8題無回顯可以嘗試盲注的手法獲取數據 發現頁面加載了3秒左右可以進行盲注 布爾盲注數據庫名 import requestsdef inject_database(url):datanamefor i in range(1,15):low 32high 128mid (low high) // 2while low < high:path "id1 and asci…

文字識別產品、文檔識別系統、表格識別API

文字識別技術讓文字錄入工作不再繁瑣。人工智能時代&#xff0c;文字識別接口產品運用先進的光學字符識別與圖像處理技術&#xff0c;衍生了一系列圖像文字快速提取的應用場景。無論是掃描文件、照片文字還是PDF文檔&#xff0c;文字識別接口都能輕松應對。支持對中文簡體、中文…

Python 依賴管理的革新——Poetry 深度解析

引言 在 Python 生態中&#xff0c;依賴管理一直是開發者關注的重要話題。從最初的 pip 和 virtualenv&#xff0c;到后來的 pipenv&#xff0c;Python 依賴管理工具不斷進化。而近年來&#xff0c;Poetry 作為一款集成包管理和虛擬環境管理的新興工具&#xff0c;逐漸獲得了廣…

springcloud集成gateway

本篇文章只介紹gateway模塊的搭建步驟&#xff0c;并無gateway詳細介紹 gateway詳解請查看&#xff1a;SpringCloudGateway官方文檔詳解 前置處理 父模塊中已指定版本 不知道如何選擇版本看這篇&#xff1a; 手把手教你梳理springcloud與springboot與springcloudalibaba的版本…

【Elasticsearch】文本分析Text analysis概述

文本分析概述 文本分析使 Elasticsearch 能夠執行全文搜索&#xff0c;搜索結果會返回所有相關的結果&#xff0c;而不僅僅是完全匹配的結果。 如果你搜索“Quick fox jumps”&#xff0c;你可能希望找到包含“A quick brown fox jumps over the lazy dog”的文檔&#xff0c…

建筑兔零基礎自學python記錄22|實戰人臉識別項目——視頻人臉識別(下)11

這次我們繼續解讀代碼&#xff0c;我們主要來看下面兩個部分&#xff1b; 至于人臉識別成功的要點我們在最后總結~ 具體代碼學習&#xff1a; #定義人臉名稱 def name():#預學習照片存放位置path M:/python/workspace/PythonProject/face/imagePaths[os.path.join(path,f) f…

二〇二四年終總結

寫在前面 簡單總結一下告訴自己&#xff0c;曾經活著 不必太糾結于當下&#xff0c;也不必太憂慮未來&#xff0c;當你經歷過一些事情的時候&#xff0c;眼前的風景已經和從前不一樣了。——村上春樹 原本應該 24 年年中的時候寫 23 年年終的總結&#xff0c;但是一直拖著&…

LabVIEW太陽能制冷監控系統

在全球能源需求日益增長的背景下&#xff0c;太陽能作為一種無限再生能源&#xff0c;被廣泛應用于各種能源系統中。本基于LabVIEW軟件和STM32F105控制器的太陽能制冷監控系統的設計與實現&#xff0c;提供一個高效、經濟的太陽能利用方案&#xff0c;以應對能源消耗的挑戰。 項…

Node.js中的npm包:從入門到實踐指南

目錄 一、npm的核心概念 二、npm核心命令與工作流 三、package.json深度解析 四、高級技巧與最佳實踐 五、常見問題解決方案 六、未來趨勢 在Node.js生態中&#xff0c;npm&#xff08;Node Package Manager&#xff09; 是開發者不可或缺的工具。它不僅是全球最大的開源軟…

AIGC圖生視頻保姆級教程

一、AI文生圖高階技巧 推薦工具 ? MidJourney&#xff08;藝術感最強&#xff09; ? DALLE 3&#xff08;與ChatGPT深度聯動&#xff09; ? Leonardo.ai&#xff08;精細化參數控制&#xff09; 核心策略 提示詞架構&#xff1a; [主體描述][環境氛圍][鏡頭語言][風格參數…

嵌入式EasyRTC實時通話支持海思hi3516cv610,編譯器arm-v01c02-linux-musleabi-gcc

EasyRTC已經完美支持海思hi3516cv610&#xff0c;編譯器arm-v01c02-linux-musleabi-gcc&#xff0c;總體SDK大小控制在680K以內&#xff08;預計還能壓縮100K上下&#xff09;&#xff1a; EasyRTC在hi3516cv610芯片上能雙向通話、發送文字以及二進制指令&#xff0c;總體運行…

力扣做題記錄 (二叉樹)

二叉樹 打算先來了解二叉樹基礎&#xff0c;都是簡單題&#xff0c;目的是熟悉代碼格式和解題基礎思路。 1、二叉樹最大深度 二叉樹最大深度 方法一、深度搜索 直接用原函數做遞歸&#xff0c;比較簡單 /*** Definition for a binary tree node.* struct TreeNode {* …

如何下載Qt和運行第一個程序。

Ubuntu24.04 下載比較容易&#xff0c;基本都是無腦操作。途中匯出現有個別package下載不成功的情況&#xff0c;重新下載即可。 文章目錄 下載qt運行qt第一個項目 下載qt 1.先找到官網&#xff0c;點擊Download。 2.然后選擇&#xff0c;community User 3.然后會跳轉到這個…

HCIA項目實踐--靜態路由的拓展配置

7.7 靜態路由的拓展配置 網絡中的兩個重要思想&#xff1a; &#xff08;1&#xff09; 實的不行來虛的&#xff1b; &#xff08;2&#xff09; 范圍太大&#xff0c;劃分范圍。&#xff08;分治&#xff09; 7.7.1 負載均衡 &#xff08;1&#xff09;定義 負載均衡是一種網…

Base64 PDF解析器

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Base64 PDF解析器</title><style>body {font-family: Arial, sans-serif;max-width: 800px;margin: 20px auto;padding: 20px;}.contain…

基于51單片機的的雞籠補光和恒溫系統的設計與實現(源程序+Protues仿真+電路圖+元件清單+器件手冊)

編號&#xff1a;71 基于51單片機的的雞籠補光和恒溫系統的設計與實現 功能描述&#xff1a; 本設計由89C52單片機液晶12864顯示模塊聲光報警電路溫濕度傳感器電路風扇電路LED照明電路光照檢測電路GSM電路DS1302時鐘電路 1.實現的功能 (1)采用DHT11溫濕傳感器、光敏電阻捕捉…

Spring——Spring開發實戰經驗(1)

摘要 文章主要介紹了 Swagger 作為 API 文檔生成和測試工具的功能&#xff0c;包括自動生成 API 文檔、提供可視化調試界面、促進前后端協作、支持 OpenAPI 規范等。同時&#xff0c;還提及了 Spring Boot 與 Swagger3 的實戰應用&#xff0c;以及 Spring 開發中其他相關技術內…

SAP-ABAP:SAP的Screen Layout Designer屏幕布局設計器詳解及示例

在SAP中&#xff0c;Screen Layout Designer&#xff08;屏幕布局設計器&#xff09;是用于設計和維護屏幕&#xff08;Dynpro&#xff09;布局的工具。通過Screen Layout Designer&#xff0c;您可以創建和修改屏幕元素&#xff08;如輸入字段、按鈕、文本、表格控件等&#x…

安全筑基,智能賦能:BeeWorks IM引領企業協同新紀元

在數字經濟高速發展的今天&#xff0c;企業通訊系統已從單純的信息傳遞工具演變為支撐業務創新的核心平臺。傳統通訊工具在安全性、智能化、協同性等方面的不足&#xff0c;嚴重制約著企業的數字化轉型進程。BeeWorks IM系統以其創新的技術架構和智能化功能&#xff0c;正在重新…

SpringBoot實戰:高效獲取視頻資源

文章目錄 前言技術實現SpringBoot項目構建產品選取配置數據采集 號外號外 前言 在短視頻行業高速發展的背景下&#xff0c;海量內容數據日益增長&#xff0c;每天都有新的視頻、評論、點贊、分享等數據涌現。如何高效、精準地獲取并處理這些龐大的數據&#xff0c;已成為各大平…