偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

如何在網(wǎng)頁(yè)上高效渲染 1000 萬(wàn)張小圖片的?

開發(fā) 前端
從最初的逐個(gè)加載小圖片,到探索 Canvas,再到通過(guò)圖片塊合并優(yōu)化加載效率,每一步都是在不斷優(yōu)化用戶體驗(yàn)與性能之間的平衡。

最近,看到一個(gè)名為 10MPage.com 的網(wǎng)站,目標(biāo)是記錄 2025 年互聯(lián)網(wǎng)的時(shí)代印記。每個(gè)用戶都可以上傳一張 64x64 像素的小圖片,形成一個(gè)龐大的互聯(lián)網(wǎng)影像檔案。

正如名字所暗示的,這個(gè)頁(yè)面需要承載高達(dá) 1000 萬(wàn)張小圖片。剛開始想到這個(gè)概念時(shí),心想如何高效渲染這些圖片?。在本文中,我將分享作者嘗試的各種方案,以及最終實(shí)現(xiàn)的高效解決方案。

在你繼續(xù)閱讀之前,可以先訪問一下 10MPage.com 看看能不能猜到我是如何實(shí)現(xiàn)的。如果你已經(jīng)打開了10MPage,不妨也為自己上傳一張圖片,搶占一個(gè)位置吧!??

HTML <img> 標(biāo)簽 vs Canvas

首先面臨的選擇是:用傳統(tǒng)的 HTML 元素來(lái)渲染,還是用 Canvas 來(lái)進(jìn)行繪制。

方法一:大量單獨(dú)的 <img> 標(biāo)簽

我最初使用了單獨(dú)的 <img> 標(biāo)簽分別加載圖片。我寫了一個(gè)腳本,生成一個(gè)32x32(共1024張圖片)的圖片網(wǎng)格,用 Laravel Blade 模板進(jìn)行渲染:

<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>

對(duì)應(yīng)的 CSS 樣式:

body {
    margin: 0;
    padding: 0;
    overflow: auto; /* 允許滾動(dòng) */
}

.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;
}

這種方式初步看起來(lái)不錯(cuò),但潛藏幾個(gè)嚴(yán)重問題:

  • 瀏覽器滾動(dòng)性能差
  • DOM 節(jié)點(diǎn)數(shù)量龐大,性能開銷大
  • 大量圖片同時(shí)加載,網(wǎng)絡(luò)請(qǐng)求數(shù)激增
  • 難以實(shí)現(xiàn)平滑滾動(dòng)或高級(jí)動(dòng)畫效果

方法二:Canvas 繪制圖片

于是嘗試了 Canvas 方式。首先,通過(guò)繪制一個(gè)棋盤格圖案來(lái)測(cè)試 Canvas 渲染效率:

// 簡(jiǎn)化的棋盤格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 方式優(yōu)勢(shì)顯著:

  • 靈活的滾動(dòng)和縮放功能
  • 極大減少 DOM 節(jié)點(diǎn)
  • 性能優(yōu)秀,支持高級(jí)動(dòng)畫和交互效果

經(jīng)過(guò)對(duì)比后,我最終選擇了 Canvas 方式,它提供了更大的靈活性和更好的渲染效率。

如何優(yōu)化圖片加載效率?

雖然 Canvas 的性能不錯(cuò),但加載數(shù)百萬(wàn)張小圖片仍然存在巨大挑戰(zhàn)。假設(shè)以一個(gè)標(biāo)準(zhǔn)的 1080p 屏幕為例:

  • 寬度:1920px / 64px ≈ 30 張圖片
  • 高度:1080px / 64px ≈ 17 張圖片
  • 共需渲染 30 × 17 = 510 張圖片。

為了實(shí)現(xiàn)流暢滾動(dòng),頁(yè)面還需提前預(yù)加載周圍的圖片。如果將屏幕外 8 個(gè)方向的圖片也加載,意味著一次滾動(dòng)需要加載 4080 張圖片,這幾乎是不可能瞬間加載完畢的。

解決方案:合并小圖片到大圖塊。

將小圖片合并成大圖塊

為解決單獨(dú)圖片加載產(chǎn)生的網(wǎng)絡(luò)請(qǐng)求過(guò)多的問題,設(shè)計(jì)了一個(gè)后端 PHP 控制器,將 16 × 16(256張) 小圖片合并成一個(gè)大的圖片塊(每個(gè)塊1024×1024像素)。

用戶訪問頁(yè)面時(shí),瀏覽器將僅需加載較少數(shù)量的大圖塊,而非大量單獨(dú)圖片。這極大地減少了網(wǎng)絡(luò)請(qǐng)求次數(shù),提升加載速度。

例如上面的例子,現(xiàn)在只需加載 24 張 大圖塊,而非4080張單獨(dú)圖片:

  • 寬度:5760px / 1024px ≈ 6 張
  • 高度:3240px / 1024px ≈ 4 張
  • 6 × 4 = 24 張圖片,負(fù)載完全可控!

未上傳圖片的位置顯示為“?”號(hào),清晰表示未填充。

一些提升用戶體驗(yàn)的小技巧

為了更好地隱藏大圖塊加載細(xì)節(jié),提升用戶體驗(yàn),作者采用了一些小技巧:

  • 加載動(dòng)畫始終顯示為 64×64 的小塊,使用戶感知不到是加載了更大的圖片塊。
  • 網(wǎng)格總是方形加載,避免出現(xiàn)邊界空白的視覺問題。

經(jīng)驗(yàn)與總結(jié)

回顧整個(gè)過(guò)程,從最初的逐個(gè)加載小圖片,到探索 Canvas,再到通過(guò)圖片塊合并優(yōu)化加載效率,每一步都是在不斷優(yōu)化用戶體驗(yàn)與性能之間的平衡。

責(zé)任編輯:姜華 來(lái)源: 大遷世界
相關(guān)推薦

2017-05-09 09:36:52

Android App高效顯示位圖

2021-12-20 07:58:59

GitHub源碼代碼

2015-01-07 09:11:49

惡意IPipset阻止惡意IP

2013-05-22 09:59:10

HTML 5音頻

2012-08-27 10:32:12

2014-06-26 16:05:53

2018-03-25 08:44:07

iPhonePDF網(wǎng)頁(yè)

2014-06-27 14:36:03

iOS演示APP原型

2012-12-10 09:49:28

2018-09-17 13:52:39

UCloudUGC

2018-09-17 14:02:28

UCloudGUC

2018-09-17 14:06:46

UCloudUGC

2020-11-16 08:07:51

瀏覽器渲染網(wǎng)頁(yè)

2022-07-04 06:11:00

預(yù)劫持攻擊多因素認(rèn)證網(wǎng)絡(luò)攻擊

2021-09-13 09:01:02

Vue 技巧 開發(fā)工具

2022-08-03 10:45:04

人工智能網(wǎng)絡(luò)安全

2023-03-07 10:50:42

Linux命令系統(tǒng)

2021-11-18 10:37:28

加密挖礦加密貨幣安全觀察

2023-07-26 06:58:24

OpenAI顯卡GPU
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)