网页图片加载优化方法总结
网页图片加载优化方法总结
1. 压缩图片
要尽可能的压缩,看用户的忍受程度。jpg 可以用很多方法压缩,png 推荐使用 工具(不过正文图片,显然要选择 jpg 格式的)
创天无忧图片压缩缩放处理工具
本程序是一款绿色小巧的压缩图片文件占用空间大小,缩放图片尺寸的实用小工具。尽心的界面设计使操作更简单,不用学习,直接使用,本程序为绿色程序,可以任意复制,不用安装,可直接运行。
创天无忧图片压缩缩放处理工具功能描述:
1. 图片压缩
图片压缩是通过压缩减少图片的占用空间,如果您有大量的数码照,或是上传图片的网站有文件大小的限制,您就可以通过此软件来压缩图片大小,压缩图片文件大小,以达到减少大量图片占用磁盘空间,上传照片等效果
2. 图片缩放
图片缩放功能可放大或是缩小图片的尺寸,可按图片的原始比例或是指定的图片尺寸大小进行放大或缩小
3. 程序可批量或是对单个文件进行压缩缩放处理,可对选中的文件列表进行单独的删除操作等
4. 本程序有第一次运行自动创建桌面快捷方式,打开输出文件目录等贴心小功能
2. 直接一开始用压缩过的体积小的图,等加载完毕后,再用高清无码图来替换掉
高清无码的图片随便怎么命名,但是压缩过的命名有要求,那就是必须在原图的名称前面加上相同的便于分辨的标识。比如
高清图 1 命名为 photo.jpg 那么相应的压缩图就叫 photo_min.jpg (_min 这个随你取名,但是要一致,不能一个叫_min, 下一个就成了_small)
<html lang="en">
<head>
<meta charset="UTF-8">
<meta >
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div class="box">
<img src="../images/photos/culture/photo.min.jpg">
</div>
</body>
<script>
$(function() {
//一段正则,匹配所有_min.的图片src属性
var test = /_min\./
//遍历所有的图片节点
$("img").each(function(index, obj) {
if (test.test($(this).attr("src"))) {
var reSrc = $(this).attr("src").replace(test, ".");
$(this).attr("src", reSrc)
}
})
})
</script>
</html>
3. 使用 base64 编码代替图片
原理:将图片转换为 base64 编码字符串 inline 到页面或 css 中
场景:适用于图片大小小于 2KB,页面上引用图片总数不多的情况background-image: url("https://img-blog.csdnimg.cn/2022010704071646520.png");
<img src="https://img-blog.csdnimg.cn/2022010704071646520.png" />
优势:减少 http 的请求次数,并可以放到后台数据库中,只传输字符串,有较多的构建工具可以直接实现
劣势:这种方法仅限于图片总数较少,而且图片大小小于 2KB 的情况。否则图片字符串会变得很长很长
4. 更好的图片格式
之前说到 webp、bpg、sharpP 等新图片格式具有更好的压缩比,可以使用这类新型的图片来代替原始图片 原理:对图片格式转换,在画质可以接受的情况下达到更好的压缩比效果优势:减少图片加载流量,效果比较明显 劣势:服务器和浏览器压力增大,而且服务器需要额外的服务支持,格式转换要考虑浏览器的兼容性
webp
目前移动端 Android4.0 以上、PC 端 chorme 10+(14 ~ 16 有渲染 bug)、opera 11+ 、safri 均支持 webp 格式图片。 WEBP 与 JPG 相比较,编码速度慢 10 倍,解码速度慢 1.5 倍,而绝大部分的网络应用中,图片都是静态文件,所以对于用户使用只需要关心解码速度即可。但实际上,webp 虽然会增加额外的解码时间,但是由于减少了文件体积,缩短了加载的时间,实际上文件的渲染速度反而变快了。
webp 上目前可行的应用场景:
-1. 客户端软件,内嵌了基于 Chromium 的 webview,这类浏览器中应用的网页是可以完全使用 webp 格式,提升加载渲染速度,不考虑兼容。
-2. 用 node-webkit 开发的程序,用 webp 可以减少文件包的体积。
-3. 移动应用 或 网页游戏 , 界面需要大量图片, 可以嵌入 webp 的解码包, 能够节省用户流量,提升访问速度优势:
- 对于 png 图片, webp 比 png 小了 45%, 但是缺点是你压缩的时候需要的时间更久了;劣势:
- 兼容性不太好, 只有 opera, 和 chrome 支持;
apng
简单来讲 apng 格式图片使用多个单张 png 连接起来的动画图片格式,支持全透明通道动画。相比于 gif 动画,没有毛刺,质量更高,但目前支持的浏览器并不完全。可以去 can i use 查看其兼容性。目前可用性相对较低,适用于对动画质量要求很高的情况。
bpg
http://bellard.org/bpg/ 图片画质比较 性能测试对比
BPG (Better Portable Graphics) 是一个新的图片格式。用来代替 jpeg 和 webp 的方案。这种格式主要有以下特点 优势:
高压缩比。在画质相同的情况下比 jpeg 小的多
使用一个很小的 js 解码器就可以被浏览器支持
基于高清视频压缩标准 (HEVC) 一个子集开发
支持和 jpeg 相同的色值,并且在有损压缩的通知支持透明,
单通道支持 8 到 14 位色值区域
支持有损压缩
可以添加更多的元数据编码
支持动画
相近画质前提下比 webp 更小
性能:
根据 mozilla 的研究,bpg 使用的 HEVC 编码比原生的 HEVC 性能更好,因为 BPG 的头部比 HEVC 的头部更小
支持 4:2:2 和 4:2:0 的色值设置
BPG 可以用于硬件上支持 HEVC 编解码器
这种图片格式目前还没有被浏览器支持,需要 js 解码,但其优势非常明显。
另外还有 mozjpg、sharpP 的图片格式,由于目前仍在起步阶段,这里暂不介绍了,有兴趣的可以去跟进了解下。
5. 合并图片 sprite(雪碧图)
场景:任何用到页面图片的场景
原理:将多个页面上用到的背景图片合并成一个大的图片在页面中引用
优势:可以有效的较少请求个数,而且,而不影响开发体验,使用构建插件可以做到对开发者透明。适用于页面图片多且丰富的场景。
劣势:生成的图片体积较大,减少请求个数同时也增加了图片大小,不合理拆分将不利于并行加载
- 使用 css、svg、canvas 或 iconfont 代替图片
css 代替图片
场景:适用于移动端或较高级的浏览器,而且绘制的图案较为简单。
原理:css 方式可以用来绘制相对简单的图案来代替图片,一般使用 before 或者 after 伪元素来丰富图案的复杂度。
优势:具有实现简单,图片体积小的特点,可以实现简单的动态效果
劣势:也受限于 css 的兼容性特点,绘制复杂图案困难
svg 代替图片
svg 是一种矢量图片,支持透明,缩放,动画,除了 android 2.3 的手机,其它场景都支持,是一种比较好的图片代替方案。 优势:
矢量图形,不受像素影响——SVG 的这个特性使得它在不同的平台或者媒体下表现良好,无论屏幕分辨率如何
SVG 对动画的支持较好;其 DOM 结构可以被其特定语法或者 Javascript 控制,从而轻松的实现动画
Javascript 可以完全控制 SVG Dom 元素
SVG 的结构是 XML,其可访问性(盲文、声音朗读等)、可操作性、可编程性、可被 CSS 样式化完胜 Canvas。另外,其支持 ARIA 属性,使其如虎添翼。
劣势:
DOM 比正常的图形慢,而且如果其结点多而杂,就更慢了
不适合网页游戏等;当然,我们可以结合 Canvas + SVG 来实现
canvas 代替图片
场景:需要高性能的图片或动画
原理:适用 html5 的 canvas 元素绘制创建图片
优势:整个就是画 2D 图形时,页面渲染性能比较高,页面渲染性能受图形复杂度影响小,性能只受图形的分辨率的影响,画出来的图形可以直接保存为 .png 或者 .jpg 的图形,适合于画光栅图像或者不规则图形
劣势:没有 dom 操作,必须依赖定时器,文字渲染性能差,不能添加描述 (title 属性什么的),兼容性限制
iconfont 是一种 web 字体来代替图片的解决方案:
场景:代替页面上色彩单一的图片 优势:兼容性好,应用广,目前使用也很广泛 劣势:但是由于字体的颜色设置单一,只能用于代替颜色单一的图片,对于色彩复杂的图片,iconfont 处理起来比较困难
7. 响应式图片
场景:不同终端对同一个图片需求不一样,可以根据终端加载不同的图片来节省没必要的流量
原理:通过 picture 元素,picturefill 或平台判断来为不同终端平台输出不同的图片
优势:减少没必要的图片加载,灵活控制,慢速用户加载小图片不至于加载失败,移动端没必要加载大尺寸图片等,可以通过不同方式兼容所有浏览器
劣势:无法避免图片的加载过程,图片本身没优化
8. 将图片服务和应用服务分离 (从架构师的角度思考)
将图片服务和应用服务放在同一个服务器的话,应用服务器很容易会因为图片的高 I/O 负载而崩溃,因此对于有些大型网站项目,我们有必要将图片服务器和应用服务器分离。
192.168.0.1 作为 nfs 服务器(同时也是图片服务器) 192.168.0.2 作为客户端,
一: 首先在图片服务器安装好 NFS, 需对 nfs 做出如下配置
nfs 服务器:
vi /etc/exports
在里面加入本机需要共享的文件目录和对应的客户端地址及权限 添加:
/data/pic 192.168.0.2(rw,no_root_squash,sync)
执行: exportfs -r , 重新刷新配置
二, 在应用服务器使用如下命令进行挂载 mount -t nfs 192.168.0.1:/data/pic /data/www/photos
三: 那怎么能够访问到图片服务器的图片呢
|| nginx 配置
server {
listen 80;
server_name 随便配置IP 配置本机IP即可;
root /data/www
index index.html index.htm index.php;
location ~* ^/photo {
rewrite ^/photo/(.*)$ http://192.168.0.2/photos/$1 ;
}
}
这样当用户访问图片是其实是访问的 192.168.0.1:/data/pic
- 预加载
预加载是浏览器对将来可能被使用资源的一种暗示,一些资源可以在当前页面使用到,一些可能在将来的某些页面中被使用。作为开发人员,我们比浏览器更加了解我们的应用,所以我们可以对我们的核心资源使用该技术
当提到前端性能优化时,我们首先会联想到文件的合并、压缩,文件缓存和开启服务器端的 gzip 压缩等,这使得页面加载更快,用户可以尽快使用我们的 Web 应用来达到他们的目标。
资源预加载是另一个性能优化技术,我们可以使用该技术来预先告知浏览器某些资源可能在将来会被使用到。在开发的过程,我们经常会遇到这样的要求,当鼠标 hover 上去的时候,更改菜单的背景。如果没有进行图片预加载的话,会出现闪烁。那么拥有 1px 的眼睛的设计师们不会放过你的。为什么会出现这张情况?因为 hover 的时候,图片才会去加载。那么我们现在来解决这个问题。
以前这种实践也被称为 prebrowsing。但这并不是一种单一的技术,实际上可以拆分成很多小点:dns-prefetch, subresource, prefetch, preconnect 和 prerender
DNS 预解析 DNS-Prefetch
DNS-Prefetch 通过指定具体的 URL 来告知客户端未来会用到相关的资源,这样浏览器可以尽早的解析 DNS。
例如,我们将来可能从 example.com 获取图片或音频资源,那么可以在文档顶部的 <head>
标签中加入以下内容:<link rel="dns-prefetch" href="//example.com">
通过简单的一行代码就可以告知那些兼容的浏览器进行 DNS 预解析,这意味着当浏览器真正请求该域中的某个资源时,DNS 的解析就已经完成了。
项目中有用到第三方的代码时这么做尤其有益;其他的使用场景,比如当静态资源和 HTML 不在一个域上,而在 CDN 上;又比如在重定向前可以加上 DNS prefetch。
预连接 Preconnect
与 DNS 预解析类似,Preconnect 不仅完成 DNS 预解析,同时还将进行 TCP 握手和建立传输层协议。
用法如下:<link rel="preconnect" href="http://example.com">
现代浏览器都试着预测网站将来需要哪些连接,然后预先建立 socket 连接,从而消除昂贵的 DNS 查找、TCP 握手和 TLS 往返开销。然而,浏览器还不够聪明,并不能准确预测每个网站的所有预链接目标。好在,在 Firefox 39 和 Chrome 46 中我们可以使用 Preconnect 告诉浏览器我们需要进行哪些预连接。
预获取 Prefetch
如果我们确定某个资源将来一定会被使用到,我们可以让浏览器预先请求该资源并放入浏览器缓存中。与 DNS 预解析不同,预获取真正请求并下载了资源,并储存在缓存中。
例如,一个图片和脚本或任何可以被浏览器缓存的资源:<link rel="prefetch" href="image.png">
然而 预获取还依赖于一些条件,某些预获取可能会被浏览器忽略,例如从一个非常缓慢的网络中获取一个庞大的字体文件。并且,Firefox 只会在浏览器闲置时进行资源预获取。
预获取对 webfonts 性能提升非常明显。目前,字体文件必须等到 DOM 和 CSS 构建完成之后才开始下载,使用预获取就可以轻松绕过该瓶颈。
注意:要测试资源的预获取有点困难,但在 Chrome 和 Firefox 的网络面板中都有资源预获取的记录。还需要记住,预获取的资源没有同源策略的限制。
Subresources
Subresources 是另一个预获取方式,这种方式指定的预获取资源具有最高的优先级,在所有 prefetch 项之前进行
<link rel="subresource" href="styles.css">
rel=prefetch 为将来的页面提供了一种低优先级的资源预加载方式
rel=subresource 为当前页面提供了一种高优先级的资源预加载
所以,如果资源是当前页面必须的,或者资源需要尽快可用,那么最好使用 subresource 而不是 prefetch。
预渲染 Prerender
预渲染类似于在一个隐藏的 tab 页中打开了某个链接 – 将下载所有资源、创建 DOM 结构、完成页面布局、应用 CSS 样式和执行 JavaScript 脚本等。当用户真正访问该链接时,隐藏的页面就切换为可见,使页面看起来就是瞬间加载完成一样。
用法如下:<link rel="prerender" href="http://example.com">
prerender 可以预先加载文档的所有资源。Google 搜索在其即时搜索页面中已经应用该技术多年了,微软也宣称将在 IE11 中支持该特性。
需要注意的是不要滥用该特性,当你知道用户一定会点击某个链接时才可以进行预渲染,否则浏览器将无条件地下载所有预渲染需要的资源。
Preload
Preload 是一个新规范,该规范还没有被所有浏览器兼容。
Preload 草案建议允许始终预加载某些资源,不像 Prefetch 有可能被浏览器忽略,浏览器必须请求 Preload 标记的资源。
用法如下:<link rel="preload" href="image.png">
其它预加载
- 使用纯的 css 进行图片预加载
body:after {
content: "";
display: block;
position: absolute;
background: url("../image/manage/help/help_item2_01.png?v=201707241359") no-repeat -10000px -1000px,url("../image/manage/help/help_item2_02.png?v=201707241359") no-repeat -10000px -1000px,url("../image/manage/help/help_item2_03.png?v=201707241359") no-repeat -10000px -1000px,url("../image/manage/help/help_item2_04.png?v=201707241359") no-repeat -10000px -1000px,url("../image/manage/help/help_item2_05.png?v=201707241359") no-repeat -10000px -1000px,url("../image/manage/help/help_item2_06.png?v=201707241359") no-repeat -10000px -1000px,url("../image/manage/help/help_item2_07.png?v=201707241359") no-repeat -10000px -1000px,url("../image/manage/help/help_item2_01.png?v=201707241359") no-repeat -10000px -1000px;
width: 0;
height: 0
}
原理是加载了该图片,但是我们不显示在可视范围内。这种方式极其简单。但是也有一个致命的弱点,图片跟随文档一同加载,有时候我们为了提高文档的加载速度,那么这种方式方式就不适合了。
- 使用纯 javascript 进行图片预加载
//存放图片路径的数组
var imgSrcArr = [
'imgsrc1',
'imgsrc2',
'imgsrc3',
'imgsrc4'
];
var imgWrap = [];
function preloadImg(arr) {
for(var i =0; i< arr.length ;i++) {
imgWrap[i] = new Image();
imgWrap[i].src = arr[i];
}
}
preloadImg(imgSrcArr);
//或者延迟的文档加载完毕在加载图片
$(function () {
preloadImg(imgSrcArr);
})
- 使用 css+js 方式进行图片预加载
.preload-img:after{
content:"",
background: url("../image/manage/help/help_item2_01.png?v=201707241359") no-repeat -10000px -1000px,url("../image/manage/help/help_item2_02.png?v=201707241359") no-repeat -10000px -1000px,url("../image/manage/help/help_item2_03.png?v=201707241359") no-repeat -10000px -1000px,url("../image/manage/help/help_item2_04.png?v=201707241359") no-repeat -10000px -1000px,url("../image/manage/help/help_item2_05.png?v=201707241359") no-repeat -10000px -1000px,url("../image/manage/help/help_item2_06.png?v=201707241359") no-repeat -10000px -1000px,url("../image/manage/help/help_item2_07.png?v=201707241359") no-repeat -10000px -1000px,url("../image/manage/help/help_item2_01.png?v=201707241359") no-repeat -10000px -1000px;
}
/*
比如我们写了上面的这样一个类,但是页面中没有用到,我们在文档加载完毕之后,给某个元素添加该类
*/
$(function(){
$("#target").addClass("preload-img")
})
- 使用 ajax 方式进行图片预加载
$(function(){
$.get('图片的路径');
})
/*
当然我们也可以写成一个函数,这里我就不演示了
*/
10. 图片懒加载
图片懒加载是一种网页优化技术。图片作为一种网络资源,在被请求时也与普通静态资源一样,将占用网络资源,而一次性将整个页面的所有图片加载完,将大大增加页面的首屏加载时间。为了解决这种问题,通过前后端配合,使图片仅在浏览器当前视窗内出现时才加载该图片,达到减少首屏图片请求数的技术就被称为 “图片懒加载”。
意义: 懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数。
实现方式:
第一种是纯粹的延迟加载,使用 setTimeOut 或 setInterval 进行加载延迟.
第二种是条件加载,符合某些条件,或触发了某些事件才开始异步下载。
第三种是可视区加载,即仅加载用户可以看到的区域,这个主要由监控滚动条来实现,一般会在距用户看到某图片前一定距离前开始加载,这样能保证用户拉下时正好能看到图片。
11. 使用 CDN 加速
CDN 的全称是 Content Delivery Network,即内容分发网络。CDN 是构建在网络之上的内容分发网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN 的关键技术主要有内容存储和分发技术。
用户向浏览器输入 www.web.com 这个域名,浏览器第一次发现本地没有 dns 缓存,则向网站的 DNS 服务器请求;
网站的 DNS 域名解析器设置了 CNAME,指向了 www.web.51cdn.com, 请求指向了 CDN 网络中的智能 DNS 负载均衡系统;
智能 DNS 负载均衡系统解析域名,把对用户响应速度最快的 IP 节点返回给用户;
用户向该 IP 节点(CDN 服务器)发出请求;
由于是第一次访问,CDN 服务器会向原 web 站点请求,并缓存内容;
请求结果发给用户。
CDN 网络是在用户和服务器之间增加 Cache 层,如何将用户的请求引导到 Cache 上获得源服务器的数据,主要是通过接管 DNS 实现,这就是 CDN 的最基本的原理,当然很多细节没有涉及到,比如第 1 步,首先向本地的 DNS 服务器请求。第 5 步,内容淘汰机制(根据 TTL)等。但原理大体如此。
当用户访问加入 CDN 服务的网站时,域名解析请求将最终交给全局负载均衡 DNS 进行处理。全局负载均衡 DNS 通过一组预先定义好的策略,将当时最接近用 户的节点地址提供给用户,使用户能够得到快速的服务。同时,它还与分布在世界各地的所有 CDNC 节点保持通信,搜集各节点的通信状态,确保不将用户的请求 分配到不可用的 CDN 节点上,实际上是通过 DNS 做全局负载均衡。
对于普通的 Internet 用户来讲,每个 CDN 节点就相当于一个放置在它周围的 WEB。通过全局负载均衡 DNS 的控制,用户的请求被透明地指向离他最近的节点,节点中 CDN 服务器会像网站的原始服务器一样,响应用户的请求。由于它离用户更近,因而响应时间必然更快。
每个 CDN 节点由两部分组成: 负载均衡设备和高速缓存服务器
负载均衡设备负责每个节点中各个 Cache 的负载均衡,保证节点的工作效率; 同时,负载均衡设备还负责收集节点与周围环境的信息,保持与全局负载 DNS 的通信,实现整个系统的负载均衡。CDN 的管理系统是整个系统能够正常运转的保证。它不仅能对系统中的各个子系统和设备进行实时监控,对各种故障产生相应的告警,还可以实时监测到系统中 总的流量和各节点的流量,并保存在系统的数据库中,使网管人员能够方便地进行进一步分析。通过完善的网管系统,用户可以对系统配置进行修改。
理论上,最简单的 CDN 网络有一个负责全局负载均衡的 DNS 和各节点一台 Cache,即可运行。DNS 支持根据用户源 IP 地址解析不同的 IP,实现 就近访问。为了保证高可用性等,需要监视各节点的流量、健康状况等。一个节点的单台 Cache 承载数量不够时,才需要多台 Cache,多台 Cache 同时 工作,才需要负载均衡器,使 Cache 群协同工作。
客户端浏览器先检查是否有本地缓存是否过期,如果过期,则向 CDN 边缘节点发起请求,CDN 边缘节点会检测用户请求数据的缓存是否过期,如果没有过期,则直接响应用户请求,此时一个完成 http 请求结束;如果数据已经过期,那么 CDN 还需要向源站发出回源请求(back to the source request), 来拉取最新的数据。CDN 的典型拓扑图如下:
域名系统(Domain Name System 缩写 DNS,Domain Name 被译为域名)是因特网的 一项核心服务,它作为可以将域名和 IP 地址相互映射的一个分布式数据库,能够使人更方便的访问互联网,而不用去记住能够被机器直接读取的 IP 数串。
高速缓存服务器(Cache):
负责存储客户网站的大量信息,就像一个靠近用户的网站服务器一样响应本地用户的访问请求。通过全局负载均衡 DNS 的控制,用户的请求被透明地指向离他最近的节点,节点中 Cache 服务器就像网站的原始服务器一样,响应终端用户的请求。因其距离用户更近,故其响应时间才更快。