66 lines
1.9 KiB
JavaScript
66 lines
1.9 KiB
JavaScript
import puppeteer from 'puppeteer';
|
|
import redisClient from './redis/index.js';
|
|
|
|
const MAX_WSE = 4; //启动几个浏览器
|
|
let WSE_LIST = []; //存储browserWSEndpoint列表
|
|
|
|
init()
|
|
|
|
async function ssr(url) {
|
|
const REDIS_KEY = `ssr:${url}`;
|
|
const CACHE_TIME = 600; // 10 分钟缓存
|
|
const CACHE_HTML = await redisClient.get(REDIS_KEY);
|
|
|
|
if (CACHE_HTML) {
|
|
return { html: CACHE_HTML, ttRenderMs: 0 };
|
|
}
|
|
|
|
const start = Date.now();
|
|
|
|
let tmp = Math.floor(Math.random()* MAX_WSE);
|
|
let browserWSEndpoint = WSE_LIST[tmp];
|
|
const browser = await puppeteer.connect({browserWSEndpoint});
|
|
|
|
const page = await browser.newPage();
|
|
try {
|
|
// networkidle0 waits for the network to be idle (no requests for 500ms).
|
|
await page.goto(url, {waitUntil: 'networkidle0'});
|
|
await page.waitForSelector('#root', { timeout: 30000 }); // ensure #posts exists in the DOM.
|
|
} catch (err) {
|
|
console.error(err);
|
|
// throw new Error('page.goto/waitForSelector timed out.');
|
|
}
|
|
|
|
const html = await page.content(); // serialized HTML of page DOM.
|
|
await page.close();
|
|
|
|
const ttRenderMs = Date.now() - start;
|
|
console.info(`Puppeteer rendered page: ${url} in: ${ttRenderMs}ms`);
|
|
|
|
redisClient.set(REDIS_KEY, html, 'EX', CACHE_TIME); // cache rendered page.
|
|
|
|
return {html, ttRenderMs};
|
|
}
|
|
|
|
function init(){
|
|
(async () => {
|
|
for(var i=0;i<MAX_WSE;i++){
|
|
const browser = await puppeteer.launch({headless:'new',
|
|
args: [
|
|
'--disable-gpu',
|
|
'--disable-dev-shm-usage',
|
|
'--disable-setuid-sandbox',
|
|
'--no-first-run',
|
|
'--no-sandbox',
|
|
'--no-zygote',
|
|
'--single-process'
|
|
]});
|
|
let browserWSEndpoint = await browser.wsEndpoint();
|
|
WSE_LIST[i] = browserWSEndpoint;
|
|
}
|
|
console.log(WSE_LIST);
|
|
})();
|
|
}
|
|
|
|
|
|
export {ssr as default}; |