chst365's blog chst365's blog
首页
  • Git
  • 网络
  • 操作系统
  • 浏览器
  • webpack
  • JavaScript
  • TypeScript
  • 性能
  • 工程化
  • React
  • 编程题
  • React技术揭秘
  • 算法
  • Node
  • 编码解码
  • NodeJS系列
  • Linux系列
  • JavaScript系列
  • HTTP系列
  • GIT系列
  • ES6系列
  • 设计模式系列
  • CSS系列
  • 小程序系列
  • 数据结构与算法系列
  • React系列
  • Vue3系列
  • Vue系列
  • TypeScript系列
  • Webpack系列
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

chst365

DIV工程师
首页
  • Git
  • 网络
  • 操作系统
  • 浏览器
  • webpack
  • JavaScript
  • TypeScript
  • 性能
  • 工程化
  • React
  • 编程题
  • React技术揭秘
  • 算法
  • Node
  • 编码解码
  • NodeJS系列
  • Linux系列
  • JavaScript系列
  • HTTP系列
  • GIT系列
  • ES6系列
  • 设计模式系列
  • CSS系列
  • 小程序系列
  • 数据结构与算法系列
  • React系列
  • Vue3系列
  • Vue系列
  • TypeScript系列
  • Webpack系列
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 浏览器

  • webpack

  • TypeScript

  • 性能

    • 浏览器动画性能优化
    • 浏览器渲染流程&Composite(渲染层合并)
    • 浏览器工作原理:从URL输入到页面展现到底发生了什么
    • 大量图片加载优化
      • 图片加载存在的问题、原因及解决方案
        • 启动页面时加载过多图片
        • 部分图片体积过大
    • 白屏时间
    • 重排和重绘
    • 前端性能优化-RAIL
  • 工程化

  • React

  • JavaScript

  • 编程题

  • React技术揭秘

  • 算法

  • 前端
  • 性能
chst365
2021-04-12
目录

大量图片加载优化

# 图片加载存在的问题、原因及解决方案

# 启动页面时加载过多图片

# 问题分析

如图,页面启动时加载了大约 49 张图,而这些图片请求几乎是并发的,在 Chrome 中,对于同一个域名,最多支持 6 个请求的并发,其他的请求将会推入到队列中等待或停滞不前,直到六个请求之一完成后,队列中新的请求才会发出

# 解决方案

  • 减少首次加载的请求次数,即只加载首屏内的图片,可以通过getBoundingClientRect方法,获取图片的位置信息,判断其是否在viewport内部
    const inViewport = (el) => {
      const rect = el.getBoundingClientRect();
      return (
        rect.top > 0 &&
        rect.left > 0 &&
        rect.bottom < window.innerHeight &&
        rect.right < window.innerWidth
      );
    };
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
  • 如果元素没有插入到 DOM 树中并渲染,怎么能判断是否在首屏中?
<!-- defer 为true 优先请求加载 -->
<img v-img="{hash: 'xxx', defer: true}" />
1
2
const promises = []; // 用来存储优先加载的图片
Vue.directive("img", {
  // bind: 只调用一次,指令第一次绑定到元素是调用。在这里可以进行一次性的初始化设置
  bind(el, binding, vnode) {
    const { defer } = binding.value;
    if (!defer) {
      promises.push(update(el, binding, vnode));
    }
  },
  // inserted: 被绑定元素插入父节点时调用(仅保证父节点存在,但不一定已被插入文档中)
  inserted(elm, binding, vnode) {
    const { defer } = binding.value;
    if (!defer) return;
    if (inViewport(el)) {
      promises.push(update(el, binding, vnode));
    } else {
      Vue.nextTick(() => {
        Promise.all(promises)
          .then(() => {
            promises.length = 0;
            update(el, binding, vnode);
          })
          .catch(() => {});
      });
    }
  },
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  • 对于同域名只支持 6 个并发请求,可以进行域名切分,来提升并发的请求数量
  • 使用 HTTP/2 协议

# 部分图片体积过大

# 问题分析

如图,该图片主要耗时在Content Download阶段,图片体积过大,直接导致下载图片时间过长

# 解决方案

  • 减小图片大小

    • FileSize = Total Number Pixels * Bytes of Encode single Pixels
    • 一张 100px*100px像素的图片,就有100*100=10000个像素点,而每个像素点通过RGBA颜色值进行存储,R/G/B/A每个色道都有 0~255 个取值,即2^8=256。正好 8 位 1byte,即每个像素点 4bytes。因此该图片体积10000*4bytes=40000bytes=39KB
  • 单位像素优化

    • 有损的删除一些像素数据:减少每个色道的颜色值来减少单位像素的字节数
    • 无损的图片像素压缩:通过算法将颜色值相近的像素压缩
    • jpeg/png/gif/webp 合理使用
  • 图片像素总数优化

    • 使用 lib-flexible (opens new window) 来对不同的移动端进行适配。lib-flexible在 HTML 元素添加了两个属性data-dpr和style
    const resize = (size) => {
      let viewWidth
      const dpr = window.devicePixelRatio
      const html = document.documentElement
      const dataDpr = html.getAttribute('data-dpr')
      const ratio = dataDpr ? (dpr / dataDpr) : dpr
    
      try {
          viewWidth = +(html.getAttribute('style').match(/(\d+)/) || [])[1]
      } catch(e) {
          const w = html.offsetWidth
          if (w / dpr > 540) {
              viewWidth = 540 \* dpr / 10
          } else {
              viewWidth = w / 10
          }
      }
    
      viewWidth = viewWidth \* ratio
    
      if (Number(viewWidth) >= 0 && typeof viewWidth === 'number') {
          return (size \* viewWidth) / 75 // 75 is the 1/10 iphone6 deivce width pixel
      } else {
          return size
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
#性能
上次更新: 2021/04/22, 13:38:59
浏览器工作原理:从URL输入到页面展现到底发生了什么
白屏时间

← 浏览器工作原理:从URL输入到页面展现到底发生了什么 白屏时间→

最近更新
01
面试官
03-27
02
this&指针&作用域&闭包
03-27
03
前端
03-27
更多文章>
Theme by Vdoing | Copyright © 2019-2025 chst365 | 豫ICP备17031889号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式