mirror of https://github.com/status-im/metro.git
Move preloaded modules to startup code section
Summary:We found that moving the preloaded modules to the startup section of the RAM Bundle improves TTI quite a bit by saving lots of through the bridge calls and injecting multiple modules at once on JSC. However, doing this on a non hacky way required a lot of work. The main changes this diff does are: - Add to `BundleBase` additional bundling options. This options are fetched based on the entry file we're building by invoking a module that exports a function (`getBundleOptionsModulePath`). - Implement `BundleOptions` module to include the `numPreloadedModules` attribute as a bundle additional option. This value is computed by getting the dependencies the entry file has and looking for the first module that exports a module we don't want to preload. The `numPreloadedModules` attribute is then used to decide where to splice the array of modules. - Additional kung fu to make sure sourcemaps work for both preloaded and non preloaded modules. Reviewed By: davidaurelio Differential Revision: D3046534 fb-gh-sync-id: 80b676222ca3bb8b9eecc912a7963be94d3dee1a shipit-source-id: 80b676222ca3bb8b9eecc912a7963be94d3dee1a
This commit is contained in:
parent
18612273be
commit
c0f446d7e2
|
@ -25,6 +25,8 @@ class Bundle extends BundleBase {
|
||||||
this._numPrependedModules = 0;
|
this._numPrependedModules = 0;
|
||||||
this._numRequireCalls = 0;
|
this._numRequireCalls = 0;
|
||||||
this._minify = minify;
|
this._minify = minify;
|
||||||
|
|
||||||
|
this._ramBundle = null; // cached RAM Bundle
|
||||||
}
|
}
|
||||||
|
|
||||||
addModule(resolver, resolutionResponse, module, moduleTransport) {
|
addModule(resolver, resolutionResponse, module, moduleTransport) {
|
||||||
|
@ -73,6 +75,7 @@ class Bundle extends BundleBase {
|
||||||
virtual: true,
|
virtual: true,
|
||||||
sourceCode: code,
|
sourceCode: code,
|
||||||
sourcePath: name + '.js',
|
sourcePath: name + '.js',
|
||||||
|
meta: {preloaded: true},
|
||||||
}));
|
}));
|
||||||
this._numRequireCalls += 1;
|
this._numRequireCalls += 1;
|
||||||
}
|
}
|
||||||
|
@ -103,7 +106,46 @@ class Bundle extends BundleBase {
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
getUnbundle() {
|
getUnbundle(type) {
|
||||||
|
if (this._ramBundle) {
|
||||||
|
return this._ramBundle;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'INDEX':
|
||||||
|
this._ramBundle = this._getAsIndexedFileUnbundle();
|
||||||
|
break;
|
||||||
|
case 'ASSETS':
|
||||||
|
this._ramBundle = this._getAsAssetsUnbundle();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error('Unkown RAM Bundle type:', type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._ramBundle;
|
||||||
|
}
|
||||||
|
|
||||||
|
_getAsIndexedFileUnbundle() {
|
||||||
|
const modules = this.getModules();
|
||||||
|
|
||||||
|
// separate modules we need to preload from the ones we don't
|
||||||
|
const shouldPreload = (module) => module.meta && module.meta.preloaded;
|
||||||
|
const preloaded = modules.filter(module => shouldPreload(module));
|
||||||
|
const notPreloaded = modules.filter(module => !shouldPreload(module));
|
||||||
|
|
||||||
|
// code that will be executed on bridge start up
|
||||||
|
const startupCode = preloaded.map(({code}) => code).join('\n');
|
||||||
|
|
||||||
|
return {
|
||||||
|
// include copy of all modules on the order they're writen on the bundle:
|
||||||
|
// polyfills, preloaded, additional requires, non preloaded
|
||||||
|
allModules: preloaded.concat(notPreloaded),
|
||||||
|
startupCode, // no entries on the index for these modules, only the code
|
||||||
|
modules: notPreloaded, // we include both the code and entries on the index
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
_getAsAssetsUnbundle() {
|
||||||
const allModules = this.getModules().slice();
|
const allModules = this.getModules().slice();
|
||||||
const prependedModules = this._numPrependedModules;
|
const prependedModules = this._numPrependedModules;
|
||||||
const requireCalls = this._numRequireCalls;
|
const requireCalls = this._numRequireCalls;
|
||||||
|
|
|
@ -60,9 +60,8 @@ class BundleBase {
|
||||||
|
|
||||||
finalize(options) {
|
finalize(options) {
|
||||||
Object.freeze(this._modules);
|
Object.freeze(this._modules);
|
||||||
Object.seal(this._modules);
|
|
||||||
Object.freeze(this._assets);
|
Object.freeze(this._assets);
|
||||||
Object.seal(this._assets);
|
|
||||||
this._finalized = true;
|
this._finalized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,9 +96,8 @@ class BundleBase {
|
||||||
bundle.setMainModuleId(json.mainModuleId);
|
bundle.setMainModuleId(json.mainModuleId);
|
||||||
|
|
||||||
Object.freeze(bundle._modules);
|
Object.freeze(bundle._modules);
|
||||||
Object.seal(bundle._modules);
|
|
||||||
Object.freeze(bundle._assets);
|
Object.freeze(bundle._assets);
|
||||||
Object.seal(bundle._assets);
|
|
||||||
bundle._finalized = true;
|
bundle._finalized = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -356,13 +356,13 @@ class Bundler {
|
||||||
const modulesByName = Object.create(null);
|
const modulesByName = Object.create(null);
|
||||||
|
|
||||||
if (!resolutionResponse) {
|
if (!resolutionResponse) {
|
||||||
let onProgess = noop;
|
let onProgress = noop;
|
||||||
if (process.stdout.isTTY && !this._opts.silent) {
|
if (process.stdout.isTTY && !this._opts.silent) {
|
||||||
const bar = new ProgressBar(
|
const bar = new ProgressBar(
|
||||||
'transformed :current/:total (:percent)',
|
'transformed :current/:total (:percent)',
|
||||||
{complete: '=', incomplete: ' ', width: 40, total: 1},
|
{complete: '=', incomplete: ' ', width: 40, total: 1},
|
||||||
);
|
);
|
||||||
onProgess = (_, total) => {
|
onProgress = (_, total) => {
|
||||||
bar.total = total;
|
bar.total = total;
|
||||||
bar.tick();
|
bar.tick();
|
||||||
};
|
};
|
||||||
|
@ -373,7 +373,7 @@ class Bundler {
|
||||||
dev,
|
dev,
|
||||||
platform,
|
platform,
|
||||||
hot,
|
hot,
|
||||||
onProgess,
|
onProgress,
|
||||||
minify,
|
minify,
|
||||||
generateSourceMaps: unbundle,
|
generateSourceMaps: unbundle,
|
||||||
});
|
});
|
||||||
|
@ -383,10 +383,22 @@ class Bundler {
|
||||||
Activity.endEvent(findEventId);
|
Activity.endEvent(findEventId);
|
||||||
onResolutionResponse(response);
|
onResolutionResponse(response);
|
||||||
|
|
||||||
|
// get entry file complete path (`entryFile` is relative to roots)
|
||||||
|
let entryFilePath;
|
||||||
|
if (response.dependencies.length > 0) {
|
||||||
|
const numModuleSystemDependencies =
|
||||||
|
this._resolver.getModuleSystemDependencies({dev, unbundle}).length;
|
||||||
|
entryFilePath = response.dependencies[
|
||||||
|
response.numPrependedDependencies +
|
||||||
|
numModuleSystemDependencies
|
||||||
|
].path;
|
||||||
|
}
|
||||||
|
|
||||||
const toModuleTransport = module =>
|
const toModuleTransport = module =>
|
||||||
this._toModuleTransport({
|
this._toModuleTransport({
|
||||||
module,
|
module,
|
||||||
bundle,
|
bundle,
|
||||||
|
entryFilePath,
|
||||||
transformOptions: response.transformOptions,
|
transformOptions: response.transformOptions,
|
||||||
}).then(transformed => {
|
}).then(transformed => {
|
||||||
modulesByName[transformed.name] = module;
|
modulesByName[transformed.name] = module;
|
||||||
|
@ -432,7 +444,7 @@ class Bundler {
|
||||||
hot = false,
|
hot = false,
|
||||||
recursive = true,
|
recursive = true,
|
||||||
generateSourceMaps = false,
|
generateSourceMaps = false,
|
||||||
onProgess,
|
onProgress,
|
||||||
}) {
|
}) {
|
||||||
return this.getTransformOptions(
|
return this.getTransformOptions(
|
||||||
entryFile,
|
entryFile,
|
||||||
|
@ -450,11 +462,12 @@ class Bundler {
|
||||||
platform,
|
platform,
|
||||||
transform: transformSpecificOptions,
|
transform: transformSpecificOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
return this._resolver.getDependencies(
|
return this._resolver.getDependencies(
|
||||||
entryFile,
|
entryFile,
|
||||||
{dev, platform, recursive},
|
{dev, platform, recursive},
|
||||||
transformOptions,
|
transformOptions,
|
||||||
onProgess,
|
onProgress,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -491,7 +504,7 @@ class Bundler {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_toModuleTransport({module, bundle, transformOptions}) {
|
_toModuleTransport({module, bundle, entryFilePath, transformOptions}) {
|
||||||
let moduleTransport;
|
let moduleTransport;
|
||||||
if (module.isAsset_DEPRECATED()) {
|
if (module.isAsset_DEPRECATED()) {
|
||||||
moduleTransport = this._generateAssetModule_DEPRECATED(bundle, module);
|
moduleTransport = this._generateAssetModule_DEPRECATED(bundle, module);
|
||||||
|
@ -509,15 +522,24 @@ class Bundler {
|
||||||
module.read(transformOptions),
|
module.read(transformOptions),
|
||||||
]).then((
|
]).then((
|
||||||
[name, {code, dependencies, dependencyOffsets, map, source}]
|
[name, {code, dependencies, dependencyOffsets, map, source}]
|
||||||
) => new ModuleTransport({
|
) => {
|
||||||
|
const preloaded =
|
||||||
|
module.path === entryFilePath ||
|
||||||
|
module.isPolyfill() || (
|
||||||
|
transformOptions.transform.preloadedModules &&
|
||||||
|
transformOptions.transform.preloadedModules.hasOwnProperty(module.path)
|
||||||
|
);
|
||||||
|
|
||||||
|
return new ModuleTransport({
|
||||||
name,
|
name,
|
||||||
id: this._getModuleId(module),
|
id: this._getModuleId(module),
|
||||||
code,
|
code,
|
||||||
map,
|
map,
|
||||||
meta: {dependencies, dependencyOffsets},
|
meta: {dependencies, dependencyOffsets, preloaded},
|
||||||
sourceCode: source,
|
sourceCode: source,
|
||||||
sourcePath: module.path
|
sourcePath: module.path
|
||||||
}));
|
})
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getGraphDebugInfo() {
|
getGraphDebugInfo() {
|
||||||
|
|
|
@ -136,7 +136,11 @@ class SocketServer {
|
||||||
_reply(sock, id, type, data) {
|
_reply(sock, id, type, data) {
|
||||||
debug('request finished', type);
|
debug('request finished', type);
|
||||||
|
|
||||||
|
try {
|
||||||
data = toJSON(data);
|
data = toJSON(data);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('SocketServer exception:', e);
|
||||||
|
}
|
||||||
|
|
||||||
sock.write(bser.dumpToBuffer({
|
sock.write(bser.dumpToBuffer({
|
||||||
id,
|
id,
|
||||||
|
|
Loading…
Reference in New Issue