阅读 115

浏览器系列 -- 优化图片加载速度

对优化网页图片加载有如下6种方案:

  1. 图片压缩
  2. 先加载压缩图片,再加载高清大图,加载完毕后代替掉(先模糊后清晰
  3. 媒体查询设备(不同屏幕不同尺寸
  4. 使用 base64、css、canvas 代替简单图片
  5. 图片预加载(提前加载
  6. 图片懒加载(先少后多
  7. 使用 CDN 加速

1. 图片压缩

从视觉上没有影响的前提下对图片的大小进行压缩,可以从根本上很好地解决网页加载图片慢的问题

图片压缩方式分为两个方面:

  • 一方面是减少一张图片总的像素个数

如果屏幕像素是 450 * 750 ,那1080 * 1920 的高清大图是没有必要的了,利用外部软件进行压缩即可

  • 另一方面是减少单位像素所需的字节数

举个例子:一张图片的每个像素点通过 RGBA 颜色值进行存储,R\G\B\A 每个色道都有 0~255 个取值,也就是 2^8 = 256。正好是 8 位 1byte。而每个像素点有四个色道,每个像素点需要 4bytes

RGBA 颜色值可以表示 256^4 种颜色,这是一个很大的数字,往往我们不需要这么多颜色值。因此我们是否可以减少色板中的颜色种类呢?这样表示单位像素的字节数就减少了。

而「无损」压缩是通过一些算法,存储像素数据不变的前提下,尽量减少图片存储体积。比如一张图片中的某一个像素点和其周围的像素点很接近,比如一张蓝天的图片,因此我们可以存储两个像素点颜色值差值,这样表示单位像素的字节数就减少了

2. 先加载压缩图片,再加载高清大图,加载完毕后代替掉

压缩图是 photo_min.jpg ,对应的高清大图是 photo.jpg

<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>
复制代码

3. 调用 API 获取屏幕尺寸,根据结果使用不同尺寸的图片

1920 × 1080 px 的电脑屏幕需要大尺寸的图片,但是 320 × 640 px 的手机屏幕就不需要那么大尺寸的图片了,所以可以视屏幕尺寸大小加载不同尺寸大小的图片,这是一种解决方案。

4. 使用base64、css、canvas代替简单图片

对于一些较为简单的图片可以采用base64、css、canvas等代替

使用base64代替图片

  • 原理:将图片转换为base64编码字符串inline到页面或css中

background-image: url("data:image/png;base64,iVBORw0KGgo=...");
<img src="data:image/png;base64,iVBORw0KGgo=..." />

  • 场景:适用于图片大小小于2KB,页面上引用图片总数不多的情况
  • 优势:1. 减少http的请求次数; 2. 并可以放到后台数据库中,只传输字符串,更快
  • 图片太大对应的字符串过长,也不利于传输

使用CSS代替图片

  • 原理:使用before或者after伪元素来丰富图案的复杂度。
  • 场景:适用于移动端或较高级的浏览器,用于绘制简单图案
  • 优势:具有实现简单,图片体积小的特点,可以实现简单的动态效果
  • 劣势:也受限于css的兼容性特点,绘制复杂图案困难

canvas代替图片

  • 原理:html5的canvas元素
  • 场景:绘制高性能的图片或动画
  • 优势:整个就是画2D图形时,页面渲染性能比较高,页面渲染性能受图形复杂度影响小,性能只受图形的分辨率的影响,画出来的图形可以直接保存为 .png 或者 .jpg的图形,适合于画光栅图像或者不规则图形
  • 劣势:没有dom操作,必须依赖定时器,文字渲染性能差,不能添加图片描述,兼容性限制

具体关于Canvas的内容可以看 HTML系列 -- Canvas

5. 图片懒加载

在用户即将看到图片时进行加载,如果位处于视窗区域内则暂且不加载

实现思路:监听触底事件

微信小程序

// 微信小程序的Page里面有onReachBottom()方法可以监听用户上拉触底事件
Page({
    onReachBottom(){
        /*开始请求加载图片*/
    }
})
// JSON文件
{
    "onReachBottomDistance": 50 // 页面上拉触底事件触发时距页面底部距离,单位为px
}
复制代码

Web 端

// html5 + vue 实现监听用户上拉触底事件
mounted () {
    window.onscroll = function(){
        var scrollTop = document.documentElement.scrollTop //当前屏幕顶部到滚动条顶部的距离
        var clientHeight = document.documentElement.clientHeight //屏幕可视区的高度
        var scrollHeight = document.documentElement.scrollHeight //滚动条的总高度
        if(scrollTop + windowHeight + 50 == scrollHeight){ 
            /*开始请求加载图片,可以先预留50px出来*/
        } 
    }
}
复制代码

6. 使用 CDN 加速资源获取

关于CDN加速的详细内容见 浏览器系列 -- CDN加速

文章分类
前端
文章标签