Skip to content

Commit

Permalink
misc(treemap): first pass (#11832)
Browse files Browse the repository at this point in the history
  • Loading branch information
connorjclark authored Feb 24, 2021
1 parent a985a7e commit 16a222f
Show file tree
Hide file tree
Showing 15 changed files with 18,582 additions and 17,997 deletions.
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ lighthouse-core/scripts/*
lighthouse-core/test/
lighthouse-core/third_party/src/
lighthouse-viewer/
lighthouse-treemap/
clients/
lighthouse-cli/results/
lighthouse-logger/
Expand Down
1 change: 1 addition & 0 deletions build-tracker.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module.exports = {
'dist/extension/scripts/lighthouse-ext-bundle.js',
'dist/lighthouse-dt-bundle.js',
'dist/gh-pages/viewer/src/bundled.js',
'dist/gh-pages/treemap/src/bundled.js',
'dist/lightrider/report-generator-bundle.js',
'dist/dt-report-resources/report.js',
'dist/dt-report-resources/report-generator.js',
Expand Down
2 changes: 2 additions & 0 deletions build/gh-pages-app.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ class GhPagesApp {
versionJs,
...this._resolveSourcesList(this.opts.javascripts),
];
if (process.env.DEBUG) return contents.join('\n');

const options = {
output: {preamble: license}, // Insert license at top.
};
Expand Down
79 changes: 42 additions & 37 deletions lighthouse-core/audits/script-treemap-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,8 @@

/**
* @fileoverview
* Creates treemap data for treemap app.
*/

/**
* Ex: https://gist.github.com/connorjclark/0ef1099ae994c075e36d65fecb4d26a7
* @typedef {LH.Treemap.RootNodeContainer[]} TreemapData
* Creates nodes for treemap app.
* Example output: lighthouse-treemap/app/debug.json
*/

/**
Expand Down Expand Up @@ -44,11 +40,12 @@ class ScriptTreemapDataAudit extends Audit {
* from a source map, and non-leaf nodes are directories. Leaf nodes have data
* for bytes, coverage, etc., when available, and non-leaf nodes have the
* same data as the sum of all descendant leaf nodes.
* @param {string} src
* @param {string} sourceRoot
* @param {Record<string, SourceData>} sourcesData
* @return {LH.Treemap.Node}
*/
static prepareTreemapNodes(sourceRoot, sourcesData) {
static makeScriptNode(src, sourceRoot, sourcesData) {
/**
* @param {string} name
* @return {LH.Treemap.Node}
Expand All @@ -60,7 +57,7 @@ class ScriptTreemapDataAudit extends Audit {
};
}

const topNode = newNode(sourceRoot);
const sourceRootNode = newNode(sourceRoot);

/**
* Given a slash-delimited path, traverse the Node structure and increment
Expand All @@ -71,11 +68,13 @@ class ScriptTreemapDataAudit extends Audit {
* @param {SourceData} data
*/
function addAllNodesInSourcePath(source, data) {
let node = topNode;
let node = sourceRootNode;

// Apply the data to the topNode.
topNode.resourceBytes += data.resourceBytes;
if (data.unusedBytes) topNode.unusedBytes = (topNode.unusedBytes || 0) + data.unusedBytes;
// Apply the data to the sourceRootNode.
sourceRootNode.resourceBytes += data.resourceBytes;
if (data.unusedBytes) {
sourceRootNode.unusedBytes = (sourceRootNode.unusedBytes || 0) + data.unusedBytes;
}

// Strip off the shared root.
const sourcePathSegments = source.replace(sourceRoot, '').split(/\/+/);
Expand Down Expand Up @@ -123,21 +122,36 @@ class ScriptTreemapDataAudit extends Audit {
}
}
}
collapseAll(topNode);
collapseAll(sourceRootNode);

return topNode;
// Script node should be just the script src.
const scriptNode = {...sourceRootNode};
scriptNode.name = src;
scriptNode.children = [sourceRootNode];
return scriptNode;
}

/**
* Returns root node containers where the first level of nodes are script URLs.
* If a script has a source map, that node will be set by prepareTreemapNodes.
* Returns nodes where the first level of nodes are URLs.
* Every external script has a node.
* All inline scripts are combined into a single node.
* If a script has a source map, that node will be set by makeNodeFromSourceMapData.
*
* Example return result:
- index.html (inlines scripts)
- main.js
- - webpack://
- - - react.js
- - - app.js
- i-have-no-map.js
*
* @param {LH.Artifacts} artifacts
* @param {LH.Audit.Context} context
* @return {Promise<TreemapData>}
* @return {Promise<LH.Treemap.Node[]>}
*/
static async makeRootNodes(artifacts, context) {
/** @type {LH.Treemap.RootNodeContainer[]} */
const rootNodeContainers = [];
static async makeNodes(artifacts, context) {
/** @type {LH.Treemap.Node[]} */
const nodes = [];

let inlineScriptLength = 0;
for (const scriptElement of artifacts.ScriptElements) {
Expand All @@ -149,12 +163,9 @@ class ScriptTreemapDataAudit extends Audit {
}
if (inlineScriptLength) {
const name = artifacts.URL.finalUrl;
rootNodeContainers.push({
nodes.push({
name,
node: {
name,
resourceBytes: inlineScriptLength,
},
resourceBytes: inlineScriptLength,
});
}

Expand All @@ -171,12 +182,9 @@ class ScriptTreemapDataAudit extends Audit {
// No bundle and no coverage information, so simply make a single node
// detailing how big the script is.

rootNodeContainers.push({
nodes.push({
name,
node: {
name,
resourceBytes: scriptElement.src.length,
},
resourceBytes: scriptElement.src.length,
});
continue;
}
Expand Down Expand Up @@ -215,7 +223,7 @@ class ScriptTreemapDataAudit extends Audit {
sourcesData[source] = sourceData;
}

node = this.prepareTreemapNodes(bundle.rawMap.sourceRoot || '', sourcesData);
node = this.makeScriptNode(scriptElement.src, bundle.rawMap.sourceRoot || '', sourcesData);
} else {
// No valid source map for this script, so we can only produce a single node.

Expand All @@ -226,13 +234,10 @@ class ScriptTreemapDataAudit extends Audit {
};
}

rootNodeContainers.push({
name,
node,
});
nodes.push(node);
}

return rootNodeContainers;
return nodes;
}

/**
Expand All @@ -241,7 +246,7 @@ class ScriptTreemapDataAudit extends Audit {
* @return {Promise<LH.Audit.Product>}
*/
static async audit(artifacts, context) {
const treemapData = await ScriptTreemapDataAudit.makeRootNodes(artifacts, context);
const treemapData = await ScriptTreemapDataAudit.makeNodes(artifacts, context);

// TODO: when out of experimental should make a new detail type.
/** @type {LH.Audit.Details.DebugData} */
Expand Down
Loading

0 comments on commit 16a222f

Please sign in to comment.