RNAheatmapShow.cgi程序速度递进

优化点总结
1.使用 Plotly.react() 代替 Plotly.newPlot(),加快绘图速度。
2.去除 @linked_gene_ids,防止 <a> 标签导致 JavaScript 解析问题。
✅ 确保 data 里的值是数值,避免 null 或字符串影响 Plotly 解析。
✅ 改用 document.addEventListener("DOMContentLoaded", function() {...}) 确保 DOM 先加载。
✅ 提前渲染 div,避免 JavaScript 过早执行而找不到 div。

这样应该可以提高速度和稳定性,你可以试试看! 🚀

#经过严格测试,发现1.不使用json速度会很快; 2.把js文件放到本地/var/www/html/Artocarpus/javascript/文件夹下速度很快.以下为修改后的代码:

#!/usr/bin/perl
use strict;
use warnings;
use DBI;
use CGI;
use List::Util qw(max min);

# 创建 CGI 对象并设置缓冲
$CGI::DISABLE_UPLOADS = 1;  # 禁用文件上传以提高性能
my $cgi = CGI->new;

# 设置数据库配置
my %db_config = (
    host => "localhost",
    name => "IlexGD",
    user => "IGD",
    pass => "IGDsecret",
    table => "heatmapTest"
);

# 优化基因ID处理并添加错误检查
my $gene_ids_input = $cgi->param('GeneID') || '';  # 添加默认值防止未初始化警告
if (!$gene_ids_input) {
    print $cgi->header(-type => 'text/html', -charset => 'UTF-8');
    print "Error: No gene IDs provided.";
    exit;
}

