文章目录
前端能够做哪些图片优化?
1、减小图片体积
压缩图片可以减小文件大小,提升页面加载速度。可以使用工具如 TinyPNG 或 ImageOptim 来优化图片。
2、图片缓存
浏览器缓存是最基础的前端缓存方式。通过设置HTTP响应头,指定缓存策略,可以控制浏览器对图片资源的缓存行为。
Cache-Control: 设置图片的缓存时长。例如,Cache-Control: max-age=31536000表示缓存一年。
Expires: 指定缓存过期日期,配合Cache-Control使用。
ETag 和 Last-Modified: 标记资源的版本号或最后修改时间,当浏览器再次请求该资源时,通过对比判断是否需要重新下载。
这些头信息可以在服务器端配置,常用于CDN或静态资源服务器。
服务工作线程 (Service Workers)缓存
Service Workers是一种更高级的缓存方式,通过注册Service Worker脚本,可以拦截图片请求并从缓存中返回内容。可以在应用初始化时加载图片资源并存储在Service Worker的缓存中,后续请求可以直接读取缓存内容。
// 安装阶段(Install Event),当 Service Worker 安装时触发
self.addEventListener('install', event =>{// 使用 event.waitUntil 确保安装过程完成后才继续执行后续的步骤
event.waitUntil(// 打开一个名为 'image-cache' 的缓存存储
caches.open('image-cache').then(cache =>{// 将图片资源添加到缓存中return cache.addAll(['/images/photo1.jpg',// 图片1'/images/photo2.jpg',// 图片2// 更多图片资源可以添加在这里...]);}));});// 激活阶段,拦截网络请求并返回缓存数据(Fetch Event)
self.addEventListener('fetch', event =>{// 判断请求是否是图片资源if(event.request.destination ==='image'){// event.respondWith 接受一个 Promise,返回响应数据
event.respondWith(// 尝试从缓存中匹配请求
caches.match(event.request).then(response =>{// 如果缓存中存在图片,直接返回缓存的响应return response ||// 如果缓存中没有对应的图片,则执行网络请求fetch(event.request).then(fetchResponse =>{// 一旦网络请求返回图片数据,就将其缓存return caches.open('image-cache').then(cache =>{// 将网络获取的图片存入缓存
cache.put(event.request, fetchResponse.clone());// 返回从网络获取的图片响应return fetchResponse;});});}));}});
IndexDB缓存图片
IndexedDB一个适合存储较大数据(如图片二进制数据)的浏览器数据库。要存储图片,我们通常将图片文件转换为 Blob(二进制大对象),并存入 IndexedDB。这样,在后续需要加载缓存图片时,可以从 IndexedDB 中检索 Blob,然后将其转化为 URL 以加载到页面中。
初始化 IndexedDB 数据库和对象存储
// 初始化 IndexedDBfunctionopenDatabase(){returnnewPromise((resolve, reject)=>{const request = indexedDB.open('imageCacheDB',1);// 创建或更新数据库时触发
request.onupgradeneeded=function(event){const db = event.target.result;if(!db.objectStoreNames.contains('images')){
db.createObjectStore('images');// 创建名为 "images" 的对象存储}};
request.onsuccess=function(event){resolve(event.target.result);// 成功打开数据库};
request.onerror=function(event){reject(event.target.error);// 打开数据库失败};});}
将图片存储到 IndexedDB 中
// 将图片 Blob 存入 IndexedDBfunctioncacheImage(url, blob){openDatabase().then(db =>{const transaction = db.transaction('images','readwrite');const store = transaction.objectStore('images');
store.put(blob, url);// 使用图片 URL 作为键
transaction.oncomplete=()=>{console.log('Image cached in IndexedDB');};}).catch(error =>{console.error('Failed to cache image:', error);});}// 获取图片并缓存functionfetchAndCacheImage(url){fetch(url).then(response => response.blob()).then(blob =>{cacheImage(url, blob);// 缓存图片}).catch(error =>{console.error('Failed to fetch image:', error);});}
从 IndexedDB 中读取图片并显示
当需要显示图片时,可以从 IndexedDB 读取 Blob 数据并生成一个 URL 给 标签使用
// 从 IndexedDB 中获取图片 BlobfunctiongetCachedImage(url){returnnewPromise((resolve, reject)=>{openDatabase().then(db =>{const transaction = db.transaction('images','readonly');const store = transaction.objectStore('images');const request = store.get(url);
request.onsuccess=function(event){if(event.target.result){resolve(event.target.result);// 返回图片 Blob}else{reject('Image not found in cache');}};
request.onerror=function(){reject('Failed to retrieve image from IndexedDB');};});});}// 使用缓存图片显示到页面functiondisplayImageFromCache(url, imgElementId){getCachedImage(url).then(blob =>{const imgURL =URL.createObjectURL(blob);
document.getElementById(imgElementId).src = imgURL;}).catch(error =>{console.error('Error displaying cached image:', error);});}// 示例调用const imageUrl ='https://example.com/image.jpg';fetchAndCacheImage(imageUrl);// 首次获取并缓存displayImageFromCache(imageUrl,'myImage');// 从缓存中显示图片
LocalStorage缓存
// 保存图片到 localStoragefunctioncacheImage(url){fetch(url).then(response => response.blob()).then(blob =>{const reader =newFileReader();
reader.onload=function(){
localStorage.setItem('cachedImage', reader.result);// 将Base64数据存入localStorage};
reader.readAsDataURL(blob);});}
3、图片懒加载
懒加载和占位图也是提升前端图片加载性能的技巧,虽然不算是严格意义的缓存。懒加载会等到图片在视窗中出现时才开始加载,减少初始页面加载的资源量,占位图则在图片未加载完成前提供一个小尺寸、模糊的占位图,让页面看起来更平滑。
假设你有多个图片,添加 data-src 属性存储图片的实际 URL,src 属性设置为占位符(比如一张模糊的小图或空白图片),这样只有当图片进入视口时,才会加载实际的图片。
<imgclass="lazy"data-src="https://example.com/photo1.jpg"src="placeholder.jpg"alt="Image 1"/><imgclass="lazy"data-src="https://example.com/photo2.jpg"src="placeholder.jpg"alt="Image 2"/><imgclass="lazy"data-src="https://example.com/photo3.jpg"src="placeholder.jpg"alt="Image 3"/><!-- 更多图片 -->
使用 IntersectionObserver 来监视图片是否进入视口,如果进入视口,就把 data-src 的值赋给 src,从而触发图片加载。
// 创建一个 IntersectionObserver 实例,监视图片是否进入视口const lazyLoadImages = document.querySelectorAll('img.lazy');const imageObserver =newIntersectionObserver((entries, observer)=>{
entries.forEach(entry =>{// 如果图片进入视口if(entry.isIntersecting){const image = entry.target;// 将 data-src 的真实图片 URL 赋值给 src 属性
image.src = image.dataset.src;// 一旦图片加载完毕,停止观察该图片
image.onload=()=>{
image.classList.remove('lazy');// 可选:移除懒加载样式};
observer.unobserve(image);// 停止观察已加载的图片}});},{
rootMargin:'0px',// 可选:在视口边缘触发加载(当图片接近视口时开始加载)
threshold:0.1// 可选:当图片至少 10% 显示时开始加载});// 观察所有懒加载图片
lazyLoadImages.forEach(image =>{
imageObserver.observe(image);});
代码解释
IntersectionObserver:
创建 IntersectionObserver 实例来观察图片元素是否进入视口。IntersectionObserver 会异步监测指定元素与视口的交集变化。
entries 是一个包含所有监测元素的数组,entry.target 是当前进入视口的图片元素。
isIntersecting 属性表示图片是否已经进入视口(或者与视口重叠)。当该属性为 true 时,图片就进入了视口。
rootMargin:
rootMargin 是视口的扩展区域。当图片距离视口边缘一定距离时就触发加载。可以使用类似 CSS 的值(如 10px 0px)。
threshold:
threshold 定义了当多少比例的图片进入视口时触发懒加载,0.1 表示图片至少 10% 进入视口时触发加载。
image.onload:
一旦图片加载完毕,可以执行一些操作,比如移除懒加载样式(如 lazy 类),表示图片已成功加载。
observer.unobserve(image):
加载完图片后,停止观察该图片,优化性能。
使用 loading=“lazy” 属性
使用 loading=“lazy” 属性可以非常简单地实现图片的懒加载。浏览器就会在图片进入视口时自动加载它。这是原生浏览器对懒加载的支持,无需额外的 JavaScript 代码。这个属性已经被大多数现代浏览器支持。
<imgsrc="image1.jpg"alt="Image 1"loading="lazy"/><imgsrc="image2.jpg"alt="Image 2"loading="lazy"/><imgsrc="image3.jpg"alt="Image 3"loading="lazy"/>
4、不同分辨率下使用不同的图片
<picture><sourcemedia="(max-width: 600px)"srcset="image-small.jpg"><sourcemedia="(max-width: 1200px)"srcset="image-medium.jpg"><imgsrc="image-large.jpg"alt="Responsive Image"></picture>
或者
<imgsrc="image-small.jpg"srcset="image-small.jpg 500w,
image-medium.jpg 1000w,
image-large.jpg 2000w"sizes="(max-width: 600px) 100vw,
(max-width: 1200px) 50vw,
33vw"alt="Responsive Image">
5、使用webp格式的图片
使用 WebP 格式(如果浏览器支持)可以显著减小图片文件大小,从而提高加载速度。
可以通过 元素来根据浏览器支持选择图片格式。
<picture><sourcesrcset="image.webp"type="image/webp"><imgsrc="image.jpg"alt="Responsive Image"></picture>
6、配置图片CDN
- 选择和设置 CDN 服务提供商 首先,选择一个合适的 CDN 服务提供商。常见的 CDN 提供商包括:
Cloudflare
AWS CloudFront
Fastly
KeyCDN
Alibaba Cloud CDN
Tencent Cloud CDN
- 上传图片到 CDN 选择图片存储方式:
存储在对象存储服务中:你可以使用云服务提供商的对象存储(如 Amazon S3、Alibaba OSS、腾讯云 COS)来存储图片文件,并通过 CDN 进行分发。通过这种方式,你可以确保文件安全,并允许 CDN 节点从这些存储服务获取资源。
直接通过 CDN 上传:有些 CDN 服务商允许直接将图片资源上传到其 CDN 网络。
上传图片:将图片上传到选定的存储服务(如 S3),并记录图片的 URL。
- 配置 CDN 创建 CDN 加速域名:
登录你的 CDN 提供商控制台,创建一个加速域名(例如 cdn.yoursite.com)。
配置源站点(通常是你存储图片的服务器或对象存储服务)。源站点是 CDN 获取图片资源的地方。
设置缓存策略:
配置缓存时间(TTL,生存时间),指示 CDN 节点在没有更新时缓存图片的时间。一般情况下,静态资源(如图片)可以设置较长的缓存时间,如一周或一月。
启用 图片优化 功能(如果支持),以便根据设备类型和网络状况自动调整图片的大小和质量。
4. 修改图片 URL
在网页中引用 CDN 提供的图片 URL。假设你的 CDN 域名是 cdn.yoursite.com,你可以像这样引用图片:
<imgsrc="https://cdn.yoursite.com/images/photo1.jpg"alt="Image 1"/><imgsrc="https://cdn.yoursite.com/images/photo2.jpg"alt="Image 2"/>
将原本直接指向服务器的图片 URL 替换为指向 CDN 的图片 URL。
7、减少图片和动图的使用
这可能需要有较强的canvas功底,和较多的开发时间。但的确是能大幅度优化图片的方案。
能用css实现的简单动画,就别用动态图片。能用css实现的样式,就别用图片。
css样式如何优化?
1、关键css优先,非关键css等页面加载完成再加载或引入
在优化 CSS 加载时,遵循“先加载关键 CSS,再懒加载非关键 CSS”的策略,可以显著提升页面加载速度。
1、提取关键css
这就要分析一个页面的功能样式,是否可以分离为进入页面就要展示的css和等用户操作后才展示的css
<style>
/* 关键 CSS */body{margin: 0;font-family: Arial, sans-serif;}header{background-color: #333;color: white;padding: 10px;}/* 添加更多关键样式 */
</style>
2、 懒加载非关键 CSS
如果页面有复杂特效(如动画、hover 状态、特定 JavaScript 动画等),可以将这些 CSS 动效代码延迟到页面加载完成后再应用,从而加快页面初始渲染速度。通过在 标签中添加 media=“print” 和 onload 事件来实现非阻塞加载。
<linkrel="stylesheet"href="non-critical.css"media="print"onload="this.media='all'">
3、使用 rel=“preload” 优化 CSS 加载
对于需要优先加载的非关键 CSS,可以用 preload 指令提前加载,提高资源加载效率。
<linkrel="preload"href="important.css"as="style"onload="this.οnlοad=null; this.rel='stylesheet'">
除了上述处理非关键css,还可以使用js直接引入
window.addEventListener('load',function(){let link = document.createElement('link');
link.rel ='stylesheet';
link.href ='additional-styles.css';
document.head.appendChild(link);});
2、使用 CSS 预处理器和后处理器
预处理器如 SCSS、LESS 可以更简洁地编写和管理 CSS。
后处理器如 PostCSS 可以根据浏览器的兼容性要求,自动添加前缀、压缩代码、处理变量等。
3、利用 CSS 变量
使用 CSS 变量可以减少重复代码,便于动态调整样式。比如色彩、尺寸等样式都可以用 CSS 变量来定义,从而减少代码量并优化可维护性。
:root{--main-color: #4CAF50;--padding: 10px;}body{color:var(--main-color);padding:var(--padding);}
4、减少和优化选择器的复杂性
尽量使用简单的选择器,避免使用深层嵌套或复杂选择器。深层嵌套和通配符(如 *)会增加浏览器的解析成本。
5、删除无用的 CSS
使用工具如 PurgeCSS 或 UnCSS 来移除未使用的 CSS 代码。这样可以极大地减少 CSS 文件体积,提高加载速度。
6、利用缓存
为 CSS 文件设置长缓存时间。通过配置缓存策略,浏览器可以在多次访问时直接加载缓存中的 CSS 文件,避免重新请求 (前端的缓存策略,无非就是 Localstorage,service work)
7、编写代码时尽量减少重排和重绘
尽量避免频繁修改布局属性(如 width、height、padding),减少重绘和重排。可以使用 transform、opacity 等性能友好的属性,进行页面更新。
transform 调用的GPU来实现渲染 ,减少使用translate
版权归原作者 可缺不可滥 所有, 如有侵权,请联系我们删除。