Skip to content

Commit

Permalink
Preload scripts and load styles in <head> (#1659)
Browse files Browse the repository at this point in the history
  • Loading branch information
divyakarippath authored Jun 2, 2020
1 parent cf64c59 commit 94a60ac
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 8 deletions.
2 changes: 2 additions & 0 deletions packages/subapp-server/src/index-page.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* @jsx createElement */

import { IndexPage, createElement, Token, Require } from "../template";
import { ReserveSpot } from "subapp-web";

const RenderSubApps = (props, context) => {
const { routeOptions } = context.user;
Expand Down Expand Up @@ -46,6 +47,7 @@ const Template = (
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<ReserveSpot saveId="headEntries" />
<Require _id="subapp-web/lib/polyfill" />
<Token _id="META_TAGS" />
<Token _id="PAGE_TITLE" />
Expand Down
10 changes: 10 additions & 0 deletions packages/subapp-web/lib/ReserveSpot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"use strict";

const ReserveSpot = (props, context) => {
if (props.saveId) {
const spot = context.output.reserve();
context.user[props.saveId] = spot;
}
};

module.exports = ReserveSpot;
2 changes: 2 additions & 0 deletions packages/subapp-web/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const { default: makeSubAppSpec } = require("../dist/node/make-subapp-spec");

const { setupFramework } = require("./util");
const lazyLoadSubApp = () => {};
const ReserveSpot = require("./ReserveSpot");

module.exports = {
// isomorphic functions
Expand All @@ -29,5 +30,6 @@ module.exports = {
init: require("./init"),
load: require("./load"),
start: require("./start"),
ReserveSpot,
xarc: { IS_BROWSER: false, HAS_WINDOW: false } // no xarc client lib on the server
};
36 changes: 29 additions & 7 deletions packages/subapp-web/lib/load.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ Response: ${err || body}`
const cdnJsBundles = util.getCdnJsBundles(assets, setupContext.routeOptions);

const bundles = entryPoints.filter(ep => !includedBundles[ep]);
const headSplits = [];
const splits = bundles
.map(ep => {
if (!inlineSubAppJs && !includedBundles[entryName]) {
Expand All @@ -153,16 +154,24 @@ Response: ${err || body}`
cdnJsBundles[ep] &&
[]
.concat(cdnJsBundles[ep])
.map(jsBundle => {
.reduce((a, jsBundle) => {
const ext = Path.extname(jsBundle);
if (ext === ".js") {
return `<script src="${jsBundle}" async></script>`;
if (context.user.headEntries) {
headSplits.push(`<link rel="preload" href="${jsBundle}" as="script">`);
}
a.push(`<script src="${jsBundle}" async></script>`);
} else if (ext === ".css") {
return `<link rel="stylesheet" href="${jsBundle}">`;
if (context.user.headEntries) {
headSplits.push(`<link rel="stylesheet" href="${jsBundle}">`);
} else {
a.push(`<link rel="stylesheet" href="${jsBundle}">`);
}
} else {
return `<!-- UNKNOWN bundle extension ${jsBundle} -->`;
a.push(`<!-- UNKNOWN bundle extension ${jsBundle} -->`);
}
})
return a;
}, [])
.join("\n")
);
}
Expand All @@ -179,7 +188,7 @@ Response: ${err || body}`
}
}

return { bundles, scripts: splits.join("\n") };
return { bundles, scripts: splits.join("\n"), preLoads: headSplits.join("\n") };
};

const loadSubApp = () => {
Expand Down Expand Up @@ -210,6 +219,8 @@ Response: ${err || body}`

const { request } = context.user;

context.user.numOfSubapps = context.user.numOfSubapps || 0;

if (request.app.webpackDev && subAppLoadTime < request.app.webpackDev.compileTime) {
subAppLoadTime = request.app.webpackDev.compileTime;
loadSubApp();
Expand Down Expand Up @@ -312,6 +323,11 @@ ${stack}`,
}

outputSpot.close();
context.user.numOfSubapps--;
if (context.user.numOfSubapps === 0 && context.user.headEntries) {
context.user.headEntries.close();
context.user.headEntries = undefined;
}
};

ssrInfo.done = () => {
Expand All @@ -329,13 +345,19 @@ ${stack}`,
ssrGroups
};

const { bundles, scripts } = await prepareSubAppSplitBundles(context);
context.user.numOfSubapps++;
const { bundles, scripts, preLoads } = await prepareSubAppSplitBundles(context);
outputSpot.add(`${comment}`);
if (bundles.length > 0) {
outputSpot.add(`${scripts}
<script>${xarc}.markBundlesLoaded(${JSON.stringify(bundles)});</script>
`);
}
if (preLoads.length > 0) {
context.user.headEntries.add("\n");
context.user.headEntries.add(preLoads);
context.user.headEntries.add("\n");
}

if (props.serverSideRendering) {
const lib = (ssrInfo.lib = util.getFramework(ref));
Expand Down
3 changes: 2 additions & 1 deletion packages/subapp-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
"jsdom": "^15.2.1",
"mock-require": "^1.3.0",
"run-verify": "^1.2.2",
"subapp-pkg-util": "../subapp-pkg-util"
"subapp-pkg-util": "../subapp-pkg-util",
"electrode-react-webapp": "^3.8.9"
},
"fyn": {
"dependencies": {
Expand Down
83 changes: 83 additions & 0 deletions packages/subapp-web/test/spec/load.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
"use strict";

const { load } = require("../../lib");
const utils = require("../../lib/util");
const Path = require("path");
const reserveSpot = require("../../lib/ReserveSpot");
const RenderOutput = require("electrode-react-webapp/lib/render-output");

describe("load", function () {
const statsPath = Path.join(__dirname, "../data/dev-stats.json");
const { assets } = utils.loadAssetsFromStats(statsPath);
let context;
let setUpContext;
let props;

beforeEach(() => {
setUpContext = {
routeOptions: {
cdn: {},
__internals: {
assets
}
}
};
context = {
user: {
request: { app: {} },
assets,
includedBundles: {}
},
transform: x => x
};
props = {
props: {
serverSideRendering: false
}
};
utils.resetCdn();
});

afterEach(() => {
delete process.env.NODE_ENV;
delete process.env.APP_SRC_DIR;
});

it("should load bundles for the subapp", done => {
process.env.APP_SRC_DIR = "test/subapps";
const loadToken = load(setUpContext, { props: { name: "mainbody" } });

context.send = results => {
expect(results).to.not.be.empty;
expect(context.user.includedBundles).to.include({ mainbody: true });
expect(results).to.include(`<script src="mainbody.bundle.dev.js" async></script>`);
expect(results).to.include(
`<script src="ae56dc06d35e1170d047.vendors~280289005828299c685d173f73011e79.js" async></script>`
);
expect(context.user.headEntries).to.not.be.ok;
done();
};
context.output = new RenderOutput(context);

loadToken.process(context, props);
context.output.close();
});

it("should load preload tags for scripts", done => {
process.env.APP_SRC_DIR = "test/subapps";
const loadToken = load(setUpContext, { props: { name: "mainbody" } });

context.send = results => {
expect(results).to.not.be.empty;
expect(results).to.include(`<link rel="preload" href="mainbody.bundle.dev.js" as="script">`);
expect(results).to.include(`<script src="mainbody.bundle.dev.js" async></script>`);
expect(context.user.includedBundles).to.include({ mainbody: true });
done();
};
context.output = new RenderOutput(context);
reserveSpot({ saveId: "headEntries" }, context);

loadToken.process(context, props);
context.output.close();
});
});
3 changes: 3 additions & 0 deletions packages/subapp-web/test/subapps/subapp1/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
foo: () => 123
};
3 changes: 3 additions & 0 deletions packages/subapp-web/test/subapps/subapp1/src/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
name: "mainbody"
};
6 changes: 6 additions & 0 deletions packages/subapp-web/test/subapps/subapp1/src/subapp-conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
name: "mainbody",
subAppDir: "Subapp1/src",
entry: "index.js",
serverEntry: "server.js"
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
name: "mainbody",
subAppDir: "subapp1/src",
entry: "index.js",
serverEntry: "server.js"
};

0 comments on commit 94a60ac

Please sign in to comment.