XWX-AI commited on
Commit
82942de
·
1 Parent(s): f44ea82

fix: use textOnlySizeMB for PDF render time estimation

Browse files

base64 images don't increase Chromium PDF engine complexity.
The benchmark formula was calibrated on text-only HTML, so using
total HTML size (including base64) severely overestimates render time.

- Accept textOnlySizeMB from frontend (v2.0.5+)
- Fallback to total HTML size for backward compatibility with old plugins
- Use effectiveSizeMB (text-only) for timeout calculation, size limit check,
and large-file warning threshold

Files changed (1) hide show
  1. server.js +16 -9
server.js CHANGED
@@ -164,7 +164,7 @@ app.post('/api/generate_pdf', async (req, res) => {
164
  let browser = null;
165
 
166
  try {
167
- const { html, showWatermark, imageCount, totalImageSizeMB, codeTheme } = req.body;
168
  if (!html) {
169
  return res.status(400).json({ error: 'Missing html content' });
170
  }
@@ -194,14 +194,20 @@ app.post('/api/generate_pdf', async (req, res) => {
194
  const imgCount = imageCount || 0;
195
  const imgSizeMB = totalImageSizeMB || 0;
196
 
197
- console.log(`[PDF-GEN] [${getElapsed()}] 解析请求完成: HTML ${htmlSizeMB} MB, 图片 ${imgCount} 张 (${imgSizeMB} MB)`);
 
 
 
 
 
198
 
199
  // HTML 大小硬性上限:超过 8 MB 时 Chromium PDF 引擎会崩溃
 
200
  // Benchmark 验证:7.01 MB 需要 31 分钟,已超过用户可接受等待时间
201
  // 建议用户减少内容量(如精简代码块、移除冗余样式)后重试
202
- const MAX_HTML_SIZE_MB = 8;
203
- if (htmlSizeMBNum > MAX_HTML_SIZE_MB) {
204
- const errorMsg = `HTML 内容过大 (${htmlSizeMB} MB,超过 ${MAX_HTML_SIZE_MB} MB 上限),无法生成 PDF。建议:1) 精简对话内容;2) 移除大型代码块;3) 分批导出。`;
205
  console.log(`[PDF-GEN] [${getElapsed()}] ${errorMsg}`);
206
  return res.status(413).json({ error: errorMsg });
207
  }
@@ -227,9 +233,10 @@ app.post('/api/generate_pdf', async (req, res) => {
227
  // Benchmark 数据揭示 PDF 渲染时间呈三次方增长:
228
  // 0.82MB→8s, 1.64MB→16s, 3.28MB→85s, 4.92MB→>600s, 7.01MB→>1183s
229
  // 拟合公式: pdfRenderMs ≈ 10*size³ + 10*size² + 2*size (秒)
 
230
  // 超时 = 2× 安全系数, 上限 1800s (30 min)
231
  const baseTimeout = 60000;
232
- const s = htmlSizeMBNum;
233
  const pdfRenderMs = (10000 * s * s * s + 10000 * s * s + 2000 * s); // 预估 PDF 实际渲染时间 (ms)
234
  const htmlExtraMs = Math.ceil(pdfRenderMs * 2); // 2x 安全系数
235
 
@@ -255,10 +262,10 @@ app.post('/api/generate_pdf', async (req, res) => {
255
  // 动态计算 PDF 生成超时上限
256
  const pdfTimeout = Math.min(120000 + extraMs / 5 + sizeExtraMs / 5 + htmlExtraMs, 3600000);
257
 
258
- console.log(`[PDF-GEN] [${getElapsed()}] 动态超时: setContent=${(setContentTimeout / 1000).toFixed(0)}s, waitForNetworkIdle=${(networkTimeout / 1000).toFixed(0)}s, pdf=${(pdfTimeout / 1000).toFixed(0)}s (HTML=${htmlSizeMB}MB, 图片=${imgCount}张)`);
259
- if (htmlSizeMBNum > 4) {
260
  const estMinutes = (pdfTimeout / 60000).toFixed(0);
261
- console.log(`[PDF-GEN] [${getElapsed()}] ⚠️ 大文件预警: ${htmlSizeMB} MB HTML 预计需要 ${estMinutes} 分钟`);
262
  }
263
  console.log(`[PDF-GEN] [${getElapsed()}] 正在启动浏览器...`);
264
  // protocolTimeout: 0 = 禁用 CDP 协议层超时
 
164
  let browser = null;
165
 
166
  try {
167
+ const { html, showWatermark, imageCount, totalImageSizeMB, codeTheme, textOnlySizeMB } = req.body;
168
  if (!html) {
169
  return res.status(400).json({ error: 'Missing html content' });
170
  }
 
194
  const imgCount = imageCount || 0;
195
  const imgSizeMB = totalImageSizeMB || 0;
196
 
197
+ // 使用前端传来的纯文本 HTML 大小(扣除 base64 图片)做时间预估
198
+ // base64 图片不增加 Chromium PDF 引擎的渲染复杂度,benchmark 公式也是基于纯文本校准的
199
+ // 如果前端未提供(旧版本插件),回退到总大小(向后兼容)
200
+ const effectiveSizeMB = textOnlySizeMB != null ? textOnlySizeMB : htmlSizeMBNum;
201
+
202
+ console.log(`[PDF-GEN] [${getElapsed()}] 解析请求完成: HTML ${htmlSizeMB} MB (纯文本=${effectiveSizeMB.toFixed(2)} MB), 图片 ${imgCount} 张 (${imgSizeMB} MB)`);
203
 
204
  // HTML 大小硬性上限:超过 8 MB 时 Chromium PDF 引擎会崩溃
205
+ // 使用纯文本大小判断(扣除 base64 图片),与前端保持一致
206
  // Benchmark 验证:7.01 MB 需要 31 分钟,已超过用户可接受等待时间
207
  // 建议用户减少内容量(如精简代码块、移除冗余样式)后重试
208
+ const MAX_TEXT_HTML_SIZE_MB = 8;
209
+ if (effectiveSizeMB > MAX_TEXT_HTML_SIZE_MB) {
210
+ const errorMsg = `HTML 内容过大 (纯文本=${effectiveSizeMB.toFixed(2)} MB,超过 ${MAX_TEXT_HTML_SIZE_MB} MB 上限),无法生成 PDF。建议:1) 精简对话内容;2) 移除大型代码块;3) 分批导出。`;
211
  console.log(`[PDF-GEN] [${getElapsed()}] ${errorMsg}`);
212
  return res.status(413).json({ error: errorMsg });
213
  }
 
233
  // Benchmark 数据揭示 PDF 渲染时间呈三次方增长:
234
  // 0.82MB→8s, 1.64MB→16s, 3.28MB→85s, 4.92MB→>600s, 7.01MB→>1183s
235
  // 拟合公式: pdfRenderMs ≈ 10*size³ + 10*size² + 2*size (秒)
236
+ // 使用纯文本大小(扣除 base64 图片),因为图片不增加渲染复杂度
237
  // 超时 = 2× 安全系数, 上限 1800s (30 min)
238
  const baseTimeout = 60000;
239
+ const s = effectiveSizeMB;
240
  const pdfRenderMs = (10000 * s * s * s + 10000 * s * s + 2000 * s); // 预估 PDF 实际渲染时间 (ms)
241
  const htmlExtraMs = Math.ceil(pdfRenderMs * 2); // 2x 安全系数
242
 
 
262
  // 动态计算 PDF 生成超时上限
263
  const pdfTimeout = Math.min(120000 + extraMs / 5 + sizeExtraMs / 5 + htmlExtraMs, 3600000);
264
 
265
+ console.log(`[PDF-GEN] [${getElapsed()}] 动态超时: setContent=${(setContentTimeout / 1000).toFixed(0)}s, waitForNetworkIdle=${(networkTimeout / 1000).toFixed(0)}s, pdf=${(pdfTimeout / 1000).toFixed(0)}s (HTML=${htmlSizeMB}MB, 纯文本=${effectiveSizeMB.toFixed(2)}MB, 图片=${imgCount}张)`);
266
+ if (effectiveSizeMB > 4) {
267
  const estMinutes = (pdfTimeout / 60000).toFixed(0);
268
+ console.log(`[PDF-GEN] [${getElapsed()}] ⚠️ 大文件预警: 纯文本=${effectiveSizeMB.toFixed(2)} MB HTML 预计需要 ${estMinutes} 分钟`);
269
  }
270
  console.log(`[PDF-GEN] [${getElapsed()}] 正在启动浏览器...`);
271
  // protocolTimeout: 0 = 禁用 CDP 协议层超时