Upload screenshotService.js
Browse files
backend/src/services/screenshotService.js
CHANGED
|
@@ -92,7 +92,6 @@ class ScreenshotService {
|
|
| 92 |
|
| 93 |
// 内存和性能优化
|
| 94 |
'--disable-dev-shm-usage',
|
| 95 |
-
'--disable-gpu',
|
| 96 |
'--disable-extensions',
|
| 97 |
'--disable-background-timer-throttling',
|
| 98 |
'--disable-backgrounding-occluded-windows',
|
|
@@ -100,17 +99,25 @@ class ScreenshotService {
|
|
| 100 |
'--no-first-run',
|
| 101 |
'--no-default-browser-check',
|
| 102 |
'--disable-default-apps',
|
| 103 |
-
'--disable-features=TranslateUI
|
| 104 |
'--disable-ipc-flooding-protection',
|
| 105 |
|
| 106 |
// 容器环境优化 - 禁用D-Bus和系统服务
|
| 107 |
'--disable-dbus',
|
| 108 |
-
'--disable-software-rasterizer',
|
| 109 |
'--disable-field-trial-config',
|
| 110 |
'--disable-translate',
|
| 111 |
'--disable-web-security',
|
| 112 |
'--allow-running-insecure-content',
|
| 113 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
// 内存限制优化
|
| 115 |
'--js-flags=--max-old-space-size=512', // 降低JS内存使用
|
| 116 |
'--memory-pressure-off',
|
|
@@ -120,9 +127,6 @@ class ScreenshotService {
|
|
| 120 |
'--disable-background-networking',
|
| 121 |
'--disable-background-mode',
|
| 122 |
|
| 123 |
-
// 字体渲染优化
|
| 124 |
-
'--font-render-hinting=none',
|
| 125 |
-
|
| 126 |
// 禁用不必要的功能
|
| 127 |
'--disable-breakpad',
|
| 128 |
'--disable-component-update',
|
|
@@ -242,17 +246,48 @@ class ScreenshotService {
|
|
| 242 |
// 构建Google字体URL
|
| 243 |
const googleFontsUrl = `https://fonts.googleapis.com/css2?family=${this.googleFonts.join('&family=')}&display=swap`;
|
| 244 |
|
| 245 |
-
// 注入字体CSS
|
| 246 |
await page.evaluateOnNewDocument((fontsUrl) => {
|
| 247 |
// 创建link元素加载Google字体
|
| 248 |
const link = document.createElement('link');
|
| 249 |
link.rel = 'stylesheet';
|
| 250 |
link.href = fontsUrl;
|
|
|
|
| 251 |
|
| 252 |
-
//
|
| 253 |
-
|
| 254 |
-
document.head
|
| 255 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 256 |
}, googleFontsUrl);
|
| 257 |
} catch (error) {
|
| 258 |
console.warn('⚠️ Failed to inject Google Fonts:', error.message);
|
|
@@ -698,7 +733,7 @@ class ScreenshotService {
|
|
| 698 |
return document.fonts ? document.fonts.ready : Promise.resolve();
|
| 699 |
});
|
| 700 |
|
| 701 |
-
// 等待SVG
|
| 702 |
await page.evaluate(() => {
|
| 703 |
return new Promise(resolve => {
|
| 704 |
const svgs = document.querySelectorAll('svg');
|
|
@@ -707,26 +742,47 @@ class ScreenshotService {
|
|
| 707 |
return;
|
| 708 |
}
|
| 709 |
|
| 710 |
-
|
| 711 |
-
|
| 712 |
-
|
| 713 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 714 |
};
|
| 715 |
|
| 716 |
-
|
| 717 |
-
|
| 718 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 719 |
} else {
|
| 720 |
-
|
| 721 |
-
|
| 722 |
}
|
| 723 |
-
}
|
| 724 |
|
| 725 |
-
//
|
| 726 |
-
|
| 727 |
|
| 728 |
-
//
|
| 729 |
-
setTimeout(
|
|
|
|
|
|
|
|
|
|
| 730 |
});
|
| 731 |
});
|
| 732 |
|
|
|
|
| 92 |
|
| 93 |
// 内存和性能优化
|
| 94 |
'--disable-dev-shm-usage',
|
|
|
|
| 95 |
'--disable-extensions',
|
| 96 |
'--disable-background-timer-throttling',
|
| 97 |
'--disable-backgrounding-occluded-windows',
|
|
|
|
| 99 |
'--no-first-run',
|
| 100 |
'--no-default-browser-check',
|
| 101 |
'--disable-default-apps',
|
| 102 |
+
'--disable-features=TranslateUI',
|
| 103 |
'--disable-ipc-flooding-protection',
|
| 104 |
|
| 105 |
// 容器环境优化 - 禁用D-Bus和系统服务
|
| 106 |
'--disable-dbus',
|
|
|
|
| 107 |
'--disable-field-trial-config',
|
| 108 |
'--disable-translate',
|
| 109 |
'--disable-web-security',
|
| 110 |
'--allow-running-insecure-content',
|
| 111 |
|
| 112 |
+
// SVG和字体渲染优化
|
| 113 |
+
'--font-render-hinting=none', // 修复字体渲染不一致问题
|
| 114 |
+
'--enable-font-antialiasing', // 启用字体抗锯齿
|
| 115 |
+
'--force-color-profile=srgb', // 强制使用sRGB颜色配置
|
| 116 |
+
'--disable-software-rasterizer', // 禁用软件光栅化,使用硬件加速
|
| 117 |
+
'--enable-gpu-rasterization', // 启用GPU光栅化以改善SVG渲染
|
| 118 |
+
'--enable-oop-rasterization', // 启用进程外光栅化
|
| 119 |
+
'--disable-features=VizDisplayCompositor', // 禁用可能影响渲染的功能
|
| 120 |
+
|
| 121 |
// 内存限制优化
|
| 122 |
'--js-flags=--max-old-space-size=512', // 降低JS内存使用
|
| 123 |
'--memory-pressure-off',
|
|
|
|
| 127 |
'--disable-background-networking',
|
| 128 |
'--disable-background-mode',
|
| 129 |
|
|
|
|
|
|
|
|
|
|
| 130 |
// 禁用不必要的功能
|
| 131 |
'--disable-breakpad',
|
| 132 |
'--disable-component-update',
|
|
|
|
| 246 |
// 构建Google字体URL
|
| 247 |
const googleFontsUrl = `https://fonts.googleapis.com/css2?family=${this.googleFonts.join('&family=')}&display=swap`;
|
| 248 |
|
| 249 |
+
// 注入字体CSS(改进版)
|
| 250 |
await page.evaluateOnNewDocument((fontsUrl) => {
|
| 251 |
// 创建link元素加载Google字体
|
| 252 |
const link = document.createElement('link');
|
| 253 |
link.rel = 'stylesheet';
|
| 254 |
link.href = fontsUrl;
|
| 255 |
+
link.crossOrigin = 'anonymous'; // 添加跨域支持
|
| 256 |
|
| 257 |
+
// 立即添加到head,不等待DOMContentLoaded
|
| 258 |
+
const addFontLink = () => {
|
| 259 |
+
if (document.head) {
|
| 260 |
+
document.head.appendChild(link);
|
| 261 |
+
console.log('Google Fonts injected successfully');
|
| 262 |
+
} else {
|
| 263 |
+
// 如果head还不存在,等待一下再试
|
| 264 |
+
setTimeout(addFontLink, 10);
|
| 265 |
+
}
|
| 266 |
+
};
|
| 267 |
+
|
| 268 |
+
// 立即尝试添加
|
| 269 |
+
addFontLink();
|
| 270 |
+
|
| 271 |
+
// 同时添加备用字体CSS
|
| 272 |
+
const style = document.createElement('style');
|
| 273 |
+
style.textContent = `
|
| 274 |
+
* {
|
| 275 |
+
font-family: 'Noto Sans SC', 'Microsoft YaHei', 'SimHei', sans-serif !important;
|
| 276 |
+
}
|
| 277 |
+
svg text {
|
| 278 |
+
font-family: 'Noto Sans SC', 'Microsoft YaHei', 'SimHei', sans-serif !important;
|
| 279 |
+
}
|
| 280 |
+
`;
|
| 281 |
+
|
| 282 |
+
const addBackupStyle = () => {
|
| 283 |
+
if (document.head) {
|
| 284 |
+
document.head.appendChild(style);
|
| 285 |
+
} else {
|
| 286 |
+
setTimeout(addBackupStyle, 10);
|
| 287 |
+
}
|
| 288 |
+
};
|
| 289 |
+
|
| 290 |
+
addBackupStyle();
|
| 291 |
}, googleFontsUrl);
|
| 292 |
} catch (error) {
|
| 293 |
console.warn('⚠️ Failed to inject Google Fonts:', error.message);
|
|
|
|
| 733 |
return document.fonts ? document.fonts.ready : Promise.resolve();
|
| 734 |
});
|
| 735 |
|
| 736 |
+
// 等待SVG元素完全加载和渲染(改进版)
|
| 737 |
await page.evaluate(() => {
|
| 738 |
return new Promise(resolve => {
|
| 739 |
const svgs = document.querySelectorAll('svg');
|
|
|
|
| 742 |
return;
|
| 743 |
}
|
| 744 |
|
| 745 |
+
console.log(`Found ${svgs.length} SVG elements, waiting for rendering...`);
|
| 746 |
+
|
| 747 |
+
// 检查SVG是否已渲染的函数
|
| 748 |
+
const checkSVGRendered = (svg) => {
|
| 749 |
+
try {
|
| 750 |
+
// 检查SVG的bounding box是否有效
|
| 751 |
+
const bbox = svg.getBBox();
|
| 752 |
+
return bbox && bbox.width > 0 && bbox.height > 0;
|
| 753 |
+
} catch (e) {
|
| 754 |
+
// 如果getBBox失败,检查SVG是否有子元素
|
| 755 |
+
return svg.children.length > 0;
|
| 756 |
+
}
|
| 757 |
};
|
| 758 |
|
| 759 |
+
// 等待所有SVG渲染完成
|
| 760 |
+
const waitForSVGs = () => {
|
| 761 |
+
let allRendered = true;
|
| 762 |
+
|
| 763 |
+
svgs.forEach(svg => {
|
| 764 |
+
if (!checkSVGRendered(svg)) {
|
| 765 |
+
allRendered = false;
|
| 766 |
+
}
|
| 767 |
+
});
|
| 768 |
+
|
| 769 |
+
if (allRendered) {
|
| 770 |
+
console.log('All SVG elements rendered successfully');
|
| 771 |
+
resolve();
|
| 772 |
} else {
|
| 773 |
+
// 继续等待
|
| 774 |
+
setTimeout(waitForSVGs, 100);
|
| 775 |
}
|
| 776 |
+
};
|
| 777 |
|
| 778 |
+
// 开始检查
|
| 779 |
+
waitForSVGs();
|
| 780 |
|
| 781 |
+
// 超时保护,最多等待5秒
|
| 782 |
+
setTimeout(() => {
|
| 783 |
+
console.log('SVG rendering timeout, proceeding anyway');
|
| 784 |
+
resolve();
|
| 785 |
+
}, 5000);
|
| 786 |
});
|
| 787 |
});
|
| 788 |
|