Repository: GoogleChrome/lighthouse
Pull request #12435 (2021-05-03 18:30:10)

core(computed-artifact): remove settings and options from context
Splitting this out from https://github.com/GoogleChrome/lighthouse/pull/12427 because it touches a lot of files.

Previously, calculating a computed artifact in the gathering stage required us to add `settings` and `options` to the context to be compatible with `LH.Audit.Context`. This PR adds a new context with just `computedCache` that computed artifacts use.

Right now the new context is `LH.Gatherer.ComputedContext`. Changing that should be a pretty simple find and replace so I'm open to other suggestions on where it should go.


brendankenny: from `basics`:

```diff
@@ -6251,6 +6251,12 @@
         "duration": 100,
         "entryType": "measure"
       },
+      {
+        "startTime": 0,
+        "name": "lh:computed:MainResource",
+        "duration": 100,
+        "entryType": "measure"
+      },
       {
         "startTime": 0,
         "name": "lh:audit:timing-budget",

❌  FAIL. LHR has changed.
```
a good example where you think you're getting a cached computed artifact but you're not :)

In this case `lh:computed:MainResource` is usually like 0.1 ms because `NetworkRecords` _is_ cached, but it's hard to even notice you've hit this path since tsc only does the structural check. I wonder how often we trigger this.
adamraine: > a good example where you think you're getting a cached computed artifact but you're not

Yeah, this was hard to find. There may be more instances of this that we don't cover in our tests because the artifacts are only requested once.