my @gene_ids = do {
    local $/ = "\n";
    grep { /\S/ }
    map { s/^\s+|\s+$//g; $_ }
    split(/\n/, $gene_ids_input);
};

# 检查是否有有效的基因ID
if (!@gene_ids) {
    print $cgi->header(-type => 'text/html', -charset => 'UTF-8');
    print "Error: No valid gene IDs found.";
    exit;
}

# 优化的数据库连接
my $dbh = DBI->connect(
    "DBI:mysql:database=$db_config{name};host=$db_config{host}",
    $db_config{user},
    $db_config{pass},
    {
        RaiseError => 1,
        AutoCommit => 1,
        mysql_enable_utf8mb4 => 1,
        mysql_auto_reconnect => 1,
        mysql_read_default_group => 'client',
        mysql_compression => 1,
        mysql_connect_timeout => 5,
        PrintError => 0,
    }
) or die "数据库连接失败: $DBI::errstr";

# 移除查询缓存相关设置,因为在新版MySQL中已不支持
# 仅保留必要的性能优化设置
$dbh->do("SET SESSION sort_buffer_size = 4194304");

# 使用预处理语句查询数据
my $placeholders = join(',', ('?') x @gene_ids);
my $sql = "SELECT * FROM $db_config{table} WHERE geneId IN ($placeholders)";

# 添加错误处理
my $sth;
eval {
    $sth = $dbh->prepare($sql);
    $sth->execute(@gene_ids);
};

if ($@) {
    print $cgi->header(-type => 'text/html', -charset => 'UTF-8');
    print "Database error: " . $DBI::errstr;
    $dbh->disconnect if $dbh;
    exit;
}

# 获取列名和数据
my $columns = $sth->{NAME};
shift @$columns;  # 移除 gene_id 列

# 处理数据
my @processed_data;
my ($min_val, $max_val) = (9999, -9999);
while (my $row = $sth->fetchrow_arrayref) {
    my @values = map {
        my $val = sprintf("%.2f", $_);
        $min_val = $val if $val < $min_val;
        $max_val = $val if $val > $max_val;
        $val;
    } @$row[1..$#$row];
    push @processed_data, \@values;
}

# 检查是否有数据返回
if (!@processed_data) {
    $sth->finish;
    $dbh->disconnect;
    print $cgi->header(-type => 'text/html', -charset => 'UTF-8');
    print "Error: No data found for the provided gene IDs.";
    exit;
}

$sth->finish;
$dbh->disconnect;

# 生成JS数组字符串
my $data_str = "[\n";
foreach my $row (@processed_data) {
    $data_str .= "[" . join(",", @$row) . "],\n";
}
$data_str =~ s/,\n$/\n/;  # 移除最后一个逗号
$data_str .= "]";

my $columns_str = "[" . join(",", map {"'$_'"} @$columns) . "]";

my $gene_ids_str = "[" . join(",", map {
    my $escaped = CGI::escapeHTML($_);
    "'<a href=\"searchGene.cgi?$escaped\">$escaped</a>'"
} @gene_ids) . "]";

# 确保在输出任何内容之前设置header
print $cgi->header(
    -type => 'text/html',
    -charset => 'UTF-8',
    -expires => '+1h',
    -cache_control => 'public, max-age=3600'
);

print <<HTML;
<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="Keywords" content="shrimp">
    <meta name="Description" content="genomic database">
    <link href="../../Artocarpus/css/dropdown.css" rel="stylesheet" type="text/css">
    <link href="../../Artocarpus/css/buttonstyle.css" rel="stylesheet" type="text/css">
    <link href="../../Artocarpus/css/style.css" rel="stylesheet" type="text/css">
    <title>IlexPortal - a portal of shrimp multi-omics data</title>
    <script src="../../Artocarpus/javascript/plotly-2.14.0.min.js"></script>
    <script language="JavaScript">
        function displaySubMenu(li) {
            var subMenu = li.getElementsByTagName("ul")[0];
            subMenu.style.display = "block";
        }
        function hideSubMenu(li) {
            var subMenu = li.getElementsByTagName("ul")[0];
            subMenu.style.display = "none";
        }
    </script>
</head>
<body>
    <table width="100%" cellspacing="0" cellpadding="0" bgcolor="#fff">
        <tr bgcolor="#B3C2C7">
            <td align="center" height="60">
                <map name="FPMap0">
                    <area href="../../Arctocarpus/index.html" shape="rect" coords="22, 2, 261, 59">
                </map>
                <img usemap="#FPMap0" runat="server" src="../../Artocarpus/images/logo.gif" hspace="0" vspace="0" border="0" width="1200" height="60">
            </td>
        </tr>
        <tr><td><hr></td></tr>
        <tr>
            <td class="menu" align="center" height="30">
                <table width="1200px">
                    <tr><td>
                        <div class="nav">
                            <ul>
                                <!-- Your menu structure here -->
                            </ul>
                        </div>
                    </td></tr>
                </table>
            </td>
        </tr>
        <tr><td align="center">
            <table cellpadding="0" bordercolorlight="#C0C0C0" cellspacing="15px" bgcolor="#EEEEEE" border="0" width="1200px">
                <tr><td>
                    <table class="tableborder" width="100%" cellpadding="0" cellspacing="15px" bgcolor="#F5F5F5">
                        <tr><td align="center"><h2>shrimp Expression Atlas</h2></td></tr>
                        <tr><td><p>&nbsp;</p></td></tr>
                        <tr><td>
                            <table class="tableborder" width="100%" cellpadding="0" cellspacing="15px" bgcolor="#ffffff">
                                <tr><td width=10%><b>Species</b>:</td><td><a href="genome.cgi?ID=Pcl"><i>Procambarus clarkii</i></a></td></tr>
                                <tr><td><b>Description</b>:</td><td>Transcriptomic analysis of the epidermis in Procambarus clarkii under different temperature stresses</td></tr>
                                <tr><td valign=top><b>Experiment</b>:</td><td>T25 (epidermis under 25^C), T35 (epidermis under 35^C), T room (epidermis under room temperature), control (epid>
                            </table>
                        </td></tr>
                        <tr><td>&nbsp;</td></tr>
                        <tr><td><b>Available analyses for Selected Genes:</b></td></tr>
                        <tr><td align="center">
                            <div id="heatmap" style="width: 100%; height: 600px;"></div>
                            <script>
                            // 直接使用JavaScript数组,避免JSON解析
                            const data = $data_str;
                            const columns = $columns_str;
                            const geneIds = $gene_ids_str;

                            // 使用 requestIdleCallback 在浏览器空闲时初始化图表
                            (window.requestIdleCallback || window.setTimeout)(() => {
                                const heatmapTrace = [{
                                    z: data,
                                    x: columns,
                                    y: geneIds,
                                    type: 'heatmap',
                                    colorscale: 'Viridis',
                                    zmin: $min_val,
                                    zmax: $max_val,
                                    hoverongaps: false,
                                    showscale: true,
                                    colorbar: {
                                        thickness: 20,
                                        len: 0.5
                                    }
                                }];

                                const layout = {
                                    width: 1130,
                                    height: 500,
                                    margin: {
                                        l: 150,
                                        t: 50,
                                        r: 50,
                                        b: 50
                                    },
                                    xaxis: {
                                        side: 'top',
                                        title: 'Samples',
                                        automargin: true,
                                        tickangle: -45
                                    },
                                    yaxis: {
                                        title: 'Expression of Genes(Log2FPKM)',
                                        automargin: true
                                    },
                                    font: {
                                        size: 10
                                    }
                                };

                                const config = {
                                    responsive: true,
                                    displayModeBar: true,
                                    displaylogo: false,
                                    scrollZoom: true,
                                    toImageButtonOptions: {
                                        format: 'svg',
                                        filename: 'heatmap',
                                        height: 500,
                                        width: 1130,
                                        scale: 1
                                    }
                                };

                                Plotly.react('heatmap', heatmapTrace, layout, config);
                            });
                            </script>
                        </td></tr>
                    </table>
                </td></tr>
            </table>
        </td></tr>
        <tr><td>
            <table cellpadding="0" cellspacing="0" bgcolor="#B3C2C7" width="100%" height="120px">
                <tr><td class="menu" style="padding-left:20px; padding-top:20px; padding-right:20px; padding-bottom:20px;" align="center">
                    <table cellpadding="0" cellspacing="15px" align="center" border="0" width="1200px" height="100%">
                        <tr><td align="left"><font color="#333333"><b>shrimpPortal</b> is developed by <a href="mailto:huxiaoao.com">Yuning Hu</a> in Freshwater Fisheries Research Institute >
                        This website is compatible with <a target="_blank" href="https://www.google.com/chrome/">Chrome</a> and <a target="_blank" href="https://www.mozilla.org/en-US/firefox>
                        <td align="right"><img alt="logo" src="../../shrimpPortal/images/logo.jpg" width="80" border="0"></td></tr>
                    </table>
                </td></tr>
            </table>
        </td></tr>
    </table>
</body>
</html>