百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

如何在网页上高效渲染 1000 万张小图片的?

qihemm 2025-05-23 20:03 8 浏览 0 评论

最近,看到一个名为 10MPage.com 的网站,目标是记录 2025 年互联网的时代印记。每个用户都可以上传一张 64x64 像素的小图片,形成一个庞大的互联网影像档案。

正如名字所暗示的,这个页面需要承载高达 1000 万张小图片。刚开始想到这个概念时,心想如何高效渲染这些图片?。在本文中,我将分享作者尝试的各种方案,以及最终实现的高效解决方案。

在你继续阅读之前,可以先访问一下 10MPage.com 看看能不能猜到我是如何实现的。如果你已经打开了10MPage,不妨也为自己上传一张图片,抢占一个位置吧!


HTML <img>标签 vs Canvas

首先面临的选择是:用传统的 HTML 元素来渲染,还是用 Canvas 来进行绘制。

方法一:大量单独的 <img>标签

我最初使用了单独的 <img> 标签分别加载图片。我写了一个脚本,生成一个32x32(共1024张图片)的图片网格,用 Laravel Blade 模板进行渲染:

<div class="grid" id="grid">
    @for($y = 0; $y < 32; $y++)
        <div class="row">
            @for($x = 0; $x < 32; $x++)
                <div class="tile">
                    <img src="http://10mpage.test/tiles/{{$y}}x{{$x}}.png" alt="Tile {{$y}}x{{$x}}">
                </div>
            @endfor
        </div>
    @endfor
</div>

对应的 CSS 样式:

body {
    margin: 0;
    padding: 0;
    overflow: auto; /* 允许滚动 */
}

.grid {
    display: block;
    position: relative;
    width: 100%; 
}

.row {
    display: flex;
}

.tile {
    width: 64px;
    height: 64px;
    box-sizing: border-box;
    border: 1px solid #ccc;
}

.tile img {
    width: 64px;
    height: 64px;
    object-fit: cover;
}

这种方式初步看起来不错,但潜藏几个严重问题:

  • 浏览器滚动性能差
  • DOM 节点数量庞大,性能开销大
  • 大量图片同时加载,网络请求数激增
  • 难以实现平滑滚动或高级动画效果

方法二:Canvas 绘制图片

于是尝试了 Canvas 方式。首先,通过绘制一个棋盘格图案来测试 Canvas 渲染效率:

// 简化的棋盘格Canvas绘制代码示意:
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

const tileSize = 64;
let translateX = 0, translateY = 0, scale = 1;

// 绘制棋盘格
function drawGrid() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.save();
    ctx.translate(translateX, translateY);
    ctx.scale(scale, scale);

    const cols = Math.ceil(canvas.width / (tileSize * scale)) + 2;
    const rows = Math.ceil(canvas.height / (tileSize * scale)) + 2;

    for (let x = 0; x < cols; x++) {
        for (let y = 0; y < rows; y++) {
            ctx.fillStyle = (x + y) % 2 ? '#fff' : '#000';
            ctx.fillRect(x * tileSize, y * tileSize, tileSize, tileSize);
        }
    }

    ctx.restore();
}
drawGrid();

Canvas 方式优势显著:

  • 灵活的滚动和缩放功能
  • 极大减少 DOM 节点
  • 性能优秀,支持高级动画和交互效果

经过对比后,我最终选择了 Canvas 方式,它提供了更大的灵活性和更好的渲染效率。


如何优化图片加载效率?

虽然 Canvas 的性能不错,但加载数百万张小图片仍然存在巨大挑战。假设以一个标准的 1080p 屏幕为例:

  • 宽度:1920px / 64px ≈ 30 张图片
  • 高度:1080px / 64px ≈ 17 张图片
  • 共需渲染 30 × 17 = 510 张图片。

为了实现流畅滚动,页面还需提前预加载周围的图片。如果将屏幕外 8 个方向的图片也加载,意味着一次滚动需要加载 4080 张图片,这几乎是不可能瞬间加载完毕的。

解决方案:合并小图片到大图块


将小图片合并成大图块

为解决单独图片加载产生的网络请求过多的问题,设计了一个后端 PHP 控制器,将 16 × 16(256张) 小图片合并成一个大的图片块(每个块1024×1024像素)。

用户访问页面时,浏览器将仅需加载较少数量的大图块,而非大量单独图片。这极大地减少了网络请求次数,提升加载速度。

例如上面的例子,现在只需加载 24 张 大图块,而非4080张单独图片:

  • 宽度:5760px / 1024px ≈ 6 张
  • 高度:3240px / 1024px ≈ 4 张
  • 6 × 4 = 24 张图片,负载完全可控!

未上传图片的位置显示为“”号,清晰表示未填充。


一些提升用户体验的小技巧

为了更好地隐藏大图块加载细节,提升用户体验,作者采用了一些小技巧:

  • 加载动画始终显示为 64×64 的小块,使用户感知不到是加载了更大的图片块。
  • 网格总是方形加载,避免出现边界空白的视觉问题。

经验与总结

回顾整个过程,从最初的逐个加载小图片,到探索 Canvas,再到通过图片块合并优化加载效率,每一步都是在不断优化用户体验与性能之间的平衡。