Patch:
diff --git a/lighthouse-core/audits/metrics.js b/lighthouse-core/audits/metrics.js
index fa839d300..53820156c 100644
--- a/lighthouse-core/audits/metrics.js
+++ b/lighthouse-core/audits/metrics.js
@@ -44,7 +44,7 @@ class Metrics extends Audit {
     const trace = artifacts.traces[Audit.DEFAULT_PASS];
     const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
     const summary = await ComputedTimingSummary
-      .request({trace, devtoolsLog}, context);
+      .request({trace, devtoolsLog, settings: context.settings}, context);
     const metrics = summary.metrics;
     const debugInfo = summary.debugInfo;
 
diff --git a/lighthouse-core/audits/performance-budget.js b/lighthouse-core/audits/performance-budget.js
index c8e68a4da..217b51537 100644
--- a/lighthouse-core/audits/performance-budget.js
+++ b/lighthouse-core/audits/performance-budget.js
@@ -120,7 +120,8 @@ class ResourceBudget extends Audit {
    */
   static async audit(artifacts, context) {
     const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
-    const summary = await ResourceSummary.request({devtoolsLog, URL: artifacts.URL}, context);
+    const data = {devtoolsLog, URL: artifacts.URL, budgets: context.settings.budgets};
+    const summary = await ResourceSummary.request(data, context);
     const mainResource = await MainResource.request({URL: artifacts.URL, devtoolsLog}, context);
     const budget = Budget.getMatchingBudget(context.settings.budgets, mainResource.url);
 
diff --git a/lighthouse-core/audits/resource-summary.js b/lighthouse-core/audits/resource-summary.js
index e41da0885..5646b9fe1 100644
--- a/lighthouse-core/audits/resource-summary.js
+++ b/lighthouse-core/audits/resource-summary.js
@@ -45,7 +45,7 @@ class ResourceSummary extends Audit {
   static async audit(artifacts, context) {
     const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
     const summary = await ComputedResourceSummary
-      .request({devtoolsLog, URL: artifacts.URL}, context);
+      .request({devtoolsLog, URL: artifacts.URL, budgets: context.settings.budgets}, context);
 
     /** @type {LH.Audit.Details.Table['headings']} */
     const headings = [
diff --git a/lighthouse-core/audits/timing-budget.js b/lighthouse-core/audits/timing-budget.js
index 950c648d5..92e416ecb 100644
--- a/lighthouse-core/audits/timing-budget.js
+++ b/lighthouse-core/audits/timing-budget.js
@@ -143,7 +143,8 @@ class TimingBudget extends Audit {
     const devtoolsLog = artifacts.devtoolsLogs[Audit.DEFAULT_PASS];
     const trace = artifacts.traces[Audit.DEFAULT_PASS];
     const mainResource = await MainResource.request({URL: artifacts.URL, devtoolsLog}, context);
-    const summary = (await TimingSummary.request({trace, devtoolsLog}, context)).metrics;
+    const data = {trace, devtoolsLog, settings: context.settings};
+    const summary = (await TimingSummary.request(data, context)).metrics;
     const budget = Budget.getMatchingBudget(context.settings.budgets, mainResource.url);
 
     if (!budget) {
diff --git a/lighthouse-core/computed/computed-artifact.js b/lighthouse-core/computed/computed-artifact.js
index 268fee9d7..595ae93ce 100644
--- a/lighthouse-core/computed/computed-artifact.js
+++ b/lighthouse-core/computed/computed-artifact.js
@@ -11,7 +11,7 @@ const log = require('lighthouse-logger');
 /**
  * Decorate computableArtifact with a caching `request()` method which will
  * automatically call `computableArtifact.compute_()` under the hood.
- * @template {{name: string, compute_(artifacts: unknown, context: LH.Audit.Context): Promise<unknown>}} C
+ * @template {{name: string, compute_(artifacts: unknown, context: LH.Artifacts.ComputedContext): Promise<unknown>}} C
  * @param {C} computableArtifact
  */
 function makeComputedArtifact(computableArtifact) {
@@ -21,7 +21,7 @@ function makeComputedArtifact(computableArtifact) {
   /**
    * Return an automatically cached result from the computed artifact.
    * @param {FirstParamType<C['compute_']>} artifacts
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {ReturnType<C['compute_']>}
    */
   const request = (artifacts, context) => {
diff --git a/lighthouse-core/computed/critical-request-chains.js b/lighthouse-core/computed/critical-request-chains.js
index 3d53c33f9..667097060 100644
--- a/lighthouse-core/computed/critical-request-chains.js
+++ b/lighthouse-core/computed/critical-request-chains.js
@@ -125,7 +125,7 @@ class CriticalRequestChains {
 
   /**
    * @param {{URL: LH.Artifacts['URL'], devtoolsLog: LH.DevtoolsLog, trace: LH.Trace}} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.CriticalRequestNode>}
    */
   static async compute_(data, context) {
diff --git a/lighthouse-core/computed/layout-shift-variants.js b/lighthouse-core/computed/layout-shift-variants.js
index ceafc060c..fca642ad8 100644
--- a/lighthouse-core/computed/layout-shift-variants.js
+++ b/lighthouse-core/computed/layout-shift-variants.js
@@ -140,7 +140,7 @@ class LayoutShiftVariants {
 
   /**
    * @param {LH.Trace} trace
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<{avgSessionGap5s: number, maxSessionGap1s: number, maxSessionGap1sLimit5s: number, maxSliding1s: number, maxSliding300ms: number}>}
    */
   static async compute_(trace, context) {
diff --git a/lighthouse-core/computed/load-simulator.js b/lighthouse-core/computed/load-simulator.js
index af34f9d1d..21d5c3c72 100644
--- a/lighthouse-core/computed/load-simulator.js
+++ b/lighthouse-core/computed/load-simulator.js
@@ -13,7 +13,7 @@ const NetworkAnalysis = require('./network-analysis.js');
 class LoadSimulator {
   /**
    * @param {{devtoolsLog: LH.DevtoolsLog, settings: Immutable<LH.Config.Settings>}} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<Simulator>}
    */
   static async compute_(data, context) {
diff --git a/lighthouse-core/computed/main-resource.js b/lighthouse-core/computed/main-resource.js
index 4a432328c..d4579fb03 100644
--- a/lighthouse-core/computed/main-resource.js
+++ b/lighthouse-core/computed/main-resource.js
@@ -16,7 +16,7 @@ const NetworkRecords = require('./network-records.js');
 class MainResource {
   /**
    * @param {{URL: LH.Artifacts['URL'], devtoolsLog: LH.DevtoolsLog}} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.NetworkRequest>}
    */
   static async compute_(data, context) {
diff --git a/lighthouse-core/computed/main-thread-tasks.js b/lighthouse-core/computed/main-thread-tasks.js
index dfda2d057..4f27ae7d9 100644
--- a/lighthouse-core/computed/main-thread-tasks.js
+++ b/lighthouse-core/computed/main-thread-tasks.js
@@ -12,7 +12,7 @@ const TraceOfTab = require('./trace-of-tab.js');
 class MainThreadTasks {
   /**
    * @param {LH.Trace} trace
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<Array<LH.Artifacts.TaskNode>>}
    */
   static async compute_(trace, context) {
diff --git a/lighthouse-core/computed/metrics/cumulative-layout-shift-all-frames.js b/lighthouse-core/computed/metrics/cumulative-layout-shift-all-frames.js
index 15e3046b4..af0042135 100644
--- a/lighthouse-core/computed/metrics/cumulative-layout-shift-all-frames.js
+++ b/lighthouse-core/computed/metrics/cumulative-layout-shift-all-frames.js
@@ -15,7 +15,7 @@ const LayoutShiftVariants = require('../layout-shift-variants.js');
 class CumulativeLayoutShiftAllFrames {
   /**
    * @param {LH.Trace} trace
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<{value: number}>}
    */
   static async compute_(trace, context) {
diff --git a/lighthouse-core/computed/metrics/cumulative-layout-shift.js b/lighthouse-core/computed/metrics/cumulative-layout-shift.js
index ff830c5b2..ce9ddcd0e 100644
--- a/lighthouse-core/computed/metrics/cumulative-layout-shift.js
+++ b/lighthouse-core/computed/metrics/cumulative-layout-shift.js
@@ -12,7 +12,7 @@ const LayoutShiftVariants = require('../layout-shift-variants.js');
 class CumulativeLayoutShift {
   /**
    * @param {LH.Trace} trace
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<{value: number, debugInfo: Record<string,boolean> | null}>}
    */
   static async compute_(trace, context) {
diff --git a/lighthouse-core/computed/metrics/estimated-input-latency.js b/lighthouse-core/computed/metrics/estimated-input-latency.js
index 809f017d7..d38a0d76c 100644
--- a/lighthouse-core/computed/metrics/estimated-input-latency.js
+++ b/lighthouse-core/computed/metrics/estimated-input-latency.js
@@ -43,7 +43,7 @@ class EstimatedInputLatency extends ComputedMetric {
 
   /**
    * @param {LH.Artifacts.MetricComputationData} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.LanternMetric>}
    */
   static computeSimulatedMetric(data, context) {
diff --git a/lighthouse-core/computed/metrics/first-contentful-paint.js b/lighthouse-core/computed/metrics/first-contentful-paint.js
index 64efd5611..1b0346837 100644
--- a/lighthouse-core/computed/metrics/first-contentful-paint.js
+++ b/lighthouse-core/computed/metrics/first-contentful-paint.js
@@ -12,7 +12,7 @@ const LanternFirstContentfulPaint = require('./lantern-first-contentful-paint.js
 class FirstContentfulPaint extends ComputedMetric {
   /**
    * @param {LH.Artifacts.MetricComputationData} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.LanternMetric>}
    */
   static computeSimulatedMetric(data, context) {
diff --git a/lighthouse-core/computed/metrics/first-cpu-idle.js b/lighthouse-core/computed/metrics/first-cpu-idle.js
index a8e78f077..236d3fb30 100644
--- a/lighthouse-core/computed/metrics/first-cpu-idle.js
+++ b/lighthouse-core/computed/metrics/first-cpu-idle.js
@@ -167,7 +167,7 @@ class FirstCPUIdle extends ComputedMetric {
 
   /**
    * @param {LH.Artifacts.MetricComputationData} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.LanternMetric>}
    */
   static computeSimulatedMetric(data, context) {
diff --git a/lighthouse-core/computed/metrics/first-meaningful-paint.js b/lighthouse-core/computed/metrics/first-meaningful-paint.js
index ee9a5b97b..d952979ab 100644
--- a/lighthouse-core/computed/metrics/first-meaningful-paint.js
+++ b/lighthouse-core/computed/metrics/first-meaningful-paint.js
@@ -13,7 +13,7 @@ const LanternFirstMeaningfulPaint = require('./lantern-first-meaningful-paint.js
 class FirstMeaningfulPaint extends ComputedMetric {
   /**
    * @param {LH.Artifacts.MetricComputationData} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.LanternMetric>}
    */
   static computeSimulatedMetric(data, context) {
diff --git a/lighthouse-core/computed/metrics/interactive.js b/lighthouse-core/computed/metrics/interactive.js
index 89b5df3ad..414888013 100644
--- a/lighthouse-core/computed/metrics/interactive.js
+++ b/lighthouse-core/computed/metrics/interactive.js
@@ -142,7 +142,7 @@ class Interactive extends ComputedMetric {
 
   /**
    * @param {LH.Artifacts.MetricComputationData} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.LanternMetric>}
    */
   static computeSimulatedMetric(data, context) {
diff --git a/lighthouse-core/computed/metrics/lantern-estimated-input-latency.js b/lighthouse-core/computed/metrics/lantern-estimated-input-latency.js
index 95d746231..7bfdcec81 100644
--- a/lighthouse-core/computed/metrics/lantern-estimated-input-latency.js
+++ b/lighthouse-core/computed/metrics/lantern-estimated-input-latency.js
@@ -70,7 +70,7 @@ class LanternEstimatedInputLatency extends LanternMetric {
 
   /**
    * @param {LH.Artifacts.MetricComputationDataInput} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.LanternMetric>}
    */
   static async compute_(data, context) {
diff --git a/lighthouse-core/computed/metrics/lantern-first-cpu-idle.js b/lighthouse-core/computed/metrics/lantern-first-cpu-idle.js
index b228118ff..60fd60c47 100644
--- a/lighthouse-core/computed/metrics/lantern-first-cpu-idle.js
+++ b/lighthouse-core/computed/metrics/lantern-first-cpu-idle.js
@@ -60,7 +60,7 @@ class LanternFirstCPUIdle extends LanternInteractive {
 
   /**
    * @param {LH.Artifacts.MetricComputationDataInput} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.LanternMetric>}
    */
   static async compute_(data, context) {
diff --git a/lighthouse-core/computed/metrics/lantern-first-meaningful-paint.js b/lighthouse-core/computed/metrics/lantern-first-meaningful-paint.js
index 7edbe1b96..1abaa8dd5 100644
--- a/lighthouse-core/computed/metrics/lantern-first-meaningful-paint.js
+++ b/lighthouse-core/computed/metrics/lantern-first-meaningful-paint.js
@@ -66,7 +66,7 @@ class LanternFirstMeaningfulPaint extends LanternMetric {
 
   /**
    * @param {LH.Artifacts.MetricComputationDataInput} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.LanternMetric>}
    */
   static async compute_(data, context) {
diff --git a/lighthouse-core/computed/metrics/lantern-interactive.js b/lighthouse-core/computed/metrics/lantern-interactive.js
index aa311ef6d..326c8a35c 100644
--- a/lighthouse-core/computed/metrics/lantern-interactive.js
+++ b/lighthouse-core/computed/metrics/lantern-interactive.js
@@ -82,7 +82,7 @@ class LanternInteractive extends LanternMetric {
 
   /**
    * @param {LH.Artifacts.MetricComputationDataInput} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.LanternMetric>}
    */
   static async compute_(data, context) {
diff --git a/lighthouse-core/computed/metrics/lantern-largest-contentful-paint.js b/lighthouse-core/computed/metrics/lantern-largest-contentful-paint.js
index 3ad61c0a6..d0b3d529f 100644
--- a/lighthouse-core/computed/metrics/lantern-largest-contentful-paint.js
+++ b/lighthouse-core/computed/metrics/lantern-largest-contentful-paint.js
@@ -94,7 +94,7 @@ class LanternLargestContentfulPaint extends LanternMetric {
 
   /**
    * @param {LH.Artifacts.MetricComputationDataInput} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.LanternMetric>}
    */
   static async compute_(data, context) {
diff --git a/lighthouse-core/computed/metrics/lantern-max-potential-fid.js b/lighthouse-core/computed/metrics/lantern-max-potential-fid.js
index df9fc1c4a..6940dcbd6 100644
--- a/lighthouse-core/computed/metrics/lantern-max-potential-fid.js
+++ b/lighthouse-core/computed/metrics/lantern-max-potential-fid.js
@@ -67,7 +67,7 @@ class LanternMaxPotentialFID extends LanternMetricArtifact {
 
   /**
    * @param {LH.Artifacts.MetricComputationDataInput} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.LanternMetric>}
    */
   static async compute_(data, context) {
diff --git a/lighthouse-core/computed/metrics/lantern-metric.js b/lighthouse-core/computed/metrics/lantern-metric.js
index c2e0a3f6e..a1ee6f470 100644
--- a/lighthouse-core/computed/metrics/lantern-metric.js
+++ b/lighthouse-core/computed/metrics/lantern-metric.js
@@ -93,7 +93,7 @@ class LanternMetricArtifact {
 
   /**
    * @param {LH.Artifacts.MetricComputationDataInput} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @param {Omit<Extras, 'optimistic'>=} extras
    * @return {Promise<LH.Artifacts.LanternMetric>}
    */
@@ -148,7 +148,7 @@ class LanternMetricArtifact {
 
   /**
    * @param {LH.Artifacts.MetricComputationDataInput} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.LanternMetric>}
    */
   static async compute_(data, context) {
diff --git a/lighthouse-core/computed/metrics/lantern-speed-index.js b/lighthouse-core/computed/metrics/lantern-speed-index.js
index f010dfbf7..10e1c4629 100644
--- a/lighthouse-core/computed/metrics/lantern-speed-index.js
+++ b/lighthouse-core/computed/metrics/lantern-speed-index.js
@@ -93,7 +93,7 @@ class LanternSpeedIndex extends LanternMetric {
 
   /**
    * @param {LH.Artifacts.MetricComputationDataInput} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.LanternMetric>}
    */
   static async compute_(data, context) {
diff --git a/lighthouse-core/computed/metrics/lantern-total-blocking-time.js b/lighthouse-core/computed/metrics/lantern-total-blocking-time.js
index a7b9d2427..082625327 100644
--- a/lighthouse-core/computed/metrics/lantern-total-blocking-time.js
+++ b/lighthouse-core/computed/metrics/lantern-total-blocking-time.js
@@ -87,7 +87,7 @@ class LanternTotalBlockingTime extends LanternMetric {
 
   /**
    * @param {LH.Artifacts.MetricComputationDataInput} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.LanternMetric>}
    */
   static async compute_(data, context) {
diff --git a/lighthouse-core/computed/metrics/largest-contentful-paint.js b/lighthouse-core/computed/metrics/largest-contentful-paint.js
index 3b3bd4558..a8162ad39 100644
--- a/lighthouse-core/computed/metrics/largest-contentful-paint.js
+++ b/lighthouse-core/computed/metrics/largest-contentful-paint.js
@@ -21,7 +21,7 @@ const LanternLargestContentfulPaint = require('./lantern-largest-contentful-pain
 class LargestContentfulPaint extends ComputedMetric {
   /**
    * @param {LH.Artifacts.MetricComputationData} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.LanternMetric>}
    */
   static computeSimulatedMetric(data, context) {
diff --git a/lighthouse-core/computed/metrics/max-potential-fid.js b/lighthouse-core/computed/metrics/max-potential-fid.js
index dc65bc583..efb31af40 100644
--- a/lighthouse-core/computed/metrics/max-potential-fid.js
+++ b/lighthouse-core/computed/metrics/max-potential-fid.js
@@ -14,7 +14,7 @@ const TracingProcessor = require('../../lib/tracehouse/trace-processor.js');
 class MaxPotentialFID extends MetricArtifact {
   /**
    * @param {LH.Artifacts.MetricComputationData} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.LanternMetric>}
    */
   static computeSimulatedMetric(data, context) {
diff --git a/lighthouse-core/computed/metrics/metric.js b/lighthouse-core/computed/metrics/metric.js
index f0ff896e9..153663fda 100644
--- a/lighthouse-core/computed/metrics/metric.js
+++ b/lighthouse-core/computed/metrics/metric.js
@@ -23,7 +23,7 @@ class ComputedMetric {
 
   /**
    * @param {LH.Artifacts.MetricComputationData} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.LanternMetric>}
    */
   static computeSimulatedMetric(data, context) { // eslint-disable-line no-unused-vars
@@ -32,7 +32,7 @@ class ComputedMetric {
 
   /**
    * @param {LH.Artifacts.MetricComputationData} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.Metric>}
    */
   static computeObservedMetric(data, context) { // eslint-disable-line no-unused-vars
@@ -41,7 +41,7 @@ class ComputedMetric {
 
   /**
    * @param {LH.Artifacts.MetricComputationDataInput} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.LanternMetric|LH.Artifacts.Metric>}
    */
   static async compute_(data, context) {
diff --git a/lighthouse-core/computed/metrics/speed-index.js b/lighthouse-core/computed/metrics/speed-index.js
index 2003e25b3..67dc97b1d 100644
--- a/lighthouse-core/computed/metrics/speed-index.js
+++ b/lighthouse-core/computed/metrics/speed-index.js
@@ -13,7 +13,7 @@ const Speedline = require('../speedline.js');
 class SpeedIndex extends ComputedMetric {
   /**
    * @param {LH.Artifacts.MetricComputationData} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.LanternMetric>}
    */
   static computeSimulatedMetric(data, context) {
@@ -22,7 +22,7 @@ class SpeedIndex extends ComputedMetric {
 
   /**
    * @param {LH.Artifacts.MetricComputationData} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.Metric>}
    */
   static async computeObservedMetric(data, context) {
diff --git a/lighthouse-core/computed/metrics/timing-summary.js b/lighthouse-core/computed/metrics/timing-summary.js
index 3e90253e2..e8ab0b2a2 100644
--- a/lighthouse-core/computed/metrics/timing-summary.js
+++ b/lighthouse-core/computed/metrics/timing-summary.js
@@ -27,15 +27,16 @@ class TimingSummary {
   /**
      * @param {LH.Trace} trace
      * @param {LH.DevtoolsLog} devtoolsLog
-     * @param {LH.Audit.Context} context
+     * @param {ImmutableObject<LH.Config.Settings>} settings
+     * @param {LH.Artifacts.ComputedContext} context
      * @return {Promise<{metrics: LH.Artifacts.TimingSummary, debugInfo: Record<string,boolean>}>}
      */
-  static async summarize(trace, devtoolsLog, context) {
-    const metricComputationData = {trace, devtoolsLog, settings: context.settings};
+  static async summarize(trace, devtoolsLog, settings, context) {
+    const metricComputationData = {trace, devtoolsLog, settings};
     /**
      * @template TArtifacts
      * @template TReturn
-     * @param {{request: (artifact: TArtifacts, context: LH.Audit.Context) => Promise<TReturn>}} Artifact
+     * @param {{request: (artifact: TArtifacts, context: LH.Artifacts.ComputedContext) => Promise<TReturn>}} Artifact
      * @param {TArtifacts} artifact
      * @return {Promise<TReturn|undefined>}
      */
@@ -141,12 +142,12 @@ class TimingSummary {
     return {metrics, debugInfo};
   }
   /**
-   * @param {{trace: LH.Trace, devtoolsLog: LH.DevtoolsLog}} data
-   * @param {LH.Audit.Context} context
+   * @param {{trace: LH.Trace, devtoolsLog: LH.DevtoolsLog, settings: ImmutableObject<LH.Config.Settings>}} data
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<{metrics: LH.Artifacts.TimingSummary, debugInfo: Record<string,boolean>}>}
    */
   static async compute_(data, context) {
-    return TimingSummary.summarize(data.trace, data.devtoolsLog, context);
+    return TimingSummary.summarize(data.trace, data.devtoolsLog, data.settings, context);
   }
 }
 
diff --git a/lighthouse-core/computed/metrics/total-blocking-time.js b/lighthouse-core/computed/metrics/total-blocking-time.js
index d55318eb7..989272478 100644
--- a/lighthouse-core/computed/metrics/total-blocking-time.js
+++ b/lighthouse-core/computed/metrics/total-blocking-time.js
@@ -79,7 +79,7 @@ class TotalBlockingTime extends ComputedMetric {
 
   /**
    * @param {LH.Artifacts.MetricComputationData} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.LanternMetric>}
    */
   static computeSimulatedMetric(data, context) {
@@ -88,7 +88,7 @@ class TotalBlockingTime extends ComputedMetric {
 
   /**
    * @param {LH.Artifacts.MetricComputationData} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.Metric>}
    */
   static async computeObservedMetric(data, context) {
diff --git a/lighthouse-core/computed/module-duplication.js b/lighthouse-core/computed/module-duplication.js
index 60bca2adb..ce36daa62 100644
--- a/lighthouse-core/computed/module-duplication.js
+++ b/lighthouse-core/computed/module-duplication.js
@@ -75,7 +75,7 @@ class ModuleDuplication {
 
   /**
    * @param {LH.Artifacts} artifacts
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    */
   static async compute_(artifacts, context) {
     const bundles = await JsBundles.request(artifacts, context);
diff --git a/lighthouse-core/computed/network-analysis.js b/lighthouse-core/computed/network-analysis.js
index f3b733db7..8c4d21bb0 100644
--- a/lighthouse-core/computed/network-analysis.js
+++ b/lighthouse-core/computed/network-analysis.js
@@ -50,7 +50,7 @@ class NetworkAnalysis {
 
   /**
    * @param {LH.DevtoolsLog} devtoolsLog
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.NetworkAnalysis>}
    */
   static async compute_(devtoolsLog, context) {
diff --git a/lighthouse-core/computed/page-dependency-graph.js b/lighthouse-core/computed/page-dependency-graph.js
index ecae3d832..74dffc38f 100644
--- a/lighthouse-core/computed/page-dependency-graph.js
+++ b/lighthouse-core/computed/page-dependency-graph.js
@@ -452,7 +452,7 @@ class PageDependencyGraph {
 
   /**
    * @param {{trace: LH.Trace, devtoolsLog: LH.DevtoolsLog}} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<Node>}
    */
   static async compute_(data, context) {
diff --git a/lighthouse-core/computed/resource-summary.js b/lighthouse-core/computed/resource-summary.js
index bc3536ce8..da9e0774e 100644
--- a/lighthouse-core/computed/resource-summary.js
+++ b/lighthouse-core/computed/resource-summary.js
@@ -37,10 +37,10 @@ class ResourceSummary {
   /**
    * @param {Array<LH.Artifacts.NetworkRequest>} networkRecords
    * @param {string} mainResourceURL
-   * @param {LH.Audit.Context} context
+   * @param {ImmutableObject<LH.Budget[]|null>} budgets
    * @return {Record<LH.Budget.ResourceType, ResourceEntry>}
    */
-  static summarize(networkRecords, mainResourceURL, context) {
+  static summarize(networkRecords, mainResourceURL, budgets) {
     /** @type {Record<LH.Budget.ResourceType, ResourceEntry>} */
     const resourceSummary = {
       'stylesheet': {count: 0, resourceSize: 0, transferSize: 0},
@@ -53,7 +53,7 @@ class ResourceSummary {
       'total': {count: 0, resourceSize: 0, transferSize: 0},
       'third-party': {count: 0, resourceSize: 0, transferSize: 0},
     };
-    const budget = Budget.getMatchingBudget(context.settings.budgets, mainResourceURL);
+    const budget = Budget.getMatchingBudget(budgets, mainResourceURL);
     /** @type {ReadonlyArray<string>} */
     let firstPartyHosts = [];
     if (budget && budget.options && budget.options.firstPartyHostnames) {
@@ -102,16 +102,16 @@ class ResourceSummary {
   }
 
   /**
-   * @param {{URL: LH.Artifacts['URL'], devtoolsLog: LH.DevtoolsLog}} data
-   * @param {LH.Audit.Context} context
+   * @param {{URL: LH.Artifacts['URL'], devtoolsLog: LH.DevtoolsLog, budgets: ImmutableObject<LH.Budget[]|null>}} data
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<Record<LH.Budget.ResourceType,ResourceEntry>>}
    */
   static async compute_(data, context) {
     const [networkRecords, mainResource] = await Promise.all([
       NetworkRecords.request(data.devtoolsLog, context),
-      MainResource.request(data, context),
+      MainResource.request({devtoolsLog: data.devtoolsLog, URL: data.URL}, context),
     ]);
-    return ResourceSummary.summarize(networkRecords, mainResource.url, context);
+    return ResourceSummary.summarize(networkRecords, mainResource.url, data.budgets);
   }
 }
 
diff --git a/lighthouse-core/computed/speedline.js b/lighthouse-core/computed/speedline.js
index aac3f855a..48c74ae53 100644
--- a/lighthouse-core/computed/speedline.js
+++ b/lighthouse-core/computed/speedline.js
@@ -13,7 +13,7 @@ const TraceOfTab = require('./trace-of-tab.js');
 class Speedline {
   /**
    * @param {LH.Trace} trace
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Artifacts.Speedline>}
    */
   static async compute_(trace, context) {
diff --git a/lighthouse-core/computed/unused-css.js b/lighthouse-core/computed/unused-css.js
index 5ac250903..847446a79 100644
--- a/lighthouse-core/computed/unused-css.js
+++ b/lighthouse-core/computed/unused-css.js
@@ -136,7 +136,7 @@ class UnusedCSS {
 
   /**
    * @param {{CSSUsage: LH.Artifacts['CSSUsage'], URL: LH.Artifacts['URL'], devtoolsLog: LH.DevtoolsLog}} data
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<LH.Audit.ByteEfficiencyItem[]>}
   */
   static async compute_(data, context) {
diff --git a/lighthouse-core/computed/user-timings.js b/lighthouse-core/computed/user-timings.js
index 78c75cb76..7ad702ea3 100644
--- a/lighthouse-core/computed/user-timings.js
+++ b/lighthouse-core/computed/user-timings.js
@@ -14,7 +14,7 @@ const TraceOfTab = require('./trace-of-tab.js');
 class UserTimings {
   /**
    * @param {LH.Trace} trace
-   * @param {LH.Audit.Context} context
+   * @param {LH.Artifacts.ComputedContext} context
    * @return {Promise<Array<MarkEvent|MeasureEvent>>}
    */
   static async compute_(trace, context) {
diff --git a/types/artifacts.d.ts b/types/artifacts.d.ts
index 073da753f..8275fd809 100644
--- a/types/artifacts.d.ts
+++ b/types/artifacts.d.ts
@@ -9,6 +9,7 @@ import _LanternSimulator = require('../lighthouse-core/lib/dependency-graph/simu
 import _NetworkRequest = require('../lighthouse-core/lib/network-request.js');
 import speedline = require('speedline-core');
 import TextSourceMap = require('../lighthouse-core/lib/cdt/generated/SourceMap.js');
+import ArbitraryEqualityMap = require('../lighthouse-core/lib/arbitrary-equality-map.js');
 
 type _TaskNode = import('../lighthouse-core/lib/tracehouse/main-thread-tasks.js').TaskNode;
 
@@ -189,6 +190,10 @@ declare global {
     }
 
     module Artifacts {
+      export type ComputedContext = Immutable<{
+        computedCache: Map<string, ArbitraryEqualityMap>;
+      }>;
+
       export type NetworkRequest = _NetworkRequest;
       export type TaskNode = _TaskNode;
       export type MetaElement = LH.Artifacts['MetaElements'][0];


Test patch:
diff --git a/lighthouse-core/test/computed/metrics/timing-summary-test.js b/lighthouse-core/test/computed/metrics/timing-summary-test.js
index d0bc696a8..481d38745 100644
--- a/lighthouse-core/test/computed/metrics/timing-summary-test.js
+++ b/lighthouse-core/test/computed/metrics/timing-summary-test.js
@@ -13,8 +13,9 @@ const devtoolsLog = require('../../fixtures/traces/frame-metrics-m90.devtools.lo
 /* eslint-env jest */
 describe('Timing summary', () => {
   it('contains the correct data', async () => {
-    const context = {settings: {throttlingMethod: 'devtools'}, computedCache: new Map()};
-    const result = await TimingSummary.request({trace, devtoolsLog}, context);
+    const artifacts = {settings: {throttlingMethod: 'devtools'}, trace, devtoolsLog};
+    const context = {computedCache: new Map()};
+    const result = await TimingSummary.request(artifacts, context);
 
     expect(result.metrics).toMatchInlineSnapshot(`
       Object {
diff --git a/lighthouse-core/test/computed/resource-summary-test.js b/lighthouse-core/test/computed/resource-summary-test.js
index ec17a1643..48e2eee2b 100644
--- a/lighthouse-core/test/computed/resource-summary-test.js
+++ b/lighthouse-core/test/computed/resource-summary-test.js
@@ -19,6 +19,7 @@ function mockArtifacts(networkRecords) {
   return {
     devtoolsLog: networkRecordsToDevtoolsLog(networkRecords),
     URL: {requestedUrl: networkRecords[0].url, finalUrl: networkRecords[0].url},
+    budgets: null,
   };
 }
 
@@ -32,7 +33,7 @@ describe('Resource summary computed', () => {
       {url: 'http://cdn.example.com/script.js', resourceType: 'Script', transferSize: 50},
       {url: 'http://third-party.com/file.jpg', resourceType: 'Image', transferSize: 70},
     ]);
-    context = {computedCache: new Map(), settings: {budgets: null}};
+    context = {computedCache: new Map()};
   });
 
   it('includes all resource types, regardless of whether page contains them', async () => {
@@ -64,7 +65,7 @@ describe('Resource summary computed', () => {
     }
 
     const result = ComputedResourceSummary.summarize(
-      networkRecords, networkRecords[0].url, context);
+      networkRecords, networkRecords[0].url, artifacts.budgets);
     assert.equal(result.other.count, 1);
     assert.equal(result.other.transferSize, 50);
   });
@@ -81,7 +82,7 @@ describe('Resource summary computed', () => {
   });
 
   it('ignores records with non-network protocols', async () => {
-    context.settings.budgets = [{
+    artifacts.budgets = [{
       path: '/',
       options: {
         firstPartyHostnames: ['example.com'],
@@ -117,7 +118,7 @@ describe('Resource summary computed', () => {
 
     describe('when firstPartyHostnames is not set', () => {
       it('the root domain and all subdomains are considered first-party', async () => {
-        context.settings.budgets = null;
+        artifacts.budgets = null;
         const result = await ComputedResourceSummary.request(artifacts, context);
         expect(result['third-party'].transferSize).toBe(25 + 50 + 70);
         expect(result['third-party'].count).toBe(3);
@@ -129,7 +130,7 @@ describe('Resource summary computed', () => {
           {url: 'http://es.shopping-mall.co.uk/file.html', resourceType: 'Script', transferSize: 7},
           {url: 'http://co.uk', resourceType: 'Script', transferSize: 10},
         ]);
-        context.settings.budgets = null;
+        artifacts.budgets = null;
         const result = await ComputedResourceSummary.request(artifacts, context);
         expect(result['third-party'].transferSize).toBe(10);
         expect(result['third-party'].count).toBe(1);
@@ -140,7 +141,7 @@ describe('Resource summary computed', () => {
       const allResourcesSize = 30 + 10 + 25 + 50 + 70;
       const allResourcesCount = 5;
       it('handles subdomain hostnames correctly', async () => {
-        context.settings.budgets = [{
+        artifacts.budgets = [{
           path: '/',
           options: {
             firstPartyHostnames: ['cdn.example.com'],
@@ -152,7 +153,7 @@ describe('Resource summary computed', () => {
       });
 
       it('handles wildcard expressions correctly', async () => {
-        context.settings.budgets = [{
+        artifacts.budgets = [{
           path: '/',
           options: {
             // Matches example.com and cdn.example.com
@@ -165,7 +166,7 @@ describe('Resource summary computed', () => {
       });
 
       it('handles root domain hostname correctly', async () => {
-        context.settings.budgets = [{
+        artifacts.budgets = [{
           path: '/',
           options: {
             // Matches example.com; does not match cdn.example.com
@@ -178,7 +179,7 @@ describe('Resource summary computed', () => {
       });
 
       it('handles multiple hostnames correctly', async () => {
-        context.settings.budgets = [{
+        artifacts.budgets = [{
           path: '/',
           options: {
             firstPartyHostnames: ['example.com', 'my-cdn.com'],
@@ -190,7 +191,7 @@ describe('Resource summary computed', () => {
       });
 
       it('handles duplication of hostnames', async () => {
-        context.settings.budgets = [{
+        artifacts.budgets = [{
           path: '/',
           options: {
             firstPartyHostnames: ['my-cdn.com', 'my-cdn.com', 'my-cdn.com'],
@@ -202,7 +203,7 @@ describe('Resource summary computed', () => {
       });
 
       it('handles logical duplication of hostnames', async () => {
-        context.settings.budgets = [{
+        artifacts.budgets = [{
           path: '/',
           options: {
             firstPartyHostnames: ['example.com', '*.example.com', 'cdn.example.com'],
@@ -214,7 +215,7 @@ describe('Resource summary computed', () => {
       });
 
       it('handles using top-level domains as firstPartyHostnames correctly', async () => {
-        context.settings.budgets = [{
+        artifacts.budgets = [{
           path: '/',
           options: {
             firstPartyHostnames: ['*.com'],