- 前端加载超大图片时,一般可以采取以下措施实现加速:
- 图片压缩:将图片进行压缩可以大幅减小图片的大小,从而缩短加载时间。压缩图片时需要注意保持图片质量,以免影响图片显示效果。
- 图片分割:将超大图片分割成多个小图块进行加载,可以避免一次性加载整个图片,从而加快加载速度。这种方式需要在前端实现图片拼接,需要确保拼接后的图片无缝衔接。
- CDN 加速:使用 CDN(内容分发网络)可以将图片缓存在离用户更近的节点上,从而加速图片加载速度。如果需要加载的图片是静态资源,可以将其存储在 CDN 上,以便快速访问。
- 懒加载:懒加载是一种图片延迟加载的方式,即当用户浏览到需要加载的图片时才进行加载,可以有效避免一次性加载大量图片而导致页面加载速度缓慢。
- WebP 格式:使用 WebP 格式可以将图片大小减小到 JPEG 和 PNG 的一半以下,从而加快图片加载速度。
- HTTP/2:使用 HTTP/2 协议可以并行加载多个图片,从而加快页面加载速度。
- 预加载:预加载是在页面加载完毕后,提前加载下一步所需要的资源。在图片加载方面,可以在页面加载完毕后提前加载下一个需要显示的图片,以便用户快速浏览。
- 3种常用图片压缩方法
- 把图片上传到阿里云或七牛云,借用云端的图片缩放技术进行压缩。
- 后端对图片尺寸大小进行压缩。
- 前端用 Canvas 作为媒介压缩图片。即(图片 -> Canvas -> 图片)
- 前端用 Canvas 作为媒介压缩图片---流程及实现代码(React写法)
- 新建 img ,使其 src 指向刚刚的 base64
- 新建 canvas ,将 img 画到 canvas 上
- 利用 canvas.toDataURL/toBlob 将 canvas 导出为 base64 或 Blob
- 将 base64 或 Blob 转化为 File
import React from 'react'; export default class Home extends React.Component { constructor(props) { super(props); this.state = { url: '', }; } changeFile(event) { console.log(event); let _this = this; // 选择的文件对象(file里只包含图片的体积,不包含图片的尺寸)----size=407517 let file = event.target.files[0]; console.log(file); // 判断选择的文件是图片 if (file.type.indexOf('image') === 0) { // 压缩图片需要的一些元素和对象---FileReader是一种异步文件读取机制,结合input:file可以很方便的读取本地文件。 let reader = new FileReader(); // 创建一个img对象----Image 对象是 JS 中的内置对象,它代表嵌入的图像。当我们创建一个 Image 对象时,就相当于给浏览器缓存了一张图片,Image 对象也常用来做预加载图片(也就是将图片预先加载到浏览器中,当浏览图片的时候就能享受到极快的加载速度)。在HTML页面中,<img> 标签每出现一次,也就创建了一个 Image 对象。 let img = new Image(); // console.log(img);-----<img></img> // FileReader实例对象的方法readAsDataURL(file)会把文件内容转换为data类型的URL: data:text/plain;base64,b3JkZXItaWQJb3JkZXItaXRlbS1p... // 这种data类型的URL可以在浏览器地址栏中直接访问。 // readAsText(file, [encoding]): 将文件读取为文本,encoding缺省值为UTF-8. reader.readAsDataURL(file); // 文件转化为base64地址图片,以便获取图片原始尺寸 reader.onload = function (e) { console.log(e); img.src = e.target.result; }; //base64地址图片加载完毕后执行 img.onload = function () { // 缩放图片需要的canvas(也可以在DOM中直接定义canvas标签,这样就能把压缩完的图片不转base64也能直接显示出来) let canvas = document.createElement('canvas'); let context = canvas.getContext('2d'); // console.log(this);----当前this指向img对象 // 图片原始尺寸 let originWidth = this.width; let originHeight = this.height; // 最大尺寸限制,可通过设置宽高来实现图片压缩程度,根据需求自行设置 let maxWidth = 200; let maxHeight = 200; // 目标尺寸 let targetWidth = originWidth; let targetHeight = originHeight; //图片尺寸超过300x300的限制 if (originWidth > maxWidth || originHeight > maxHeight) { if (originWidth / originHeight > maxWidth / maxHeight) { // 更宽,按照宽度限定尺寸 targetWidth = maxWidth; // Math.round()---四舍五入 targetHeight = Math.round(maxWidth * (originHeight / originWidth)); } else { targetHeight = maxHeight; targetWidth = Math.round(maxHeight * (originWidth / originHeight)); } } // canvas对图片进行缩放 canvas.width = targetWidth; canvas.height = targetHeight; // 清除画布 context.clearRect(0, 0, targetWidth, targetHeight); // 图片压缩 // 通过drawImage方法将img图片对象渲染到canvas里 context.drawImage(img, 0, 0, targetWidth, targetHeight); // drawImage 方法有三种形态: // drawImage(image, dx, dy) 在画布指定位置绘制原图 // drawImage(image, dx, dy, dw, dh) 在画布指定位置上按原图大小绘制指定大小的图 // drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) 剪切图像,并在画布上定位被剪切的部分 // image 规定要使用的图像、画布或视频 // sx 可选。开始剪切图片的 x 坐标位置 // sy 可选。开始剪切图片的 y 坐标位置 // sw 可选。被剪切图像的宽度(就是裁剪之前的图片宽度,这里的宽度若小于图片的原宽。则图片多余部分被剪掉;若大于,则会以空白填充) // sh 可选。被剪切图像的高度(就是裁剪之前的图片高度) // dx 在画布上放置图像的 x 坐标位置 // dy 在画布上放置图像的 y 坐标位置 // dw 可选。要使用的图像的宽度(就是裁剪之后的图片高度,放大或者缩放) // dh 可选。要使用的图像的高度(就是裁剪之后的图片高度,放大或者缩放) let newUrl = canvas.toDataURL('image/jpeg', 0.92); //base64格式 // canvas.toDataURL(type, encoderOptions);---canvas的toDataURL()方法是返回一个包含图片展示的数据URL。可以使用 type 参数其类型,默认为 PNG 格式。图片的分辨率为96dpi。 // 1、type:图片格式,默认为 image/png,可以是其他image/jpeg等 // 2、encoderOptions:0到1之间的取值,主要用来选定图片的质量,默认值是0.92,超出范围也会选择默认值。只有导出为jpeg和webp格式的时候此参数才有效 // 1、如果画布的高度或宽度是0,那么会返回字符串“data:,”。 // 2、如果传入的类型非“image/png”,但是返回的值以“data:image/png”开头,那么该传入的类型是不支持的 // 3、Chrome支持“image/webp”类型。 console.log(newUrl); //缩放后的图片 // 显示缩放后的图片 _this.setState({ url: newUrl, }); // 也可以把压缩后的图片转blob格式用于上传 // 语法:canvas.toBlob(callback, mimeType, qualityArgument) // 创造Blob对象, mimeType展示canvas的图片,默认图片类型是image/png,分辨率是96dpi,callback: 参数是blob对象的回调函数 canvas.toBlob((blob) => { // console.log(blob);-----{type:'image/png',size:34128(缩放前407517)} // 获取上传接口上传即可--发起上传请求 }); }; } else { alert('请上传图片格式的文件'); } } render() { let { url } = this.state; return ( <div> <input id="file" type="file" onChange={this.changeFile.bind(this)} /> <img id="preview" src={url} alt="" /> </div> ); } }
- CDN加速
- 站点在使用CDN图片加速服务前,这些静态资源采用集中放置的管理方式
- 使用 CDN图片加速服务后,站点的静态资源被全部分发到CDN中心网络边缘的各CDN节点,这样就把原来集中在源站的静态资源调取工作全部分配到CDN加速节点。互联网站终端用户如果要访问站点中的静态资源,距其最近的CDN节点就会把这些内容自动发送给访问者,而不会去源站来调取这些内容。
1、有效降低源站服务器压力:避免了因内部操作过多出现服务器宕机问题,源站也无需为突发流量添置多余的服务器设备;
2、有效提升用户的访问质量:用户就近访问,静态资源在互联网终端加载速度更快,受网络通讯状况的影响更小,解决跨运营商的网络互联问题;
3、有效提升源站的安全系数:使用CDN节点替代源站被互联网终端用户直接访问,有效抵御各种网络黑客攻击,隐藏源站IP,不会出现单点被攻击而全局访问受到影响的状况;
4、有效提升站点管理便利性:源站业务扩展时无需刻意增加服务器设备,提供带宽流量、流量缓存、节点流量比例、页面访问及日志等多种数据下载功能。