相关推荐

VLOOKUP的18种高阶用法大公开!99%的人都不知道的神操作!

作为被头条用户催更的Excel课代表,今天带来让HR追着要模板、让老板主动加薪的VLOOKUP终极指南!从基础到高阶一网打尽,文末送36个行业专用模板!一、为什么你的VLOOKUP总报错?血泪大数据...

Vlooup公式,2种模糊查找匹配,1分钟学会

工作中,VLOOKUP公式使用频率是很高的,用来各种查找匹配问题今天我们分享两种模糊查找匹配问题,一种是文本的模糊查找匹配,一种是数字的模糊查找匹配问题1、文本模糊查找匹配使用模拟数据举个例子,原始数...

与vlookup功能相似的函数,照样搞定表格数据查询,简单还实用

在日常表格数据处理工作,说到数据查询,很多小伙伴首先想到的是Vlookup函数,老师的教程中也多次讲到Vlookup函数的用法和实例。其实在Excel中还有其他的数据查询函数公式或技巧,今天我们先来学...

别再折腾VLOOKUP了!DGET逆向查找10秒通关,小白必看

今天要掀翻一个“过气网红”——VLOOKUP!你是不是也经历过这些崩溃瞬间:逆向查找要交换列顺序,复制粘贴到手软!多条件查找要嵌套MATCH,公式长到怀疑人生!别忍了!今天教你用DGET函数一键封...

职场新人必学!VLOOKUP函数10分钟速成指南

正文:"今天来讲解办公人入职期初函数VLOOKUP,这是所有职场人最重要也是最基础的技能。掌握它,90%的数据查找再不用求人!特别献给刚入职场的你——别让Excel成为加班理由。"——...

巧用Vlookup函数揪出“第三者”(vlookup第三个参数是什么)

在一张Excel表格的重复记录中,让你快速列出每种不同物品第2次或第n次出现的记录,你会怎么做?Vlookup函数就有这个本事。举例来说,产品或者物流表格中往往会记录有同一货物的多笔数据(如下图的今日...

分享12个VLOOKUP超经典用法(vlookup通俗易懂)

刚毕业那会,面试的时候经常会被问到会不会用Excel?我就理直气壮地回答:“会啊。”毕竟,简历上可是写着熟练。接着面试官扔出一句“那你会VLOOKUP吗?”我还是会一口咬定:“我会。“其实,我都没用过...

查找匹配别只知道Vlookup,Sumifs也可以!

工作中遇到查找匹配问题的时候,大家第一反应是不是都想到的Vlookup公式呢,有没有小伙伴们给Sumifs一点点机会的呢,有时候Sumifs比Vlookup更好用1、Vlookup公式举个例子,左边是...

Excel函数讲解:VLOOKUP函数,轻松玩转数据查找

常用函数系列教学:VLOOKUP函数讲解(46)。不懂VLOOKUP函数怎么高效查找数据?闲话少叙直接开讲。基本含义:VLOOKUP函数用于在表格按垂直方向(到)上查找返回行数据。如何使用及注意事项?...

CHOOSEROWS+CHOOSECOLS原来是一个超级查找函数组合!

场景一:要在学生名册中,抽查一名学生成绩。公式:=CHOOSEROWS(A1:D5,2)解析:第一参数A1:D5为数据区域,第二参数2表示提取第2行数据。把数据区域改为A2:D5,结合RANDBETW...

数据查询不止有vlookup函数,自定义zlookup函数查询操作更高效

Excel数据查询,相信大家首先会想到vlookup函数。毋庸置疑vlookup函数在Excel数据查询中作用是非常的强大。但是它也有一些不能实现的数据查询。如上图所示,我们需要根据人员的出现次数,提...

「EXCEL进阶」VLOOKUP函数怎么查询一个值返回多个结果

前言:VLOOKUP函数一般一次只能返回一个结果,本例介绍通过辅助列的方法使VLOOKUP函数查询一个值,返回这个值对应的多个结果。使用场景举例:根据表格中同一数值,返回对应值的多个结果。比如这张数据...

WPS查找能手VLOOKUP函数使用方法讲解

各位同学好!今天我们来深度剖析WPS最实用的查找工具——VLOOKUP函数。这个函数能帮你在表格中快速定位并提取所需数据,可以帮你快速核对两批数据差异,还可以合并多个表格的关联信息,甚至可以帮你制作动...

Excel常用10个函数:跨表查找Vlookup,适用于大数据中查找精确值

Hello大家好,我是Office米,今天,我们将和大家一起分享交流,常用的10个函数之一:查找引用函数VLOOKUP。在说VLOOKUP函数之前,我们要先了解,平时Excel日常工作中会遇到哪些问题...

掌握了这个套路,无论用 Excel vlookup 函数查找第几次结果都很轻松

用vlookup查找默认情况下是一对一出结果,如果要一对多查找,就需要用到各种技巧,具体方法我写过非常多了,可以搜索一下历史记录。只要掌握了今天这个套路,无论你想查找第几次重复值,都易如反掌。案例...

取消回复欢迎 发表评论: