You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask中send_file配合表格图片滚动懒加载失效问题解决

解决Flask表格图片滚动懒加载问题

一、修复基础懒加载失效问题

你的懒加载不生效核心原因是img标签直接设置了src属性,浏览器会优先加载src指向的资源,懒加载插件根本无法拦截。按以下步骤修改:

1. 调整前端img标签代码

将src替换为懒加载插件识别的data-src,同时给src设置一个极小的空白占位图(用base64编码避免额外请求):

<td>
    <a href="#" data-toggle="modal" data-target="#imageModal{{ id }}">
        <img data-src="{{ url_for('getLogImage', fn=id.zfill(12) ~ '.jpg') }}" 
             src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" 
             class="lazy rounded" width="100px" height="100px">
    </a>
</td>

2. 正确配置lazyload插件

由于你的滚动容器是.scrollable-table(不是全局window),初始化时必须指定container参数,否则插件无法监听正确的滚动事件:

$(document).ready(function() {
    // 初始化懒加载,指定滚动容器并设置提前加载阈值
    $("img.lazy").lazyload({
        container: $('.scrollable-table'),
        threshold: 200 // 提前200px加载即将进入可视区域的图片
    });
});

无需手动在scroll事件里重复调用lazyload,插件会自动监听容器的滚动事件


二、解决8万行DOM性能问题

即使修复了懒加载,8万行表格DOM会导致页面渲染极慢、CPU占用过高,必须配合虚拟滚动(只渲染可视区域内的行+少量缓冲行):

1. 改造表格结构

添加空白占位行模拟完整表格高度,避免滚动时出现空白:

<div class="scrollable-table" style="height:72vh; width:90vw; overflow:scroll;" id="scrollContainer">
    <table id="logTable" class="table">
        <thead class="sticky-top" style="background-color: #f8f9fa;">
            <tr>
                <th>Date and time</th>
                <th>Image</th>
            </tr>
        </thead>
        <tbody id="tableBody">
            <!-- 动态渲染的行放在这里 -->
        </tbody>
        <!-- 空白占位行,模拟完整表格高度 -->
        <tbody id="placeholderBody">
            <tr style="height: {{ imgids|length * 120 }}px;"> <!-- 假设每行高度120px,根据实际调整 -->
                <td colspan="2"></td>
            </tr>
        </tbody>
    </table>
</div>

2. 实现虚拟滚动逻辑

$(document).ready(function() {
    const container = $('#scrollContainer');
    const tableBody = $('#tableBody');
    const totalRows = {{ imgids|length }};
    const rowHeight = 120; // 每行高度,需和实际渲染行高度一致
    const bufferRows = 20; // 上下缓冲行数,避免滚动时闪屏
    const imgData = {{ imgids|tojson }};
    const dateData = {{ dateTime|tojson }};

    // 渲染指定范围的行
    function renderRows(start, end) {
        tableBody.empty();
        for (let i = start; i < end; i++) {
            if (i >= totalRows) break;
            const id = imgData[i];
            const dt = dateData[i];
            const imgUrl = "{{ url_for('getLogImage', fn='') }}" + id.zfill(12) + '.jpg';
            const row = `
                <tr>
                    <td>${dt}</td>
                    <td>
                        <a href="#" data-toggle="modal" data-target="#imageModal${id}">
                            <img data-src="${imgUrl}" 
                                 src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" 
                                 class="lazy rounded" width="100px" height="100px">
                        </a>
                    </td>
                </tr>
            `;
            tableBody.append(row);
        }
        // 重新初始化懒加载
        $("img.lazy").lazyload({
            container: container,
            threshold: 200
        });
    }

    // 计算当前可视范围的行
    function calculateVisibleRows() {
        const scrollTop = container.scrollTop();
        const startRow = Math.max(0, Math.floor(scrollTop / rowHeight) - bufferRows);
        const endRow = Math.min(totalRows, startRow + bufferRows * 2 + Math.ceil(container.height() / rowHeight));
        renderRows(startRow, endRow);
    }

    // 初始化渲染
    calculateVisibleRows();

    // 监听滚动事件更新渲染
    container.scroll(calculateVisibleRows);
});

三、Flask后端优化(可选)

为了进一步提升图片加载速度,给接口添加安全校验和缓存控制:

from flask import send_file, request
from werkzeug.utils import secure_filename
import os

@app.route('/getLogImage/')
def getLogImage():
    fileName = request.args.get('fn', None)
    if not fileName:
        return "Missing filename", 400
    # 安全校验文件名,防止路径遍历攻击
    safe_fn = secure_filename(fileName)
    img_path = os.path.join("D:/images/", safe_fn)
    if not os.path.exists(img_path):
        return "Image not found", 404
    # 添加缓存控制,让浏览器缓存图片30天
    return send_file(img_path, mimetype='image/jpg', cache_timeout=2592000)

内容的提问来源于stack exchange,提问作者sharkyenergy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 15:55:43