Skip to content

Commit

Permalink
Merge branch 'master' into 5.0
Browse files Browse the repository at this point in the history
* master:
  revert fix Kunstmaan#1562 with new solution
  • Loading branch information
janb87 committed Aug 2, 2017
1 parent 30224d0 commit 6b7214b
Showing 1 changed file with 38 additions and 44 deletions.
82 changes: 38 additions & 44 deletions groundcontrol/critical-css.task.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { adminBundle } from './admin-bundle.tasks';
import http from 'http';
import critical from 'critical';
import fs from 'fs';
import url from 'url';
import path from 'path';
import consoleArguments from './console-arguments';
import chalk from 'chalk';
import { BUNDLES } from './start-local.task';

// TODO
// 1. Remove example of custom home page, focus on the kunstmaan bundles
// 2. Auto inject critical css into the template (src and proxy application), delay loading of main css (in background)
// 3. Add more urls
// 4. Find a way to do this on "secured" pages
// - Add more urls
// - Find a way to do this on "secured" pages
// - Compare time for "DOMContenLoaded" (how much did we win?)
// - Where does these .tmp files come from?? Remove the generation of them
// - Add "async" to script tags

// Some issues found:
// 1. Hard to do for secured webpages as we are using a proxy to a php backend (altough if we load the main css in the background on the login page this should be more or less ok as on the second visit the bundle is there)
Expand All @@ -25,24 +26,19 @@ const PAGES_TO_OPTIMIZE = [
{
url: `${consoleArguments.backendProxy}en/admin/login`,
targetFileName: 'login.html',
basePath: '.',
distPath: adminBundle.config.distPath.substring(1)
},
// css load time takes 230ms after processing with critical before 550ms (size down to 3,5KB, from 19kb)
{
url: `${consoleArguments.backendProxy}en`,
targetFileName: 'home.html',
basePath: '../../',
distPath: 'frontendpoc/data/frontendpoc/web/frontend/'
distPath: BUNDLES.admin.bundleInfo.config.distPath,
virtualPath: BUNDLES.admin.url + '/'
}
];
const CSS_REGEX = /(<link\s+rel=\"stylesheet\"\s+href=\").*(css\/.*\.css.*\"\s?(>|\/>))/gmi;
const CSS_REGEX = /(<link\s+rel=\"(stylesheet|preload)\"\s+href=\").*(css\/.*\.css.*\"\s?(>|\/>))/gmi;

const getTargetPath = item => {
const { url: itemUrl, distPath, basePath } = item;
return basePath + distPath + 'generated-static-html/' + item.targetFileName;
const getTargetPath = (item, optimized = false) => {
const { url: itemUrl, distPath } = item;
return distPath + (optimized ? getOptimizedFileName(item) : item.targetFileName);
};

const getOptimizedFileName = item => `${path.basename(item.targetFileName, '.html')}-optimized.html`;

// Create target dir if it doesn't exist
const createTargetDir = (targetDir, done) => {
fs.stat(targetDir, (err, stats) => {
Expand All @@ -54,12 +50,11 @@ const createTargetDir = (targetDir, done) => {
});
};

const writeStaticHtml = (item, done) => {
const getStaticHtml = (item, done) => {
const { url: itemUrl, distPath } = item;
http.get(itemUrl, res => {
res.on('data', chunk => {
const originalData = chunk.toString();
const data = originalData.replace(CSS_REGEX, `$1${distPath}$2`);
const data = chunk.toString();
const targetPath = getTargetPath(item);
const targetDir = path.dirname(targetPath);
createTargetDir(targetDir, err => {
Expand All @@ -73,37 +68,36 @@ const writeStaticHtml = (item, done) => {
});
};

const updateCssPathsInGeneratedHtml = (item, done) => {

const staticHtmlPath = getTargetPath(item, true);
fs.readFile(staticHtmlPath, (err, originalData) => {
// Change urls inside styles to use virtual path again
let data = originalData.toString().replace(CSS_REGEX, `$1${item.virtualPath}$3`);

// Mark "script" tags as async (which have .bundle.js)
// TODO
fs.writeFile(staticHtmlPath, data, done);
});
};

const extractCriticalCss = (item, done) => {
const basePath = item.basePath;
const distPath = item.distPath;
const urlToCheck = item.url;

const staticHtmlPath = getTargetPath(item);
fs.readFile(staticHtmlPath, (err, data) => {
fs.readFile(staticHtmlPath, (err, originalData) => {
if (err) {
done(err);
return;
}

let cssFiles = [];
let originalCssSize = 0;
// Rewrite the url to the css bundles dist path
const cssTags = data.toString().match(CSS_REGEX);
if (cssTags && cssTags.length > 0) {
cssFiles = cssTags.map(tag => {
const cssPath = tag.match(/.*href=\"(.*)\".*/i)[1];
return url.parse(cssPath).pathname;
});
for (const cssFile of cssFiles) {
const fullPath = basePath + cssFile;
originalCssSize = originalCssSize + fs.statSync(fullPath).size;
}
}
const data = originalData.toString().replace(CSS_REGEX, `$1${distPath}$3`);

critical.generate({
inline: false,
base: basePath,
dest: 'styles-critical.css',
inline: true,
base: '.',
dest: distPath + getOptimizedFileName(item),
html: data,
minify: true,
width: 1024,
Expand All @@ -113,10 +107,10 @@ const extractCriticalCss = (item, done) => {
console.log(err);
done(err);
return;
}
}

console.log(`Reduced css size for url ${urlToCheck} from ${originalCssSize} to ${output.length}`);
done();
// Update css paths again to use url format
updateCssPathsInGeneratedHtml(item, done);
});
});
};
Expand All @@ -126,7 +120,7 @@ export function generateStaticHtml(done) {
let hasError = false;
for (const itemToCheck of PAGES_TO_OPTIMIZE) {
console.log(chalk.blue('Generating static html for '), chalk.yellow(itemToCheck.url));
writeStaticHtml(itemToCheck, err => {
getStaticHtml(itemToCheck, err => {
itemsProcessed++;
if (err) {
console.log(chalk.red(err.message));
Expand Down

0 comments on commit 6b7214b

Please sign in to comment.