Repository: GoogleChrome/lighthouse
Pull request #9772 (2019-10-02 16:59:39)

misc: more releasing tweaks
another iteration of trying to streamline this thing :)


Patch:
diff --git a/.gitignore b/.gitignore
index 321c5a9de..9fb7dedeb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,6 +32,7 @@ last-run-results.html
 
 latest-run
 lantern-data
+timings-data
 
 closure-error.log
 yarn-error.log
diff --git a/changelog.md b/changelog.md
index 76c24ebf8..bca4da08a 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,49 @@
+<a name="5.5.0"></a>
+# 5.5.0 (2019-10-02)
+
+## Notable changes
+* Preliminary implementation of the [Largest Contentful Paint](https://web.dev/largest-contentful-paint) metric has landed (`devtools` and `provided` throttling only) and can be found in the hidden `metrics` audit in the raw LHR JSON ([#9706](https://github.com/googlechrome/lighthouse/pull/9706))
+* The creation of main-thread tasks from a trace is now more robust. This should significantly reduce the occurrence of Issue [#7764](https://github.com/GoogleChrome/lighthouse/issues/7764), `"Fatal trace logic error - expected start event, got X"` ([#9491](https://github.com/googlechrome/lighthouse/pull/9491))
+* `<script>` element `id` has been added to the `ScriptElements` artifact ([#9718](https://github.com/googlechrome/lighthouse/pull/9718))
+
+## New contributors!
+Thanks to @LarsKumbier, @TimvdLippe, and @uchoudh for their first contributions!
+
+## Core
+
+* network-recorder: remove quic-request-finished workaround ([#9744](https://github.com/googlechrome/lighthouse/pull/9744))
+* network-recorder: optimize network idle detection ([#9712](https://github.com/googlechrome/lighthouse/pull/9712))
+* unused-css-rules: no more infinity savings ([#9731](https://github.com/googlechrome/lighthouse/pull/9731))
+
+## Clients
+
+* devtools: expose `registerLocaleData` to worker ([#9645](https://github.com/googlechrome/lighthouse/pull/9645))
+* devtools: update references to `Runtime.cachedResources` ([#9758](https://github.com/googlechrome/lighthouse/pull/9758))
+
+## Docs
+
+* new documentation for running Lighthouse on [authenticated pages](https://github.com/GoogleChrome/lighthouse/blob/a7e823ebf017224a3528a5a337e3b79c2983fee5/docs/authenticated-pages.md) ([#9628](https://github.com/googlechrome/lighthouse/pull/9628), [#9705](https://github.com/googlechrome/lighthouse/pull/9705))
+* point more docs links to web.dev ([#9540](https://github.com/googlechrome/lighthouse/pull/9540), [#9711](https://github.com/googlechrome/lighthouse/pull/9711), [#9761](https://github.com/googlechrome/lighthouse/pull/9761))
+* readme: add more related projects ([#9716](https://github.com/googlechrome/lighthouse/pull/9716), [#9743](https://github.com/googlechrome/lighthouse/pull/9743))
+* releasing: add schedule, more integration testing ([#9695](https://github.com/googlechrome/lighthouse/pull/9695))
+* add links to more info about throttling and variability ([#9734](https://github.com/googlechrome/lighthouse/pull/9734))
+* update scoring calculator link to v5 ([#9729](https://github.com/googlechrome/lighthouse/pull/9729))
+
+## Tests
+
+* add Lighthouse CI dogfood script to travis ([#9677](https://github.com/googlechrome/lighthouse/pull/9677), [#9745](https://github.com/googlechrome/lighthouse/pull/9745))
+* report: update `utm_medium` check for web.dev links ([#9737](https://github.com/googlechrome/lighthouse/pull/9737))
+* smokehouse: add check for any `runWarnings` ([#9732](https://github.com/googlechrome/lighthouse/pull/9732))
+* attempt to download lantern test trace set a few times ([#9766](https://github.com/googlechrome/lighthouse/pull/9766))
+
+## Misc
+
+* devtools: remove version replacement for expectations ([#9702](https://github.com/googlechrome/lighthouse/pull/9702))
+* remove unnecessary return in Promise ([#9703](https://github.com/googlechrome/lighthouse/pull/9703))
+* assets: update logo ([#9694](https://github.com/googlechrome/lighthouse/pull/9694))
+
+[Full Changelog](https://github.com/googlechrome/lighthouse/compare/v5.4.0...v5.5.0)
+
  <a name="5.4.0"></a>
 # 5.4.0 (2019-09-18)
 
diff --git a/clients/extension/manifest.json b/clients/extension/manifest.json
index 177c706b3..b288d76d6 100644
--- a/clients/extension/manifest.json
+++ b/clients/extension/manifest.json
@@ -1,6 +1,6 @@
 {
   "name": "__MSG_appName__",
-  "version": "5.4.0",
+  "version": "5.5.0",
   "minimum_chrome_version": "72",
   "manifest_version": 2,
   "description": "__MSG_appDescription__",
diff --git a/docs/configuration.md b/docs/configuration.md
index 2419204e6..e49f3174c 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -15,10 +15,9 @@ module.exports = {
   settings: {
     onlyAudits: [
       'first-meaningful-paint',
-      'speed-index-metric',
-      'estimated-input-latency',
-      'first-interactive',
-      'consistently-interactive',
+      'speed-index',
+      'first-cpu-idle',
+      'interactive',
     ],
   },
 };
@@ -129,7 +128,7 @@ The audits property controls which audits to run and include with your Lighthous
 {
   audits: [
     'first-meaningful-paint',
-    'first-interactive',
+    'first-cpu-idle',
     'byte-efficiency/uses-optimized-images',
   ]
 }
@@ -151,8 +150,8 @@ The categories property controls how to score and organize the audit results in
       description: 'This category judges your performance',
       auditRefs: [
         {id: 'first-meaningful-paint', weight: 2, group: 'metrics'},
-        {id: 'first-interactive', weight: 3, group: 'metrics'},
-        {id: 'consistently-interactive', weight: 5, group: 'metrics'},
+        {id: 'first-cpu-idle', weight: 3, group: 'metrics'},
+        {id: 'interactive', weight: 5, group: 'metrics'},
       ],
     }
   }
diff --git a/docs/readme.md b/docs/readme.md
index a397dbd5a..1d379e616 100644
--- a/docs/readme.md
+++ b/docs/readme.md
@@ -92,10 +92,9 @@ In order to extend the Lighthouse configuration programmatically, you need to pa
   settings: {
     onlyAudits: [
       'first-meaningful-paint',
-      'speed-index-metric',
-      'estimated-input-latency',
-      'first-interactive',
-      'consistently-interactive',
+      'speed-index',
+      'first-cpu-idle',
+      'interactive',
     ],
   },
 }
diff --git a/docs/releasing.md b/docs/releasing.md
index 51f42e2c9..8c89f0d58 100644
--- a/docs/releasing.md
+++ b/docs/releasing.md
@@ -60,7 +60,7 @@ and that no new PRs should be merged until you are done.
 ```sh
 # Run the tests.
 bash ./lighthouse-core/scripts/release/test.sh
-# Change into the pristine folder.
+# Change into the newly-created pristine folder.
 cd ../lighthouse-pristine
 ```
 
@@ -85,7 +85,7 @@ yarn --cwd ~/chromium/src/third_party/blink/renderer/devtools test 'http/tests/d
 git diff
 
 # Verify that the Audits panel still works. Consider the new features that have been added.
-# If anything is wrong, stop releasing, investigate, and prioritize landing the PR.
+# If anything is wrong, stop releasing, investigate, land a fix and start over.
 
 # For bonus points, add some tests covering new features. Either a new test, or an extra
 # assertion in an existing test.
@@ -105,7 +105,7 @@ Confirm Lightrider integration will work:
 
 # Verify that Lightrider works properly, and is generating reports fully. Consider the new features that have been added.
 # Note: if the changes include proto changes make sure that the API has those new fields.
-# If anything is wrong, stop releasing, investigate, and prioritize landing the PR.
+# If anything is wrong, stop releasing, investigate, land a fix and start over.
 
 # For bonus points, add some tests covering new features. Either a new test, or an extra
 # assertion in an existing test.
@@ -114,10 +114,6 @@ Confirm Lightrider integration will work:
 Now that the integrations are confirmed to work, go back to `lighthouse` folder.
 
 ```sh
-# Run the tests again.
-# Note: you can skip this if you didn't need to land any changes.
-bash ./lighthouse-core/scripts/release/test.sh
-
 # Prepare the commit, replace x.x.x with the desired version
 bash ./lighthouse-core/scripts/release/prepare-commit.sh x.x.x
 
diff --git a/lighthouse-core/audits/seo/link-text.js b/lighthouse-core/audits/seo/link-text.js
index ddae4abca..0eac23289 100644
--- a/lighthouse-core/audits/seo/link-text.js
+++ b/lighthouse-core/audits/seo/link-text.js
@@ -53,6 +53,16 @@ const BLOCKLIST = new Set([
   'mais informações',
   'mais',
   'veja mais',
+  // Korean
+  '여기',
+  '여기를 클릭',
+  '클릭',
+  '링크',
+  '자세히',
+  '자세히 보기',
+  '계속',
+  '이동',
+  '전체 보기',
 ]);
 const i18n = require('../../lib/i18n/i18n.js');
 
diff --git a/lighthouse-core/gather/gatherers/dobetterweb/optimized-images.js b/lighthouse-core/gather/gatherers/dobetterweb/optimized-images.js
index 9f155f54f..1c81e0afd 100644
--- a/lighthouse-core/gather/gatherers/dobetterweb/optimized-images.js
+++ b/lighthouse-core/gather/gatherers/dobetterweb/optimized-images.js
@@ -10,6 +10,7 @@
   */
 'use strict';
 
+const log = require('lighthouse-logger');
 const Gatherer = require('../gatherer.js');
 const URL = require('../../../lib/url-shim.js');
 const NetworkRequest = require('../../../lib/network-request.js');
@@ -124,6 +125,8 @@ class OptimizedImages extends Gatherer {
         const image = {failed: false, ...stats, ...record};
         results.push(image);
       } catch (err) {
+        log.warn('optimized-images', err.message);
+
         // Track this with Sentry since these errors aren't surfaced anywhere else, but we don't
         // want to tank the entire run due to a single image.
         Sentry.captureException(err, {
diff --git a/lighthouse-core/gather/gatherers/link-elements.js b/lighthouse-core/gather/gatherers/link-elements.js
index 156dad46c..a6961ed8b 100644
--- a/lighthouse-core/gather/gatherers/link-elements.js
+++ b/lighthouse-core/gather/gatherers/link-elements.js
@@ -9,8 +9,9 @@ const Gatherer = require('./gatherer.js');
 const URL = require('../../lib/url-shim.js').URL;
 const NetworkAnalyzer = require('../../lib/dependency-graph/simulator/network-analyzer.js');
 const LinkHeader = require('http-link-header');
-const getElementsInDocumentString = require('../../lib/page-functions.js')
-  .getElementsInDocumentString; // eslint-disable-line max-len
+const {getElementsInDocumentString} = require('../../lib/page-functions.js');
+
+/* globals HTMLLinkElement */
 
 /**
  * @fileoverview
@@ -42,6 +43,36 @@ function getCrossoriginFromHeader(value) {
   return null;
 }
 
+/**
+ * @return {LH.Artifacts['LinkElements']}
+ */
+/* istanbul ignore next */
+function getLinkElementsInDOM() {
+  /** @type {Array<HTMLOrSVGElement>} */
+  // @ts-ignore - getElementsInDocument put into scope via stringification
+  const browserElements = getElementsInDocument('link'); // eslint-disable-line no-undef
+  /** @type {LH.Artifacts['LinkElements']} */
+  const linkElements = [];
+
+  for (const link of browserElements) {
+    // We're only interested in actual LinkElements, not `<link>` tagName elements inside SVGs.
+    // https://github.com/GoogleChrome/lighthouse/issues/9764
+    if (!(link instanceof HTMLLinkElement)) continue;
+
+    linkElements.push({
+      rel: link.rel,
+      href: link.href,
+      hrefRaw: link.href,
+      hreflang: link.hreflang,
+      as: link.as,
+      crossOrigin: link.crossOrigin,
+      source: link.closest('head') ? 'head' : 'body',
+    });
+  }
+
+  return linkElements;
+}
+
 class LinkElements extends Gatherer {
   /**
    * @param {LH.Gatherer.PassContext} passContext
@@ -52,18 +83,9 @@ class LinkElements extends Gatherer {
     // the values like access from JavaScript does.
     return passContext.driver.evaluateAsync(`(() => {
       ${getElementsInDocumentString};
+      ${getLinkElementsInDOM};
 
-      return getElementsInDocument('link').map(link => {
-        return {
-          rel: link.rel,
-          href: link.href,
-          hrefRaw: link.href,
-          hreflang: link.hreflang,
-          as: link.as,
-          crossOrigin: link.crossOrigin,
-          source: link.closest('head') ? 'head' : 'body',
-        };
-      });
+      return getLinkElementsInDOM();
     })()`, {useIsolation: true});
   }
 
diff --git a/lighthouse-core/lib/i18n/README.md b/lighthouse-core/lib/i18n/README.md
index 35c61af0a..8ec3779d9 100644
--- a/lighthouse-core/lib/i18n/README.md
+++ b/lighthouse-core/lib/i18n/README.md
@@ -1,6 +1,6 @@
 # Terminology
 
-* **CTC format**: The [Chrome extension & Chrome app i18n format](https://developer.chrome.com/extensions/i18n-messages). JSON with their specified model for declaring placeholders, examples, etc. Used as an interchange data format.
+* **CTC format**: The [Chrome extension & Chrome app i18n format](https://developer.chrome.com/extensions/i18n-messages) with some minor changes. JSON with their specified model for declaring placeholders, examples, etc. Used as an interchange data format.
 * **LHL syntax** (Lighthouse Localizable syntax): The ICU-friendly string syntax that is used to author `UIStrings` and is seen in the locale files in `i18n/locales/*.json`. Lighthouse has a custom syntax these strings combines many ICU message features along with some markdown.
 * **ICU**: ICU (International Components for Unicode) is a localization project and standard defined by the Unicode consortium. In general, we refer to "ICU" as the [ICU message formatting](http://userguide.icu-project.org/formatparse/messages) syntax.
 
@@ -195,13 +195,12 @@ CTC is a name that is distinct and identifies this as the Chrome translation for
 
 ### Parts of a CTC message
 
-(From the Chrome Docs)
-
 ```json
 {
   "name": {
     "message": "Message text, with optional placeholders.",
     "description": "Translator-aimed description of the message.",
+    "meaning": "Description given when a message is duplicated, in order to give context to the message. Lighthouse uses a copy of the description for this.",
     "placeholders": {
       "placeholder_name": {
         "content": "A string to be placed within the message.",
diff --git a/lighthouse-core/lib/i18n/locales/ca.json b/lighthouse-core/lib/i18n/locales/ca.json
index da2b75cbe..1d374dc80 100644
--- a/lighthouse-core/lib/i18n/locales/ca.json
+++ b/lighthouse-core/lib/i18n/locales/ca.json
@@ -918,7 +918,7 @@
     "message": "El {decimalProportion, number, extendedPercent} del text és llegible"
   },
   "lighthouse-core/audits/seo/font-size.js | explanationViewport": {
-    "message": "El text és il·legible perquè no hi ha cap metaetiqueta de finestra gràfica optimitzada per a pantalles de mòbil."
+    "message": "El text és il·legible perquè no hi ha cap metaetiqueta de finestra gràfica optimitzada per a pantalles de dispositius mòbils."
   },
   "lighthouse-core/audits/seo/font-size.js | explanationWithDisclaimer": {
     "message": "El {decimalProportion, number, extendedPercent} del text és massa petit (d'acord amb una mostra del {decimalProportionVisited, number, extendedPercent})."
@@ -999,7 +999,7 @@
     "message": "Si el format del fitxer robots.txt no és correcte, és possible que els rastrejadors no puguin entendre com vols que rastregin o indexin el lloc web. [Obtén més informació](https://web.dev/robots-txt)."
   },
   "lighthouse-core/audits/seo/robots-txt.js | displayValueHttpBadCode": {
-    "message": "La sol·licitud del fitxer robots.txt ha tornat l'estat HTTP: {statusCode}"
+    "message": "La sol·licitud del fitxer robots.txt ha tornat l'estat HTTP següent: {statusCode}"
   },
   "lighthouse-core/audits/seo/robots-txt.js | displayValueValidationError": {
     "message": "{itemCount,plural, =1{S'ha trobat 1 error}other{S'han trobat # errors}}"
diff --git a/lighthouse-core/lib/i18n/locales/da.json b/lighthouse-core/lib/i18n/locales/da.json
index f015c0c84..a053e6cd8 100644
--- a/lighthouse-core/lib/i18n/locales/da.json
+++ b/lighthouse-core/lib/i18n/locales/da.json
@@ -759,7 +759,7 @@
     "message": "Formindsker primært trådarbejde"
   },
   "lighthouse-core/audits/manual/pwa-cross-browser.js | description": {
-    "message": "Websites bør fungere på alle de mest populære browsere, så de når ud til flest mulige brugere. [Få flere oplysninger](https://developers.google.com/web/progressive-web-apps/checklist#site-works-cross-browser)."
+    "message": "Websites bør fungere på alle populære browsere, så de når ud til flest mulige brugere. [Få flere oplysninger](https://developers.google.com/web/progressive-web-apps/checklist#site-works-cross-browser)."
   },
   "lighthouse-core/audits/manual/pwa-cross-browser.js | title": {
     "message": "Websitet fungerer i forskellige browsere"
diff --git a/lighthouse-core/lib/i18n/locales/de.json b/lighthouse-core/lib/i18n/locales/de.json
index 51fb43eb0..2493fd35b 100644
--- a/lighthouse-core/lib/i18n/locales/de.json
+++ b/lighthouse-core/lib/i18n/locales/de.json
@@ -702,10 +702,10 @@
     "message": "Zeigt Bilder mit einem korrekten Seitenverhältnis an"
   },
   "lighthouse-core/audits/image-aspect-ratio.js | warningCompute": {
-    "message": "Ungültige Informationen zur Bildgröße {url}"
+    "message": "Ungültige Informationen zur Bildgröße: {url}"
   },
   "lighthouse-core/audits/installable-manifest.js | description": {
-    "message": "Browser können Nutzer direkt dazu auffordern, Ihre Web-App zum Startbildschirm hinzuzufügen. Das kann zu mehr Interaktionen führen. [Weitere Informationen.](https://developers.google.com/web/tools/lighthouse/audits/install-prompt)"
+    "message": "Browser können Nutzer direkt dazu auffordern, Ihre Web-App zum Startbildschirm hinzuzufügen. Das kann zu mehr Engagement führen. [Weitere Informationen.](https://developers.google.com/web/tools/lighthouse/audits/install-prompt)"
   },
   "lighthouse-core/audits/installable-manifest.js | failureTitle": {
     "message": "Das Manifest der Web-App erfüllt die Anforderungen an die Installierbarkeit nicht"
@@ -1071,7 +1071,7 @@
     "message": "Legt keine Designfarbe für die Adressleiste fest."
   },
   "lighthouse-core/audits/themed-omnibox.js | title": {
-    "message": "Legt die Designfarbe der Adressleiste fest."
+    "message": "Legt eine Designfarbe für die Adressleiste fest."
   },
   "lighthouse-core/audits/third-party-summary.js | columnBlockingTime": {
     "message": "Dauer der Blockierung des Hauptthreads"
diff --git a/lighthouse-core/lib/i18n/locales/es-419.json b/lighthouse-core/lib/i18n/locales/es-419.json
index 74d081547..b64b49567 100644
--- a/lighthouse-core/lib/i18n/locales/es-419.json
+++ b/lighthouse-core/lib/i18n/locales/es-419.json
@@ -318,7 +318,7 @@
     "message": "Los elementos `<video>` contienen un elemento `<track>` con `[kind=\"description\"]`"
   },
   "lighthouse-core/audits/apple-touch-icon.js | description": {
-    "message": "Para que el aspecto en iOS sea perfecto cuando los usuarios agreguen una app web progresiva a la pantalla principal, define un atributo `apple-touch-icon`. El atributo debe apuntar a un archivo PNG cuadrado de 192 px (o 180 px) no transparente. [Obtén más información](https://developers.google.com/web/fundamentals/design-and-ux/browser-customization/)."
+    "message": "Para que el aspecto en iOS sea perfecto cuando los usuarios agreguen una app web progresiva a la pantalla principal, define un atributo `apple-touch-icon`. El atributo debe apuntar a un archivo PNG cuadrado de 192 px (o 180 px) que no sea transparente. [Obtén más información](https://developers.google.com/web/fundamentals/design-and-ux/browser-customization/)."
   },
   "lighthouse-core/audits/apple-touch-icon.js | failureTitle": {
     "message": "No proporciona un ícono `apple-touch-icon` válido"
@@ -441,16 +441,16 @@
     "message": "Publica imágenes con formatos de próxima generación"
   },
   "lighthouse-core/audits/content-width.js | description": {
-    "message": "Si el ancho del contenido de tu app no coincide con el de la vista del puerto, es posible que la app no esté optimizada para pantallas de dispositivos móviles. [Obtén más información](https://developers.google.com/web/tools/lighthouse/audits/content-sized-correctly-for-viewport)."
+    "message": "Si el ancho del contenido de tu app no coincide con el del viewport, es posible que la app no esté optimizada para pantallas de dispositivos móviles. [Obtén más información](https://developers.google.com/web/tools/lighthouse/audits/content-sized-correctly-for-viewport)."
   },
   "lighthouse-core/audits/content-width.js | explanation": {
-    "message": "El tamaño de la vista del puerto de {innerWidth} px no coincide con el tamaño de la ventana de {outerWidth} px."
+    "message": "El tamaño de viewport de {innerWidth} px no coincide con el tamaño de ventana de {outerWidth} px."
   },
   "lighthouse-core/audits/content-width.js | failureTitle": {
-    "message": "El contenido no tiene el tamaño correcto para la vista del puerto"
+    "message": "El contenido no tiene el tamaño correcto para el viewport"
   },
   "lighthouse-core/audits/content-width.js | title": {
-    "message": "El contenido tiene el tamaño correcto para la vista del puerto"
+    "message": "El contenido tiene el tamaño correcto para el viewport"
   },
   "lighthouse-core/audits/critical-request-chains.js | description": {
     "message": "Las cadenas de solicitudes críticas que se muestran a continuación indican qué recursos son de alta prioridad en la carga. Te recomendamos que reduzcas la longitud de las cadenas, disminuyas el tamaño de los recursos para la descarga o postergues la descarga de recursos innecesarios para mejorar la carga de la página. [Obtén más información](https://developers.google.com/web/tools/lighthouse/audits/critical-request-chains)."
@@ -666,7 +666,7 @@
     "message": "Descripción"
   },
   "lighthouse-core/audits/errors-in-console.js | description": {
-    "message": "Los errores registrados en la consola indican la existencia de problemas no resueltos. Es posible que se deban a fallos en solicitudes de red y otros problemas del navegador. [Obtén más información](https://web.dev/errors-in-console)."
+    "message": "Los errores registrados en la consola indican la existencia de problemas no resueltos. Es posible que se deban a problemas con solicitudes de red y otros relativos al navegador. [Obtén más información](https://web.dev/errors-in-console)."
   },
   "lighthouse-core/audits/errors-in-console.js | failureTitle": {
     "message": "Se registraron errores del navegador en la consola"
@@ -705,13 +705,13 @@
     "message": "La información sobre el tamaño de la imagen no es válida {url}"
   },
   "lighthouse-core/audits/installable-manifest.js | description": {
-    "message": "Los navegadores pueden solicitarles a los usuarios de forma proactiva que agreguen tu app a la pantalla principal, lo que puede conllevar un mayor compromiso. [Obtén más información](https://developers.google.com/web/tools/lighthouse/audits/install-prompt)."
+    "message": "Los navegadores pueden solicitar a los usuarios proactivamente que agreguen tu app a la pantalla principal, lo que es posible que genere un mayor compromiso. [Obtén más información](https://developers.google.com/web/tools/lighthouse/audits/install-prompt)."
   },
   "lighthouse-core/audits/installable-manifest.js | failureTitle": {
-    "message": "El manifiesto de la aplicación web no cumple los requisitos de instalación"
+    "message": "El manifiesto de la aplicación web no cumple los requisitos de aptitud para la instalación"
   },
   "lighthouse-core/audits/installable-manifest.js | title": {
-    "message": "El manifiesto de la aplicación web cumple los requisitos de instalación"
+    "message": "El manifiesto de la aplicación web cumple los requisitos de aptitud para la instalación"
   },
   "lighthouse-core/audits/is-on-https.js | columnInsecureURL": {
     "message": "URL no segura"
@@ -738,7 +738,7 @@
     "message": "Interactiva en una red móvil simulada a los {timeInMs, number, seconds} s"
   },
   "lighthouse-core/audits/load-fast-enough-for-pwa.js | explanationLoadSlow": {
-    "message": "Tu página es demasiado lenta y no es interactiva en menos de 10 segundos. Para obtener información sobre cómo mejorarla, accede a la sección \"Rendimiento\" para ver las oportunidades y el diagnóstico."
+    "message": "Tu página tarda mucho en cargarse y no es interactiva en menos de 10 segundos. Para obtener información sobre cómo mejorarla, accede a la sección Rendimiento, donde podrás consultar las oportunidades disponibles y el diagnóstico correspondiente."
   },
   "lighthouse-core/audits/load-fast-enough-for-pwa.js | failureTitle": {
     "message": "La página no se carga suficientemente rápido en las redes móviles"
@@ -759,7 +759,7 @@
     "message": "Minimiza el trabajo del hilo principal"
   },
   "lighthouse-core/audits/manual/pwa-cross-browser.js | description": {
-    "message": "Para alcanzar la mayor cantidad de usuarios, los sitios deben poder funcionar en todos los navegadores principales. [Obtén más información](https://developers.google.com/web/progressive-web-apps/checklist#site-works-cross-browser)."
+    "message": "Para alcanzar la mayor cantidad de usuarios, los sitios tienen que funcionar en todos los navegadores principales. [Obtén más información](https://developers.google.com/web/progressive-web-apps/checklist#site-works-cross-browser)."
   },
   "lighthouse-core/audits/manual/pwa-cross-browser.js | title": {
     "message": "El sitio funciona en diferentes navegadores"
@@ -771,7 +771,7 @@
     "message": "Cada página tiene una URL"
   },
   "lighthouse-core/audits/manual/pwa-page-transitions.js | description": {
-    "message": "Una clave del rendimiento percibido es la agilidad de las transiciones cuando presionas diferentes teclas, incluso con conexiones de red lentas. [Obtén más información](https://developers.google.com/web/progressive-web-apps/checklist#page-transitions-dont-feel-like-they-block-on-the-network)."
+    "message": "Una clave del rendimiento percibido es la agilidad de las transiciones cuando presionas en diferentes lugares, incluso con conexiones de red lentas. [Obtén más información](https://developers.google.com/web/progressive-web-apps/checklist#page-transitions-dont-feel-like-they-block-on-the-network)."
   },
   "lighthouse-core/audits/manual/pwa-page-transitions.js | title": {
     "message": "No parece que se bloqueen las transiciones de la página en la red"
@@ -837,7 +837,7 @@
     "message": "Latencias de backend del servidor"
   },
   "lighthouse-core/audits/offline-start-url.js | description": {
-    "message": "Un service worker permite que tu aplicación web sea confiable en condiciones de red impredecibles. [Obtén más información](https://developers.google.com/web/tools/lighthouse/audits/http-200-when-offline)."
+    "message": "Usar un service worker permite que tu aplicación web sea confiable en condiciones de red impredecibles. [Obtén más información](https://developers.google.com/web/tools/lighthouse/audits/http-200-when-offline)."
   },
   "lighthouse-core/audits/offline-start-url.js | failureTitle": {
     "message": "`start_url` no responde con un código de estado HTTP 200 cuando no hay conexión"
@@ -846,7 +846,7 @@
     "message": "`start_url` responde con un código de estado HTTP 200 cuando no hay conexión"
   },
   "lighthouse-core/audits/offline-start-url.js | warningCantStart": {
-    "message": "Lighthouse no pudo leer el atributo `start_url` del manifiesto. Como resultado, se consideró que el atributo `start_url` fuera la URL del documento. Mensaje de error: \"{manifestWarning}\"."
+    "message": "Lighthouse no pudo leer el atributo `start_url` del manifiesto. Por lo tanto, se tomó como `start_url` la URL del documento. Mensaje de error: \"{manifestWarning}\"."
   },
   "lighthouse-core/audits/performance-budget.js | columnOverBudget": {
     "message": "Superior a la estimación"
@@ -861,7 +861,7 @@
     "message": "Estimación de rendimiento"
   },
   "lighthouse-core/audits/redirects-http.js | description": {
-    "message": "Si ya configuraste el protocolo HTTPS, asegúrate de redireccionar todo el tráfico de HTTP a HTTPS para que todos los usuarios aprovechen las características de protección de la Web. [Obtén más información](https://developers.google.com/web/tools/lighthouse/audits/http-redirects-to-https)."
+    "message": "Si ya configuraste el protocolo HTTPS, asegúrate de redireccionar el tráfico de HTTP a HTTPS a fin de habilitar las características de protección de la Web para todos los usuarios. [Obtén más información](https://developers.google.com/web/tools/lighthouse/audits/http-redirects-to-https)."
   },
   "lighthouse-core/audits/redirects-http.js | failureTitle": {
     "message": "No redirecciona el tráfico HTTP a HTTPS"
@@ -1035,28 +1035,28 @@
     "message": "El tamaño de los elementos táctiles es el adecuado"
   },
   "lighthouse-core/audits/service-worker.js | description": {
-    "message": "El service worker es la tecnología que te permite usar las funciones de las apps web progresivas, como el modo sin conexión, agregarlas a la pantalla principal y las notificaciones push. [Obtén más información](https://developers.google.com/web/tools/lighthouse/audits/registered-service-worker)."
+    "message": "El service worker es la tecnología que permite que tu app use varias funciones de las apps web progresivas, como el modo sin conexión, el agregado a la pantalla principal y las notificaciones push. [Obtén más información](https://developers.google.com/web/tools/lighthouse/audits/registered-service-worker)."
   },
   "lighthouse-core/audits/service-worker.js | explanationBadManifest": {
-    "message": "Un service worker controla esta página, pero no se encontró ningún atributo `start_url` porque el archivo de manifiesto no es un JSON válido"
+    "message": "Un service worker controla esta página, pero no se encontró ningún atributo `start_url` porque no se pudo analizar el archivo de manifiesto como un JSON válido"
   },
   "lighthouse-core/audits/service-worker.js | explanationBadStartUrl": {
-    "message": "Un service worker controla esta página, pero el atributo `start_url` ({startUrl}) está fuera del rango del service worker ({scopeUrl})"
+    "message": "Un service worker controla esta página, pero el atributo `start_url` ({startUrl}) está fuera del alcance del service worker ({scopeUrl})"
   },
   "lighthouse-core/audits/service-worker.js | explanationNoManifest": {
-    "message": "Un service worker controla esta página, pero no se encontró el atributo `start_url` porque no se recuperó ningún manifiesto."
+    "message": "Un service worker controla esta página, pero no se encontró el atributo `start_url` porque no se obtuvo ningún manifiesto."
   },
   "lighthouse-core/audits/service-worker.js | explanationOutOfScope": {
-    "message": "Este origen tiene al menos un service worker, pero la página ({pageUrl}) no está dentro del rango."
+    "message": "Este origen tiene al menos un service worker, pero la página ({pageUrl}) no está dentro del alcance."
   },
   "lighthouse-core/audits/service-worker.js | failureTitle": {
     "message": "No registra un service worker que controle la página y `start_url`"
   },
   "lighthouse-core/audits/service-worker.js | title": {
-    "message": "Registra a un service worker que controle la página y `start_url`"
+    "message": "Registra un service worker que controle la página y `start_url`"
   },
   "lighthouse-core/audits/splash-screen.js | description": {
-    "message": "Una pantalla de presentación personalizada asegura que la experiencia de los usuarios sea de calidad cuando ejecuten tu app desde sus pantallas principales. [Obtén más información](https://developers.google.com/web/tools/lighthouse/audits/custom-splash-screen)."
+    "message": "El uso de una pantalla de presentación con un tema asegura que los usuarios tengan una experiencia de calidad al ejecutar tu app desde sus pantallas principales. [Obtén más información](https://developers.google.com/web/tools/lighthouse/audits/custom-splash-screen)."
   },
   "lighthouse-core/audits/splash-screen.js | failureTitle": {
     "message": "No se configuró para una pantalla de presentación personalizada"
@@ -1065,13 +1065,13 @@
     "message": "Se configuró para una pantalla de presentación personalizada"
   },
   "lighthouse-core/audits/themed-omnibox.js | description": {
-    "message": "El color de la barra de direcciones del navegador puede adaptarse a tu sitio web. [Obtén más información](https://developers.google.com/web/tools/lighthouse/audits/address-bar)."
+    "message": "Se puede aplicar un tema a la barra de direcciones del navegador para que combine con tu sitio web. [Obtén más información](https://developers.google.com/web/tools/lighthouse/audits/address-bar)."
   },
   "lighthouse-core/audits/themed-omnibox.js | failureTitle": {
-    "message": "No establece el color de un tema para la barra de direcciones."
+    "message": "No establece un color de tema para la barra de direcciones."
   },
   "lighthouse-core/audits/themed-omnibox.js | title": {
-    "message": "Establece el color de un tema para la barra de direcciones."
+    "message": "Establece un color de tema para la barra de direcciones."
   },
   "lighthouse-core/audits/third-party-summary.js | columnBlockingTime": {
     "message": "Tiempo de bloqueo del subproceso principal"
@@ -1152,7 +1152,7 @@
     "message": "Tiene una etiqueta `<meta name=\"viewport\">` con `width` o `initial-scale`"
   },
   "lighthouse-core/audits/without-javascript.js | description": {
-    "message": "Tu app debe mostrar algún contenido cuando JavaScript esté inhabilitado, aunque solo sea un aviso para informar al usuario de que es necesario activar JavaScript para usar la app. [Obtén más información](https://developers.google.com/web/tools/lighthouse/audits/no-js)."
+    "message": "Tu app debe mostrar algún contenido cuando JavaScript está inhabilitado, aunque solo sea un aviso para informar al usuario que se necesita JavaScript para usar la app. [Obtén más información](https://developers.google.com/web/tools/lighthouse/audits/no-js)."
   },
   "lighthouse-core/audits/without-javascript.js | explanation": {
     "message": "El cuerpo de la página debe renderizar parte del contenido aunque sus secuencias de comandos no estén disponibles."
@@ -1275,7 +1275,7 @@
     "message": "Estas comprobaciones se centran en diferentes aspectos de las apps web progresivas. [Obtén más información](https://developers.google.com/web/progressive-web-apps/checklist)."
   },
   "lighthouse-core/config/default-config.js | pwaCategoryManualDescription": {
-    "message": "Estas comprobaciones son necesarias según el modelo de referencia [Lista de tareas para AWP](https://developers.google.com/web/progressive-web-apps/checklist), pero Lighthouse no las verifica automáticamente. Es importante que las verifiques a mano (aunque no afectan a la puntuación)."
+    "message": "Estas comprobaciones son necesarias según el modelo de referencia [Lista de tareas para AWP](https://developers.google.com/web/progressive-web-apps/checklist), pero Lighthouse no las realiza automáticamente. Es importante que las verifiques a mano (aunque no afectan a la puntuación)."
   },
   "lighthouse-core/config/default-config.js | pwaCategoryTitle": {
     "message": "App web progresiva"
diff --git a/lighthouse-core/lib/i18n/locales/es.json b/lighthouse-core/lib/i18n/locales/es.json
index aa0d90d58..4e29c3129 100644
--- a/lighthouse-core/lib/i18n/locales/es.json
+++ b/lighthouse-core/lib/i18n/locales/es.json
@@ -861,7 +861,7 @@
     "message": "Límites de rendimiento"
   },
   "lighthouse-core/audits/redirects-http.js | description": {
-    "message": "Si ya has configurado HTTPS, asegúrate de redireccionar todo el tráfico HTTP a HTTPS para habilitar funciones de seguridad web para todos los usuarios. [Más información](https://developers.google.com/web/tools/lighthouse/audits/http-redirects-to-https)"
+    "message": "Si ya has configurado HTTPS, asegúrate de redirigir todo el tráfico HTTP a HTTPS para habilitar funciones de seguridad web para todos los usuarios. [Más información](https://developers.google.com/web/tools/lighthouse/audits/http-redirects-to-https)"
   },
   "lighthouse-core/audits/redirects-http.js | failureTitle": {
     "message": "No redirige el tráfico HTTP a HTTPS"
diff --git a/lighthouse-core/lib/i18n/locales/fil.json b/lighthouse-core/lib/i18n/locales/fil.json
index cd2f16a2d..2fd7259da 100644
--- a/lighthouse-core/lib/i18n/locales/fil.json
+++ b/lighthouse-core/lib/i18n/locales/fil.json
@@ -318,7 +318,7 @@
     "message": "Naglalaman ng element na `<track>` na may `[kind=\"description\"]` ang mga element na `<video>`"
   },
   "lighthouse-core/audits/apple-touch-icon.js | description": {
-    "message": "Para sa magandang hitsura sa iOS kapag nagdagdag ang mga user ng progressive web app sa home screen, tumukoy ng isang `apple-touch-icon`. Dapat itong nakadirekta sa isang hindi transparent na kuwadradong 192px (o 180px) PNG. [Matuto Pa](https://developers.google.com/web/fundamentals/design-and-ux/browser-customization/)."
+    "message": "Para sa magandang hitsura sa iOS kapag nagdagdag ang mga user ng progressive web app sa home screen, tumukoy ng `apple-touch-icon`. Dapat itong nakadirekta sa isang hindi transparent na kuwadradong 192px (o 180px) PNG. [Matuto Pa](https://developers.google.com/web/fundamentals/design-and-ux/browser-customization/)."
   },
   "lighthouse-core/audits/apple-touch-icon.js | failureTitle": {
     "message": "Hindi nagbibigay ng valid na `apple-touch-icon`"
@@ -705,7 +705,7 @@
     "message": "Invalid ang laki ng larawan ng impormasyon {url}"
   },
   "lighthouse-core/audits/installable-manifest.js | description": {
-    "message": "Puwedeng proactive na i-prompt ng mga browser ang mga user para idagdag ang iyong app sa kanilang homescreen, na maaaring magresulta sa mas mataas na pakikipag-ugnayan. [Matuto pa](https://developers.google.com/web/tools/lighthouse/audits/install-prompt)."
+    "message": "Puwedeng proactive na i-prompt ng mga browser ang mga user na idagdag ang iyong app sa kanilang homescreen, na puwedeng magresulta sa mas maraming pakikipag-ugnayan. [Matuto pa](https://developers.google.com/web/tools/lighthouse/audits/install-prompt)."
   },
   "lighthouse-core/audits/installable-manifest.js | failureTitle": {
     "message": "Hindi natutugunan ng manifest ng web app ang mga kinakailangan sa pag-install"
@@ -738,7 +738,7 @@
     "message": "Interactive sa naka-simulate na mobile network sa loob ng {timeInMs, number, seconds} s"
   },
   "lighthouse-core/audits/load-fast-enough-for-pwa.js | explanationLoadSlow": {
-    "message": "Masyadong mabagal mag-load ang iyong page at hindi interactive sa loob ng 10 segundo. Tingnan ang mga pagkakataon at diagnostic sa seksyong \"Performance\" para matutunan kung paano magpahusay."
+    "message": "Masyadong mabagal mag-load ang iyong page at hindi ito interactive sa loob ng 10 segundo. Tingnan ang mga pagkakataon at diagnostic sa seksyong \"Performance\" para malaman kung paano magpahusay."
   },
   "lighthouse-core/audits/load-fast-enough-for-pwa.js | failureTitle": {
     "message": "Hindi sapat ang bilis ng pag-load ng page sa mga mobile network"
@@ -759,19 +759,19 @@
     "message": "Binabawasan ang gawain sa pangunahing thread"
   },
   "lighthouse-core/audits/manual/pwa-cross-browser.js | description": {
-    "message": "Para maabot ang pinakamaraming bilang nguser, dapat gumana ang mga site sa bawat pangunahing browser. [Matuto pa](https://developers.google.com/web/progressive-web-apps/checklist#site-works-cross-browser)."
+    "message": "Para maabot ang pinakamaraming user, dapat gumana ang mga site sa bawat pangunahing browser. [Matuto pa](https://developers.google.com/web/progressive-web-apps/checklist#site-works-cross-browser)."
   },
   "lighthouse-core/audits/manual/pwa-cross-browser.js | title": {
-    "message": "Gumagana ang site sa cross-browser"
+    "message": "Gumagana ang site sa iba't ibang browser"
   },
   "lighthouse-core/audits/manual/pwa-each-page-has-url.js | description": {
-    "message": "Tiyaking nali-link nang malalim ang mga indibidwal na page sa pamamagitan ng URL at natatangi ang mga URL para sa pagbabahagi sa social media. [Matuto pa](https://developers.google.com/web/progressive-web-apps/checklist#each-page-has-a-url)."
+    "message": "Tiyaking puwedeng i-deep link ang mga indibidwal na page sa pamamagitan ng URL at natatangi ang mga URL para sa pagbabahagi sa social media. [Matuto pa](https://developers.google.com/web/progressive-web-apps/checklist#each-page-has-a-url)."
   },
   "lighthouse-core/audits/manual/pwa-each-page-has-url.js | title": {
     "message": "May URL ang bawat page"
   },
   "lighthouse-core/audits/manual/pwa-page-transitions.js | description": {
-    "message": "Mabilis dapat ang dating ng mga transition habang nagta-tap ka sa paligid, kahit nasa mabagal na network, isang susi sa kapansin-pansing performance. [Matuto pa](https://developers.google.com/web/progressive-web-apps/checklist#page-transitions-dont-feel-like-they-block-on-the-network)."
+    "message": "Mabilis dapat ang mga transition habang nagta-tap ka, kahit sa mabagal na network, na isang susi sa nakikitang performance. [Matuto pa](https://developers.google.com/web/progressive-web-apps/checklist#page-transitions-dont-feel-like-they-block-on-the-network)."
   },
   "lighthouse-core/audits/manual/pwa-page-transitions.js | title": {
     "message": "Mukhang hindi nagba-block sa network ang mga transition ng page"
@@ -846,7 +846,7 @@
     "message": "Tumutugon ang `start_url` gamit ang 200 kapag offline"
   },
   "lighthouse-core/audits/offline-start-url.js | warningCantStart": {
-    "message": "Hindi mabasa ng Lighthouse ang `start_url` na galing sa manifest. Dahil dito, ipinagpapalagay ang `start_url` bilang URL ng dokumento. Mensahe ng error: '{manifestWarning}'."
+    "message": "Hindi mabasa ng Lighthouse ang `start_url` na galing sa manifest. Dahil dito, ipinagpapalagay na `start_url` ang URL ng dokumento. Mensahe ng error: '{manifestWarning}.'"
   },
   "lighthouse-core/audits/performance-budget.js | columnOverBudget": {
     "message": "Lampas sa Badyet"
@@ -861,7 +861,7 @@
     "message": "Badyet sa performance"
   },
   "lighthouse-core/audits/redirects-http.js | description": {
-    "message": "Kung na-set up mo na ang HTTPS, tiyaking iyong na-redirect sa HTTPS ang lahat ng trapiko sa HTTP para ma-enable ang mga ligtas na feature sa web para sa lahat ng user mo. [Matuto pa](https://developers.google.com/web/tools/lighthouse/audits/http-redirects-to-https)."
+    "message": "Kung na-set up mo na ang HTTPS, tiyaking ire-redirect mo sa HTTPS ang lahat ng trapiko sa HTTP para ma-enable ang mga ligtas na feature sa web para sa lahat ng iyong user. [Matuto pa](https://developers.google.com/web/tools/lighthouse/audits/http-redirects-to-https)."
   },
   "lighthouse-core/audits/redirects-http.js | failureTitle": {
     "message": "Hindi nire-redirect sa HTTPS ang trapiko sa HTTP"
@@ -1035,19 +1035,19 @@
     "message": "Angkop ang laki ng mga target ng pag-tap"
   },
   "lighthouse-core/audits/service-worker.js | description": {
-    "message": "Ang service worker ay ang teknolohiyang nag-e-enable sa iyong app na gumamit ng maraming feature ng Progressive Web App, gaya ng offline, pagdaragdag sa homescreen, at mga push notification. [Matuto pa](https://developers.google.com/web/tools/lighthouse/audits/registered-service-worker)."
+    "message": "Ang service worker ay ang teknolohiyang nagbibigay-daan sa iyong app na gumamit ng maraming feature ng Progressive Web App, gaya ng offline, pagdaragdag sa homescreen, at mga push notification. [Matuto pa](https://developers.google.com/web/tools/lighthouse/audits/registered-service-worker)."
   },
   "lighthouse-core/audits/service-worker.js | explanationBadManifest": {
-    "message": "Kinokontrol ng isang service worker ang page na ito, gayunpaman, walang nakitang `start_url` dahil hindi na-parse ang manifest bilang valid na JSON"
+    "message": "Kinokontrol ng service worker ang page na ito, gayunpaman, walang nakitang `start_url` dahil hindi na-parse ang manifest bilang valid na JSON"
   },
   "lighthouse-core/audits/service-worker.js | explanationBadStartUrl": {
-    "message": "Kinokontrol ng isang service worker ang page na ito, gayunpaman, wala ang `start_url` ({startUrl}) sa saklaw ng service worker ({scopeUrl})"
+    "message": "Kinokontrol ng service worker ang page na ito, gayunpaman, wala ang `start_url` ({startUrl}) sa saklaw ng service worker ({scopeUrl})"
   },
   "lighthouse-core/audits/service-worker.js | explanationNoManifest": {
-    "message": "Kinokontrol ng isang service worker ang page na ito, gayunpaman, walang nakitang `start_url` dahil walang nakuhang manifest."
+    "message": "Kinokontrol ng service worker ang page na ito, gayunpaman, walang nakitang `start_url` dahil walang nakuhang manifest."
   },
   "lighthouse-core/audits/service-worker.js | explanationOutOfScope": {
-    "message": "May isa o higit pang service worker ang origin na ito, gayunpaman, wala sa saklaw ang page ({pageUrl})."
+    "message": "May isa o higit pang service worker ang pinagmulang ito, gayunpaman, wala sa saklaw ang page ({pageUrl})."
   },
   "lighthouse-core/audits/service-worker.js | failureTitle": {
     "message": "Hindi nagrerehistro ng service worker na kumokontrol sa page at `start_url`"
@@ -1056,7 +1056,7 @@
     "message": "Nagrerehistro ng service worker na kumokontrol sa page at `start_url`"
   },
   "lighthouse-core/audits/splash-screen.js | description": {
-    "message": "Tinititiyak ng isang splash screen na may tema ang mataas na kalidad na karanasan kapag inilunsad ng mga user ang iyong app sa kanilang mga homescreen. [Matuto pa](https://developers.google.com/web/tools/lighthouse/audits/custom-splash-screen)."
+    "message": "Tinitiyak ng splash screen na may tema na magkakaroon ng karanasang may mataas na kalidad kapag inilunsad ng mga user ang iyong app sa kanilang mga homescreen. [Matuto pa](https://developers.google.com/web/tools/lighthouse/audits/custom-splash-screen)."
   },
   "lighthouse-core/audits/splash-screen.js | failureTitle": {
     "message": "Hindi naka-configure para sa custom na splash screen"
@@ -1083,10 +1083,10 @@
     "message": "Puwedeng lubos na makaapekto ang code ng third party sa performance ng pag-load. Limitahan ang bilang ng paulit-ulit na mga third-party na provider at subukang i-load ang code ng third party pagkatapos ng pangunahing pag-load ng iyong page. [Matuto pa](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/loading-third-party-javascript/)."
   },
   "lighthouse-core/audits/third-party-summary.js | displayValue": {
-    "message": "Na-block ng third-party na code ang pangunahing thread sa loob ng {timeInMs, number, milliseconds} ms"
+    "message": "Na-block ng code ng third party ang pangunahing thread sa loob ng {timeInMs, number, milliseconds} ms"
   },
   "lighthouse-core/audits/third-party-summary.js | failureTitle": {
-    "message": "Bawasan ang epekto ng third-party na code"
+    "message": "Bawasan ang epekto ng code ng third party"
   },
   "lighthouse-core/audits/third-party-summary.js | title": {
     "message": "Paggamit ng Third Party"
@@ -1152,7 +1152,7 @@
     "message": "May tag na `<meta name=\"viewport\">` na may `width` o `initial-scale`"
   },
   "lighthouse-core/audits/without-javascript.js | description": {
-    "message": "Dapat magpakita ng ilang content ang iyong app kapag naka-disable ang JavaScript, kahit isang babala lang ito sa user na kinakailangan ang Javascript para magamit ang app. [Matuto pa](https://developers.google.com/web/tools/lighthouse/audits/no-js)."
+    "message": "Dapat magpakita ng ilang content ang iyong app kapag naka-disable ang JavaScript, kahit isang babala lang sa user na kinakailangan ang Javascript para magamit ang app. [Matuto pa](https://developers.google.com/web/tools/lighthouse/audits/no-js)."
   },
   "lighthouse-core/audits/without-javascript.js | explanation": {
     "message": "Dapat mag-render ng ilang content ang nilalaman ng page kung hindi available ang mga script nito."
@@ -1164,7 +1164,7 @@
     "message": "Naglalaman ng ilang content kapag hindi available ang JavaScript"
   },
   "lighthouse-core/audits/works-offline.js | description": {
-    "message": "Kung bumubuo ka ng Progressive Web App, pag-isipang gumamit ng isang service worker para puwedeng gumana ang iyong app offline. [Matuto pa](https://developers.google.com/web/tools/lighthouse/audits/http-200-when-offline)."
+    "message": "Kung bumubuo ka ng Progressive Web App, pag-isipang gumamit ng service worker para gumana ang iyong app offline. [Matuto pa](https://developers.google.com/web/tools/lighthouse/audits/http-200-when-offline)."
   },
   "lighthouse-core/audits/works-offline.js | failureTitle": {
     "message": "Hindi tumutugon ang kasalukuyang page gamit ang 200 kapag offline"
@@ -1275,7 +1275,7 @@
     "message": "Vina-validate ng mga pagsusuring ito ang mga aspeto ng isang Progressive Web App. [Matuto pa](https://developers.google.com/web/progressive-web-apps/checklist)."
   },
   "lighthouse-core/config/default-config.js | pwaCategoryManualDescription": {
-    "message": "Kinakailangan ang mga pagsusuring ito ng baseline na [Checklist ng PWA ](https://developers.google.com/web/progressive-web-apps/checklist) pero hindi awtomatikong sinusuri ng Lighthouse. Hindi nakakaapekto ang mga ito sa iyong score pero mahalagang ma-verify mo ang mga ito nang manual."
+    "message": "Kinakailangan ang mga pagsusuring ito ng baseline na [Checklist ng PWA ](https://developers.google.com/web/progressive-web-apps/checklist) pero hindi ito awtomatikong sinusuri ng Lighthouse. Hindi nakakaapekto ang mga ito sa iyong score pero mahalagang ma-verify mo ang mga ito nang manual."
   },
   "lighthouse-core/config/default-config.js | pwaCategoryTitle": {
     "message": "Progressive Web App"
diff --git a/lighthouse-core/lib/i18n/locales/he.json b/lighthouse-core/lib/i18n/locales/he.json
index cbf8d00d0..a0c3a5892 100644
--- a/lighthouse-core/lib/i18n/locales/he.json
+++ b/lighthouse-core/lib/i18n/locales/he.json
@@ -879,7 +879,7 @@
     "message": "כדי להגדיר תקציבים עבור הכמות והגודל של משאבי הדף, יש להוסיף קובץ budget.json. [מידע נוסף](https://developers.google.com/web/tools/lighthouse/audits/budgets)."
   },
   "lighthouse-core/audits/resource-summary.js | displayValue": {
-    "message": "{requestCount,plural, =1{בקשה אחת •KB‎‎ {byteCount, number, bytes}‏}two{# בקשות • KB {byteCount, number, bytes}}many{# בקשות • KB {byteCount, number, bytes}}other{# בקשות • KB {byteCount, number, bytes}}}"
+    "message": "{requestCount,plural, =1{בקשה אחת • ‎{byteCount, number, bytes} KB‏}two{# בקשות • ‎KB {byteCount, number, bytes}}many{# בקשות • ‎KB {byteCount, number, bytes}}other{# בקשות • ‎KB {byteCount, number, bytes}}}"
   },
   "lighthouse-core/audits/resource-summary.js | title": {
     "message": "יש לצמצם ככל האפשר את מספר הבקשות ואת גודל ההעברות"
diff --git a/lighthouse-core/lib/i18n/locales/hi.json b/lighthouse-core/lib/i18n/locales/hi.json
index f17c56626..99d90a2f7 100644
--- a/lighthouse-core/lib/i18n/locales/hi.json
+++ b/lighthouse-core/lib/i18n/locales/hi.json
@@ -318,7 +318,7 @@
     "message": "`<video>` एलिमेंट में `[kind=\"description\"]` वाला एक `<track>` एलिमेंट है"
   },
   "lighthouse-core/audits/apple-touch-icon.js | description": {
-    "message": "उपयोगकर्ता जब होम स्क्रीन पर प्रगतिशील वेब ऐप जोड़ें, तो iOS पर वह अच्छे से नज़र आए, इसके लिए `apple-touch-icon` तय करें. यह ज़रूरी है कि यह आइकॉन किसी ऐसे 192px (या 180px) के चौकोर PNG की तरफ़ इशारा करे जिसके आर-पार न देखा जा सके. [ज़्यादा जानें](https://developers.google.com/web/fundamentals/design-and-ux/browser-customization/)."
+    "message": "उपयोगकर्ता जब होम स्क्रीन पर प्रगतिशील वेब ऐप्लिकेशन जोड़ें, तो iOS पर वह अच्छे से नज़र आए, इसके लिए `apple-touch-icon` तय करें. यह ज़रूरी है कि यह आइकॉन किसी ऐसे 192px (या 180px) के वर्गाकार PNG की तरफ़ इशारा करे जिसके आर-पार न देखा जा सके. [ज़्यादा जानें](https://developers.google.com/web/fundamentals/design-and-ux/browser-customization/)."
   },
   "lighthouse-core/audits/apple-touch-icon.js | failureTitle": {
     "message": "एक सही `apple-touch-icon` नहीं उपलब्ध कराता"
@@ -441,7 +441,7 @@
     "message": "इमेज अगली जेनरेशन के फ़ॉर्मेट में ऑफ़र करें"
   },
   "lighthouse-core/audits/content-width.js | description": {
-    "message": "आपके ऐप्लिकेशन की सामग्री की चौड़ाई व्यूपोर्ट की चौड़ाई से मेल नहीं खाती है, तो आपका ऐप्लिकेशन मोबाइल स्क्रीन पर ऑप्टिमाइज़ नहीं किया जा सकेगा. [ज़्यादा जानें](https://developers.google.com/web/tools/lighthouse/audits/content-sized-correctly-for-viewport)."
+    "message": "अगर आपके ऐप्लिकेशन की सामग्री की चौड़ाई व्यूपोर्ट की चौड़ाई से मेल नहीं खाती है, तो आपका ऐप्लिकेशन मोबाइल स्क्रीन पर ऑप्टिमाइज़ नहीं किया जा सकेगा. [ज़्यादा जानें](https://developers.google.com/web/tools/lighthouse/audits/content-sized-correctly-for-viewport)."
   },
   "lighthouse-core/audits/content-width.js | explanation": {
     "message": "{innerWidth}px के व्यूपोर्ट का आकार {outerWidth}px की विंडो के आकार से मेल नहीं खाता है."
@@ -705,7 +705,7 @@
     "message": "इमेज के आकार की जानकारी गलत है {url}"
   },
   "lighthouse-core/audits/installable-manifest.js | description": {
-    "message": "ब्राउज़र अपनी ओर से, उपयोगकर्ताओं को आपके ऐप्लिकेशन को उनकी होमस्क्रीन पर जोड़ने के लिए कह सकते हैं. इससे उपयोगकर्ताओं के साथ बेहतरी से जुड़ने में मदद मिलती है. [ज़्यादा जानें](https://developers.google.com/web/tools/lighthouse/audits/install-prompt)."
+    "message": "ब्राउज़र अपनी ओर से उपयोगकर्ताओं को आपके ऐप्लिकेशन को उनकी होमस्क्रीन पर जोड़ने का सुझाव दे सकते हैं. इससे उपयोगकर्ताओं के साथ बेहतर तरीके से जुड़ने में मदद मिलती है. [ज़्यादा जानें](https://developers.google.com/web/tools/lighthouse/audits/install-prompt)."
   },
   "lighthouse-core/audits/installable-manifest.js | failureTitle": {
     "message": "वेब ऐप्लिकेशन का मेनिफ़ेस्ट, इंस्टॉल करने की ज़रूरतों को पूरा नहीं करता है"
@@ -738,7 +738,7 @@
     "message": "{timeInMs, number, seconds} से. में सिम्युलेट किए गए मोबाइल नेटवर्क पर इंटरैक्शन शुरू हुआ"
   },
   "lighthouse-core/audits/load-fast-enough-for-pwa.js | explanationLoadSlow": {
-    "message": "आपका पेज बहुत धीरे लोड होता है और 10 सेकंड में इंटरैक्टिव (पेज लोड होने के दौरान उपयोगकर्ता के इनपुट जैसे कि क्लिक, टैप, और बटन दबाने का जवाब देने में लगने वाला समय) नहीं होता है. सुधार करने के तरीके जानने के लिए \"प्रदर्शन\" सेक्शन में अवसरों पर नज़र डालें और गड़बड़ी की जानकारी लें."
+    "message": "आपका पेज बहुत धीरे लोड होता है और 10 सेकंड में इंटरैक्टिव नहीं होता है. सुधार करने के तरीके जानने के लिए \"परफ़ॉर्मेंस\" सेक्शन में अवसरों पर नज़र डालें और गड़बड़ी की जानकारी लें."
   },
   "lighthouse-core/audits/load-fast-enough-for-pwa.js | failureTitle": {
     "message": "मोबाइल नेटवर्क पर पेज लोड होने की गति ज़रूरत के मुताबिक तेज़ नहीं है"
@@ -762,19 +762,19 @@
     "message": "ज़्यादा से ज़्यादा उपयोगकर्ताओं तक पहुंचने के लिए, साइटों का सभी प्रमुख ब्राउज़र पर काम करना ज़रूरी है. [ज़्यादा जानें](https://developers.google.com/web/progressive-web-apps/checklist#site-works-cross-browser)."
   },
   "lighthouse-core/audits/manual/pwa-cross-browser.js | title": {
-    "message": "यह क्रॉस-ब्राउज़र वेबसाइट है जो अलग-अलग ब्राउज़र पर काम करती है"
+    "message": "यह वेबसाइट अलग-अलग ब्राउज़र पर काम करती है"
   },
   "lighthouse-core/audits/manual/pwa-each-page-has-url.js | description": {
-    "message": "पक्का करें कि अलग-अलग पेज, यूआरएल के ज़रिए डीप लिंक के लायक हैं. साथ ही, वे ऐसे खास यूआरएल हैं जो सोशल मीडिया पर शेयर करने के मकसद को पूरा करते हैं. [ज़्यादा जानें](https://developers.google.com/web/progressive-web-apps/checklist#each-page-has-a-url)."
+    "message": "पक्का करें कि हर पेज को यूआरएल के ज़रिए डीप लिंक किया जा सकता हो. साथ ही, वे ऐसे खास यूआरएल हों जिन्हें सोशल मीडिया पर शेयर किया जा सकता है. [ज़्यादा जानें](https://developers.google.com/web/progressive-web-apps/checklist#each-page-has-a-url)."
   },
   "lighthouse-core/audits/manual/pwa-each-page-has-url.js | title": {
     "message": "हर पेज का एक यूआरएल होता है"
   },
   "lighthouse-core/audits/manual/pwa-page-transitions.js | description": {
-    "message": "नेटवर्क धीमा होने के बाद भी वेब ऐप्लिकेशन पर टैप करने पर ट्रांज़िशन की रफ़्तार तेज़ महसूस होनी चाहिए. यह आपके पेज की अच्छी परफ़ॉर्मेंस के लिए अहम है. [ज़्यादा जानें](https://developers.google.com/web/progressive-web-apps/checklist#page-transitions-dont-feel-like-they-block-on-the-network)."
+    "message": "नेटवर्क धीमा होने पर भी वेब ऐप्लिकेशन में टैप करने पर ट्रांज़िशन की रफ़्तार तेज़ महसूस होनी चाहिए. यह आपके पेज की अच्छी परफ़ॉर्मेंस के लिए अहम है. [ज़्यादा जानें](https://developers.google.com/web/progressive-web-apps/checklist#page-transitions-dont-feel-like-they-block-on-the-network)."
   },
   "lighthouse-core/audits/manual/pwa-page-transitions.js | title": {
-    "message": "पेज ट्रांज़िशन को देखकर ऐसा नहीं लगना चाहिए जैसे वे नेटवर्क लोड होने का इंतज़ार कर रहे हैं"
+    "message": "पेज ट्रांज़िशन को देखकर ऐसा नहीं लगना चाहिए जैसे कि वे नेटवर्क लोड होने का इंतज़ार कर रहे हैं"
   },
   "lighthouse-core/audits/metrics/estimated-input-latency.js | description": {
     "message": "इनपुट के इंतज़ार के समय का अंदाज़ा, इस बात से लगाया जाता है कि पेज लोड होने की सबसे व्यस्त पांच सेकंड की विंडो के दौरान आपके ऐप्लिकेशन को इस्तेमाल करने वाले के इनपुट का जवाब देने में कितना समय लगेगा. इस समय का हिसाब मिलीसेकंड में लगाया जाता है. अगर इंतज़ार का समय 50 मिलीसेकंड से ज़्यादा हो, तो इस्तेमाल करने वाले आपके ऐप्लिकेशन को धीमा मान सकते हैं. [ज़्यादा जानें](https://developers.google.com/web/tools/lighthouse/audits/estimated-input-latency)."
@@ -837,7 +837,7 @@
     "message": "सर्वर बैकएंड के इंतज़ार का समय"
   },
   "lighthouse-core/audits/offline-start-url.js | description": {
-    "message": "सर्विस वर्कर की वजह से आपका वेब ऐप्लिकेशन ऑनलाइन, ऑफ़लाइन, और रुक-रुककर चलने वाले नेटवर्क कनेक्शन जैसी स्थितियों में भी अच्छे ढंग से काम करता है. [ज़्यादा जानें](https://developers.google.com/web/tools/lighthouse/audits/http-200-when-offline)."
+    "message": "सर्विस वर्कर की वजह से आपका वेब ऐप्लिकेशन ऑनलाइन, ऑफ़लाइन, और रुक-रुककर चलने वाले नेटवर्क जैसी स्थितियों में भी अच्छे ढंग से काम करता है. [ज़्यादा जानें](https://developers.google.com/web/tools/lighthouse/audits/http-200-when-offline)."
   },
   "lighthouse-core/audits/offline-start-url.js | failureTitle": {
     "message": "`start_url` ऑफ़लाइन होने पर, \"200\" कोड का जवाब नहीं देता है"
@@ -1035,7 +1035,7 @@
     "message": "टैप की जाने वाली जगहें सही आकार में हैं"
   },
   "lighthouse-core/audits/service-worker.js | description": {
-    "message": "सर्विस वर्कर एक ऐसी तकनीक है जो आपके ऐप्लिकेशन के लिए कई प्रगतिशील वेब ऐप फ़ीचर जैसे कि ऑफ़लाइन, होमस्क्रीन पर जोड़ें, और पुश नोटिफ़िकेशन को चालू करती है. [ज़्यादा जानें](https://developers.google.com/web/tools/lighthouse/audits/registered-service-worker)."
+    "message": "सर्विस वर्कर एक ऐसी तकनीक है जो आपके ऐप्लिकेशन के लिए कई प्रगतिशील वेब ऐप्लिकेशन फ़ीचर जैसे कि ऑफ़लाइन, होमस्क्रीन पर जोड़ें, और पुश नोटिफ़िकेशन को चालू करती है. [ज़्यादा जानें](https://developers.google.com/web/tools/lighthouse/audits/registered-service-worker)."
   },
   "lighthouse-core/audits/service-worker.js | explanationBadManifest": {
     "message": "इस पेज का नियंत्रण सर्विस वर्कर के पास है. हालांकि, कोई `start_url` नहीं मिला, क्योंकि मेनिफ़ेस्ट को मान्य JSON के रूप में पार्स नहीं किया जा सका"
@@ -1044,10 +1044,10 @@
     "message": "इस पेज का नियंत्रण सर्विस वर्कर के पास है. हालांकि, `start_url` ({startUrl}) सर्विस वर्कर के दायरे में नहीं है ({scopeUrl})"
   },
   "lighthouse-core/audits/service-worker.js | explanationNoManifest": {
-    "message": "इस पेज का नियंत्रण सर्विस वर्कर के पास है. हालांकि, कोई `start_url` नहीं मिला, क्योंकि कोई पेज पर कोई मेनिफ़ेस्ट ही नहीं था."
+    "message": "इस पेज का नियंत्रण सर्विस वर्कर के पास है. हालांकि, कोई `start_url` नहीं मिला, क्योंकि किसी पेज पर कोई मेनिफ़ेस्ट ही नहीं था."
   },
   "lighthouse-core/audits/service-worker.js | explanationOutOfScope": {
-    "message": "इस मूल में एक या ज़्यादा सर्विस वर्कर हैं. हालांकि, पेज ({pageUrl}) दायरे में नहीं है."
+    "message": "यहां पर एक या ज़्यादा सर्विस वर्कर हैं. हालांकि, पेज ({pageUrl}) दायरे में नहीं है."
   },
   "lighthouse-core/audits/service-worker.js | failureTitle": {
     "message": "किसी ऐसे सर्विस वर्कर को रजिस्टर नहीं करता जो पेज और `start_url` को नियंत्रित करता है"
@@ -1056,7 +1056,7 @@
     "message": "किसी ऐसे सर्विस वर्कर को रजिस्टर करता है जो पेज और `start_url` को नियंत्रित करता है"
   },
   "lighthouse-core/audits/splash-screen.js | description": {
-    "message": "उपयोगकर्ता जब अपनी होमस्क्रीन से आपका ऐप्लिकेशन लॉन्च करते हैं, तो थीम वाली स्प्लैश स्क्रीन की वजह से इसका इस्तेमाल करने वालों को अच्छा अनुभव मिलता है. [ज़्यादा जानें](https://developers.google.com/web/tools/lighthouse/audits/custom-splash-screen)."
+    "message": "उपयोगकर्ता जब अपनी होमस्क्रीन से आपका ऐप्लिकेशन लॉन्च करते हैं, तो थीम वाली स्प्लैश स्क्रीन की वजह से इस्तेमाल करने वालों को अच्छा अनुभव मिलता है. [ज़्यादा जानें](https://developers.google.com/web/tools/lighthouse/audits/custom-splash-screen)."
   },
   "lighthouse-core/audits/splash-screen.js | failureTitle": {
     "message": "पसंद के मुताबिक स्प्लैश स्क्रीन के लिए कॉन्फ़िगर नहीं किया गया"
@@ -1065,13 +1065,13 @@
     "message": "पसंद के मुताबिक स्प्लैश स्क्रीन के लिए कॉन्फ़िगर किया गया"
   },
   "lighthouse-core/audits/themed-omnibox.js | description": {
-    "message": "ब्राउज़र का पता बार आपकी वेबसाइट से मेल खाए, इसके लिए थीम इस्तेमाल कर सकते हैं. [ज़्यादा जानें](https://developers.google.com/web/tools/lighthouse/audits/address-bar)."
+    "message": "ब्राउज़र के 'पता बार' की थीम ऐसी हो सकती है जो आपकी वेबसाइट से मेल खाए. [ज़्यादा जानें](https://developers.google.com/web/tools/lighthouse/audits/address-bar)."
   },
   "lighthouse-core/audits/themed-omnibox.js | failureTitle": {
-    "message": "पता बार के लिए थीम का रंग सेट नहीं करता है."
+    "message": "'पता बार' के लिए थीम का रंग सेट नहीं करता है."
   },
   "lighthouse-core/audits/themed-omnibox.js | title": {
-    "message": "पता बार के लिए थीम का रंग सेट करता है."
+    "message": "'पता बार' के लिए थीम का रंग सेट करता है."
   },
   "lighthouse-core/audits/third-party-summary.js | columnBlockingTime": {
     "message": "मुख्य थ्रेड ब्लॉक होने का समय"
@@ -1125,7 +1125,7 @@
     "message": "\"{securityOrigin}\" के लिए पहले से कनेक्ट किया गया <link> मिला, लेकिन ब्राउज़र ने इसका इस्तेमाल नहीं किया था. यह पक्का कर लें कि आप `crossorigin` विशेषता का इस्तेमाल ठीक से कर रहे हैं."
   },
   "lighthouse-core/audits/uses-rel-preconnect.js | description": {
-    "message": "तीसरे पक्ष के मूल से जल्दी कनेक्शन बनाने के लिए `preconnect` या `dns-prefetch` संसाधन संकेत जोड़ें. [ज़्यादा जानें](https://developers.google.com/web/fundamentals/performance/resource-prioritization#preconnect)."
+    "message": "तीसरे पक्ष से जल्दी कनेक्शन बनाने के लिए `preconnect` या `dns-prefetch` संसाधन संकेत जोड़ें. [ज़्यादा जानें](https://developers.google.com/web/fundamentals/performance/resource-prioritization#preconnect)."
   },
   "lighthouse-core/audits/uses-rel-preconnect.js | title": {
     "message": "ज़रूरी मूल से प्री-कनेक्ट करें"
@@ -1158,7 +1158,7 @@
     "message": "अगर इसकी स्क्रिप्ट उपलब्ध नहीं हैं, तो पेज के मुख्य हिस्से को कुछ सामग्री रेंडर करनी चाहिए या उसकी इमेज बनानी चाहिए."
   },
   "lighthouse-core/audits/without-javascript.js | failureTitle": {
-    "message": "यह वेब पेज, JavaScript उपलब्ध न होने पर फ़ॉलबैक सामग्री मुहैया नहीं करवाता है"
+    "message": "यह वेब पेज, JavaScript उपलब्ध न होने पर फ़ॉलबैक सामग्री मुहैया नहीं कराता है"
   },
   "lighthouse-core/audits/without-javascript.js | title": {
     "message": "यह वेब पेज, JavaScript उपलब्ध नहीं होने पर कुछ सामग्री दिखाता है"
@@ -1167,13 +1167,13 @@
     "message": "अगर आप एक प्रगतिशील वेब ऐप्लिकेशन बना रहे हैं, तो सर्विस वर्कर का इस्तेमाल करें, ताकि आपका ऐप्लिकेशन ऑफ़लाइन भी काम कर सके. [ज़्यादा जानें](https://developers.google.com/web/tools/lighthouse/audits/http-200-when-offline)."
   },
   "lighthouse-core/audits/works-offline.js | failureTitle": {
-    "message": "ऑफ़लाइन होने पर, मौजूदा पेज \"200\" कोड (एचटीटीपी स्टेटस कोड जिसका मतलब है कि एचटीटीपी स्तर पर ट्रांसमिशन ठीक है) का जवाब नहीं देता है"
+    "message": "ऑफ़लाइन होने पर, मौजूदा पेज \"200\" कोड का जवाब नहीं देता है"
   },
   "lighthouse-core/audits/works-offline.js | title": {
     "message": "ऑफ़लाइन होने पर, मौजूदा पेज \"200\" कोड का जवाब देता है"
   },
   "lighthouse-core/audits/works-offline.js | warningNoLoad": {
-    "message": "ऐसा हो सकता है कि ऑफ़लाइन होने पर पेज इसलिए लोड नहीं हो रहा है, क्योंकि आपका टेस्ट यूआरएल ({requested}) को \"{final}\" की ओर रीडायरेक्ट किया गया था. टेस्टिंग के लिए सीधे दूसरी यूआरएल आज़माएं."
+    "message": "ऐसा हो सकता है कि ऑफ़लाइन होने पर पेज इसलिए लोड नहीं हो रहा है, क्योंकि आपका टेस्ट यूआरएल ({requested}) को \"{final}\" की ओर रीडायरेक्ट किया गया था. टेस्टिंग के लिए सीधे दूसरा यूआरएल आज़माएं."
   },
   "lighthouse-core/config/default-config.js | a11yAriaGroupDescription": {
     "message": "ये आपके ऐप्लिकेशन में ARIA के इस्तेमाल को बेहतर बनाने के अवसर हैं, जिससे उपयोगकर्ताओं का स्क्रीन रीडर जैसी सहायक तकनीक का अनुभव बेहतर हो सकता है."
diff --git a/lighthouse-core/lib/i18n/locales/ja.json b/lighthouse-core/lib/i18n/locales/ja.json
index 6fa39301f..807d7ba82 100644
--- a/lighthouse-core/lib/i18n/locales/ja.json
+++ b/lighthouse-core/lib/i18n/locales/ja.json
@@ -363,7 +363,7 @@
     "message": "オフスクリーン画像の遅延読み込み"
   },
   "lighthouse-core/audits/byte-efficiency/render-blocking-resources.js | description": {
-    "message": "ページの初回ペイントをリソースがブロックしています。重要な JavaScript や CSS はインラインで配信し、それ以外の JavaScript やスタイルはすべて遅らせることをご検討ください。[詳細](https://developers.google.com/web/tools/lighthouse/audits/blocking-resources)"
+    "message": "ページの First Paint をリソースがブロックしています。重要な JavaScript や CSS はインラインで配信し、それ以外の JavaScript やスタイルはすべて遅らせることをご検討ください。[詳細](https://developers.google.com/web/tools/lighthouse/audits/blocking-resources)"
   },
   "lighthouse-core/audits/byte-efficiency/render-blocking-resources.js | title": {
     "message": "レンダリングを妨げるリソースの除外"
@@ -783,10 +783,10 @@
     "message": "入力の推定待ち時間"
   },
   "lighthouse-core/audits/metrics/first-contentful-paint.js | description": {
-    "message": "コンテンツの初回ペイントは、テキストまたは画像が初めてペイントされるまでにかかった時間です。[詳細](https://developers.google.com/web/tools/lighthouse/audits/first-contentful-paint)"
+    "message": "First Contentful Paint は、テキストまたは画像が初めてペイントされるまでにかかった時間です。[詳細](https://developers.google.com/web/tools/lighthouse/audits/first-contentful-paint)"
   },
   "lighthouse-core/audits/metrics/first-contentful-paint.js | title": {
-    "message": "コンテンツの初回ペイント"
+    "message": "First Contentful Paint"
   },
   "lighthouse-core/audits/metrics/first-cpu-idle.js | description": {
     "message": "CPU の初回アイドルは、ページのメインスレッド処理が静止し、初めて入力の処理が可能になるまでにかかった時間です。[詳細](https://developers.google.com/web/tools/lighthouse/audits/first-interactive)"
@@ -795,10 +795,10 @@
     "message": "CPU の初回アイドル"
   },
   "lighthouse-core/audits/metrics/first-meaningful-paint.js | description": {
-    "message": "意味のあるコンテンツの初回ペイントは、ページの主要なコンテンツが可視化されるまでにかかった時間です。[詳細](https://developers.google.com/web/tools/lighthouse/audits/first-meaningful-paint)"
+    "message": "First Meaningful Paint は、ページの主要なコンテンツが可視化されるまでにかかった時間です。[詳細](https://developers.google.com/web/tools/lighthouse/audits/first-meaningful-paint)"
   },
   "lighthouse-core/audits/metrics/first-meaningful-paint.js | title": {
-    "message": "意味のあるコンテンツの初回ペイント"
+    "message": "First Meaningful Paint"
   },
   "lighthouse-core/audits/metrics/interactive.js | description": {
     "message": "操作可能になるまでの時間とは、ページが完全に操作可能になるのに要する時間です。[詳細](https://developers.google.com/web/tools/lighthouse/audits/consistently-interactive)"
@@ -1248,10 +1248,10 @@
     "message": "診断"
   },
   "lighthouse-core/config/default-config.js | firstPaintImprovementsGroupDescription": {
-    "message": "パフォーマンスの最も重要な点は、ピクセルをどのくらい速く画面にレンダリングできるかです。主要な指標: コンテンツの初回ペイント、意味のあるコンテンツの初回ペイント"
+    "message": "パフォーマンスの最も重要な点は、ピクセルをどのくらい速く画面にレンダリングできるかです。主要な指標: First Contentful Paint、First Meaningful Paint"
   },
   "lighthouse-core/config/default-config.js | firstPaintImprovementsGroupTitle": {
-    "message": "初回ペイントの改善点"
+    "message": "First Paint の改善点"
   },
   "lighthouse-core/config/default-config.js | loadOpportunitiesGroupDescription": {
     "message": "これらの提案を実施すると、ページの読み込み時間を短縮できる可能性があります。なお、パフォーマンス スコアには[直接影響](https://github.com/GoogleChrome/lighthouse/blob/d2ec9ffbb21de9ad1a0f86ed24575eda32c796f0/docs/scoring.md#how-are-the-scores-weighted)しません。"
diff --git a/lighthouse-core/lib/i18n/locales/ko.json b/lighthouse-core/lib/i18n/locales/ko.json
index b661ce518..fcc58ffa2 100644
--- a/lighthouse-core/lib/i18n/locales/ko.json
+++ b/lighthouse-core/lib/i18n/locales/ko.json
@@ -738,7 +738,7 @@
     "message": "시뮬레이션된 모바일 네트워크에서 페이지와 상호작용할 수 있게 될 때까지 걸린 시간: {timeInMs, number, seconds}초"
   },
   "lighthouse-core/audits/load-fast-enough-for-pwa.js | explanationLoadSlow": {
-    "message": "페이지가 너무 느리게 로드되므로 10초 이내에 사용할 수 없습니다. '성능' 섹션에서 추천 내용과 진단을 확인하고 개선 방안을 알아보세요."
+    "message": "페이지가 너무 느리게 로드되므로 10초 이내에 사용할 수 없습니다. '성능' 섹션에서 추천 내용과 진단을 확인해 개선 방안을 알아보세요."
   },
   "lighthouse-core/audits/load-fast-enough-for-pwa.js | failureTitle": {
     "message": "모바일 네트워크에서 페이지 로딩이 충분히 빠르지 않음"
@@ -1053,7 +1053,7 @@
     "message": "페이지와 `start_url`을(를) 제어하는 서비스 워커를 등록하지 않음"
   },
   "lighthouse-core/audits/service-worker.js | title": {
-    "message": "페이지와`start_url`을(를) 제어하는 서비스 워커를 등록함"
+    "message": "페이지와 `start_url`을(를) 제어하는 서비스 워커를 등록함"
   },
   "lighthouse-core/audits/splash-screen.js | description": {
     "message": "테마 스플래시 화면을 사용하면 사용자가 홈 화면에서 앱을 실행했을 때 고품질의 환경을 경험할 수 있습니다. [자세히 알아보기](https://developers.google.com/web/tools/lighthouse/audits/custom-splash-screen)"
@@ -1155,7 +1155,7 @@
     "message": "JavaScript가 사용 중지되었더라도 사용자에게 앱을 사용하려면 JavaScript가 필요하다는 경고 등의 일부 콘텐츠는 앱에 표시되어야 합니다. [자세히 알아보기](https://developers.google.com/web/tools/lighthouse/audits/no-js)"
   },
   "lighthouse-core/audits/without-javascript.js | explanation": {
-    "message": "스크립트를 사용할 수 없는 경우 페이지 본문에서 일부 콘텐츠를 렌더링해야 합니다."
+    "message": "페이지 본문에서 스크립트를 사용할 수 없는 경우 본문에서 콘텐츠를 일부 렌더링해야 합니다."
   },
   "lighthouse-core/audits/without-javascript.js | failureTitle": {
     "message": "JavaScript를 사용할 수 없는 경우 대체 콘텐츠를 제공하지 않음"
diff --git a/lighthouse-core/lib/i18n/locales/pt-PT.json b/lighthouse-core/lib/i18n/locales/pt-PT.json
index f7fe89e0e..4fd8ce7eb 100644
--- a/lighthouse-core/lib/i18n/locales/pt-PT.json
+++ b/lighthouse-core/lib/i18n/locales/pt-PT.json
@@ -1518,10 +1518,10 @@
     "message": "Um número de [plug-ins do WordPress](https://wordpress.org/plugins/search/minify+javascript/) pode acelerar o seu site ao concatenar, reduzir e comprimir os seus scripts. Poderá ainda utilizar um processo de criação para proceder previamente à redução se possível."
   },
   "stack-packs/packs/wordpress.js | unused_css_rules": {
-    "message": "Considere reduzir ou mudar o número de [plug-ins do WordPress](https://wordpress.org/plugins/) que carregam CSS não utilizadas na sua página. Para identificar plug-ins que estejam a adicionar CSS não reconhecido, experimente realizar a [cobertura de código](https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage) nas DevTools do Chrome. Pode identificar o tema/plug-in responsável a partir do URL da folha de estilos. Esteja atento a plug-ins que tenham muitas folhas de estilo na lista com muito vermelho na cobertura do código. Um plug-in só deve ter uma folha de estilos na fila de espera se esta for realmente utilizada na página."
+    "message": "Considere reduzir ou mudar o número de [plug-ins do WordPress](https://wordpress.org/plugins/) que carregam CSS não utilizadas na sua página. Para identificar plug-ins que estejam a adicionar CSS não reconhecido, experimente realizar a [cobertura de código](https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage) nas DevTools do Chrome. Pode identificar o tema/plug-in responsável a partir do URL da folha de estilos. Esteja atento a plug-ins que tenham muitas folhas de estilo na lista com muito vermelho na cobertura do código. Um plug-in só deve ter uma folha de estilos na lista de espera se esta for realmente utilizada na página."
   },
   "stack-packs/packs/wordpress.js | unused_javascript": {
-    "message": "Considere reduzir ou mudar o número de [plug-ins do WordPress](https://wordpress.org/plugins/) que carregam JavaScript não utilizado na sua página. Para identificar plug-ins que estejam a adicionar JS não reconhecido, experimente realizar a [cobertura de código](https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage) nas DevTools do Chrome. Pode identificar o tema/plug-in responsável a partir do URL do script. Esteja atento a plug-ins que tenham muitos scripts na lista com muito vermelho na cobertura do código. Um plug-in só deve ter um script na fila de espera se este for realmente utilizado na página."
+    "message": "Considere reduzir ou mudar o número de [plug-ins do WordPress](https://wordpress.org/plugins/) que carregam JavaScript não utilizado na sua página. Para identificar plug-ins que estejam a adicionar JS não reconhecido, experimente realizar a [cobertura de código](https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage) nas DevTools do Chrome. Pode identificar o tema/plug-in responsável a partir do URL do script. Esteja atento a plug-ins que tenham muitos scripts na lista com muito vermelho na cobertura do código. Um plug-in só deve ter um script na lista de espera se este for realmente utilizado na página."
   },
   "stack-packs/packs/wordpress.js | uses_long_cache_ttl": {
     "message": "Leia sobre [Colocação do navegador em cache no WordPress](https://codex.wordpress.org/WordPress_Optimization#Browser_Caching)."
diff --git a/lighthouse-core/lib/i18n/locales/ta.json b/lighthouse-core/lib/i18n/locales/ta.json
index e20bd6f09..9923c6ec9 100644
--- a/lighthouse-core/lib/i18n/locales/ta.json
+++ b/lighthouse-core/lib/i18n/locales/ta.json
@@ -282,7 +282,7 @@
     "message": "`[headers]` பண்புக்கூறைப் பயன்படுத்தும் `<table>` உறுப்பிலுள்ள கலங்கள் அதே அட்டவணையின் பிற கலங்களைக் குறிப்பிடுகின்றன."
   },
   "lighthouse-core/audits/accessibility/th-has-data-cells.js | description": {
-    "message": "அட்டவணைகளில் எளிதாகச் செல்வதற்கு ஸ்க்ரீன் ரீடர்களில் அம்சங்கள் உள்ளன. டேபிள் தலைப்புகள் எப்போதும் சில கலங்களின் தொகுப்பைக் குறிப்பிடுமாறு அமைப்பது ஸ்க்ரீன் ரீடர் பயனர்களின் அனுபவத்தை மேம்படுத்தக்கூடும். [மேலும் அறிக](https://web.dev/th-has-data-cells/)."
+    "message": "அட்டவணைகளில் எளிதாகச் செல்வதற்கு ஸ்க்ரீன் ரீடர்களில் அம்சங்கள் உள்ளன. அட்டவணைத் தலைப்புகள் எப்போதும் சில கலங்களின் தொகுப்பைக் குறிப்பிடுமாறு அமைப்பது ஸ்க்ரீன் ரீடர் பயனர்களின் அனுபவத்தை மேம்படுத்தக்கூடும். [மேலும் அறிக](https://web.dev/th-has-data-cells/)."
   },
   "lighthouse-core/audits/accessibility/th-has-data-cells.js | failureTitle": {
     "message": "`<th>` உறுப்புகளும் `[role=\"columnheader\"/\"rowheader\"]`ஐக் கொண்டுள்ள உறுப்புகளும் விவரிக்கும் தரவுக் கலங்கள் அவற்றுக்கு இல்லை."
diff --git a/lighthouse-core/lib/i18n/locales/vi.json b/lighthouse-core/lib/i18n/locales/vi.json
index 8c75577eb..fb70bd10d 100644
--- a/lighthouse-core/lib/i18n/locales/vi.json
+++ b/lighthouse-core/lib/i18n/locales/vi.json
@@ -318,7 +318,7 @@
     "message": "Các phần tử `<video>` chứa phần tử `<track>` có `[kind=\"description\"]`"
   },
   "lighthouse-core/audits/apple-touch-icon.js | description": {
-    "message": "Hãy xác định `apple-touch-icon` để hiển thị đúng cách trên iOS khi người dùng thêm một ứng dụng web tiến bộ vào màn hình chính. Thuộc tính này phải trỏ đến ảnh PNG vuông có kích thước 192px (hoặc 180px) ở dạng không trong suốt. [Tìm hiểu thêm](https://developers.google.com/web/fundamentals/design-and-ux/browser-customization/)"
+    "message": "Hãy xác định `apple-touch-icon` để khi người dùng thêm một ứng dụng web tiến bộ vào màn hình chính trên iOS, biểu tượng ứng dụng sẽ hiển thị chính xác. Thuộc tính này phải trỏ đến ảnh PNG vuông có kích thước 192px (hoặc 180px) ở dạng không trong suốt. [Tìm hiểu thêm](https://developers.google.com/web/fundamentals/design-and-ux/browser-customization/)"
   },
   "lighthouse-core/audits/apple-touch-icon.js | failureTitle": {
     "message": "Chưa cung cấp `apple-touch-icon` hợp lệ"
@@ -573,7 +573,7 @@
     "message": "Phiên bản"
   },
   "lighthouse-core/audits/dobetterweb/js-libraries.js | description": {
-    "message": "Phát hiện tất cả thư viện giao diện người dùng JavaScript trên trang này. [Tìm hiểu thêm](https://web.dev/js-libraries)"
+    "message": "Phát hiện tất cả thư viện JavaScript ở phía giao diện người dùng trên trang này. [Tìm hiểu thêm](https://web.dev/js-libraries)"
   },
   "lighthouse-core/audits/dobetterweb/js-libraries.js | title": {
     "message": "Thư viện JavaScript phát hiện được"
@@ -738,7 +738,7 @@
     "message": "Tương tác trên mạng di động mô phỏng ở giây thứ {timeInMs, number, seconds}"
   },
   "lighthouse-core/audits/load-fast-enough-for-pwa.js | explanationLoadSlow": {
-    "message": "Trang của bạn tải quá chậm và không tương tác trong vòng 10 giây. Hãy xem các cơ hội và thông tin chẩn đoán trong phần \"Hiệu suất\" để tìm hiểu cách cải thiện."
+    "message": "Trang của bạn tải quá chậm và không tương tác trong vòng 10 giây. Hãy xem các lựa chọn tối ưu hóa và thông tin chẩn đoán trong phần \"Hiệu suất\" để tìm hiểu cách cải thiện."
   },
   "lighthouse-core/audits/load-fast-enough-for-pwa.js | failureTitle": {
     "message": "Tốc độ tải trang không đủ nhanh trên mạng di động"
@@ -765,16 +765,16 @@
     "message": "Trang web hoạt động trên nhiều trình duyệt"
   },
   "lighthouse-core/audits/manual/pwa-each-page-has-url.js | description": {
-    "message": "Đảm bảo từng trang có thể liên kết sâu qua URL và URL là duy nhất, có như vậy thì mới chia sẻ được trên mạng xã hội. [Tìm hiểu thêm](https://developers.google.com/web/progressive-web-apps/checklist#each-page-has-a-url)"
+    "message": "Đảm bảo từng trang có thể liên kết sâu qua URL và URL là duy nhất để có thể chia sẻ trên mạng xã hội. [Tìm hiểu thêm](https://developers.google.com/web/progressive-web-apps/checklist#each-page-has-a-url)"
   },
   "lighthouse-core/audits/manual/pwa-each-page-has-url.js | title": {
     "message": "Mỗi trang có một URL"
   },
   "lighthouse-core/audits/manual/pwa-page-transitions.js | description": {
-    "message": "Quá trình chuyển tiếp phải diễn ra ngay khi bạn nhấn vào, kể cả khi mạng chậm, một yếu tố then chốt để tăng hiệu suất cảm nhận. [Tìm hiểu thêm](https://developers.google.com/web/progressive-web-apps/checklist#page-transitions-dont-feel-like-they-block-on-the-network)"
+    "message": "Quá trình chuyển tiếp phải diễn ra ngay khi bạn nhấn vào, kể cả khi mạng chậm. Đây là một yếu tố quan trọng trong cảm nhận về hiệu suất. [Tìm hiểu thêm](https://developers.google.com/web/progressive-web-apps/checklist#page-transitions-dont-feel-like-they-block-on-the-network)"
   },
   "lighthouse-core/audits/manual/pwa-page-transitions.js | title": {
-    "message": "Quá trình chuyển tiếp trang không bị chậm trễ do mạng"
+    "message": "Người dùng không cảm thấy mạng chậm khi chuyển trang"
   },
   "lighthouse-core/audits/metrics/estimated-input-latency.js | description": {
     "message": "Thời gian chờ nhập thông tin theo ước tính là thời gian ước tính mà ứng dụng cần để phản hồi thông tin do người dùng nhập (tính bằng mili giây) trong khoảng thời gian 5 giây tải nhiều trang nhất. Nếu người dùng phải chờ quá 50 mili giây, thì ứng dụng của bạn bị coi là chạy chậm. [Tìm hiểu thêm](https://developers.google.com/web/tools/lighthouse/audits/estimated-input-latency)."
@@ -840,10 +840,10 @@
     "message": "Trình chạy dịch vụ giúp ứng dụng web của bạn hoạt động ổn định trong điều kiện mạng chập chờn. [Tìm hiểu thêm](https://developers.google.com/web/tools/lighthouse/audits/http-200-when-offline)"
   },
   "lighthouse-core/audits/offline-start-url.js | failureTitle": {
-    "message": "`start_url` không phản hồi kèm mã trạng thái 200 khi không có mạng"
+    "message": "`start_url` không trả về mã trạng thái 200 khi không có mạng"
   },
   "lighthouse-core/audits/offline-start-url.js | title": {
-    "message": "`start_url` phản hồi kèm mã trạng thái 200 khi không có mạng"
+    "message": "`start_url` trả về mã trạng thái 200 khi không có mạng"
   },
   "lighthouse-core/audits/offline-start-url.js | warningCantStart": {
     "message": "Lighthouse không đọc được `start_url` trong tệp kê khai. Do đó, `start_url` được giả định là URL của tài liệu. Thông báo lỗi: '{manifestWarning}'."
@@ -996,7 +996,7 @@
     "message": "Tài liệu tránh sử dụng plugin"
   },
   "lighthouse-core/audits/seo/robots-txt.js | description": {
-    "message": "Nếu định dạng của tệp robots.txt không đúng, thì trình thu thập thông tin có thể không hiểu được cách bạn muốn thu thập thông tin hoặc lập chỉ mục trang web. [Tìm hiểu thêm](https://web.dev/robots-txt)"
+    "message": "Nếu định dạng của tệp robots.txt không đúng, thì trình thu thập thông tin có thể không hiểu được cách bạn muốn thu thập thông tin hoặc lập chỉ mục trang web của mình. [Tìm hiểu thêm](https://web.dev/robots-txt)"
   },
   "lighthouse-core/audits/seo/robots-txt.js | displayValueHttpBadCode": {
     "message": "Yêu cầu robots.txt trả về trạng thái HTTP: {statusCode}"
@@ -1035,19 +1035,19 @@
     "message": "Mục tiêu nhấn có kích thước phù hợp"
   },
   "lighthouse-core/audits/service-worker.js | description": {
-    "message": "Trình chạy dịch vụ là công nghệ cho phép ứng dụng của bạn dùng nhiều tính năng của Ứng dụng web tiến bộ, chẳng hạn như thêm vào màn hình chính khi không có mạng và thông báo đẩy. [Tìm hiểu thêm](https://developers.google.com/web/tools/lighthouse/audits/registered-service-worker)"
+    "message": "Trình chạy dịch vụ là công nghệ cho phép ứng dụng của bạn dùng nhiều tính năng của Ứng dụng web tiến bộ, chẳng hạn như hoạt động khi không có mạng, thêm vào màn hình chính, và thông báo đẩy. [Tìm hiểu thêm](https://developers.google.com/web/tools/lighthouse/audits/registered-service-worker)"
   },
   "lighthouse-core/audits/service-worker.js | explanationBadManifest": {
     "message": "Trang này do một trình chạy dịch vụ kiểm soát. Tuy nhiên, không tìm thấy `start_url` vì tệp kê khai không thể phân tích cú pháp thành tệp JSON hợp lệ"
   },
   "lighthouse-core/audits/service-worker.js | explanationBadStartUrl": {
-    "message": "Trang này do một trình chạy dịch vụ kiểm soát. Tuy nhiên, `start_url` ({startUrl}) không thuộc phạm vi kiểm soát của trình chạy này ({scopeUrl})"
+    "message": "Trang này do một trình chạy dịch vụ kiểm soát. Tuy nhiên, `start_url` ({startUrl}) không thuộc phạm vi của trình chạy dịch vụ này ({scopeUrl})"
   },
   "lighthouse-core/audits/service-worker.js | explanationNoManifest": {
     "message": "Trang này do một trình chạy dịch vụ kiểm soát. Tuy nhiên, không tìm thấy `start_url` vì không tìm nạp được tệp kê khai."
   },
   "lighthouse-core/audits/service-worker.js | explanationOutOfScope": {
-    "message": "Nguồn gốc này có tối thiểu một trình chạy dịch vụ. Tuy nhiên, trang ({pageUrl}) không thuộc phạm vi kiểm soát của các trình chạy này."
+    "message": "Nguồn gốc này có một hoặc nhiều trình chạy dịch vụ. Tuy nhiên, trang ({pageUrl}) không thuộc phạm vi của các trình chạy dịch vụ này."
   },
   "lighthouse-core/audits/service-worker.js | failureTitle": {
     "message": "Không đăng ký một trình chạy dịch vụ kiểm soát trang và `start_url`"
@@ -1056,7 +1056,7 @@
     "message": "Đăng ký một trình chạy dịch vụ kiểm soát trang và `start_url`"
   },
   "lighthouse-core/audits/splash-screen.js | description": {
-    "message": "Màn hình chờ theo chủ đề giúp đảm bảo người dùng có trải nghiệm chất lượng cao khi chạy ứng dụng từ màn hình chính. [Tìm hiểu thêm](https://developers.google.com/web/tools/lighthouse/audits/custom-splash-screen)"
+    "message": "Màn hình chờ có giao diện giúp đảm bảo người dùng có trải nghiệm chất lượng cao khi chạy ứng dụng từ màn hình chính. [Tìm hiểu thêm](https://developers.google.com/web/tools/lighthouse/audits/custom-splash-screen)"
   },
   "lighthouse-core/audits/splash-screen.js | failureTitle": {
     "message": "Chưa được định cấu hình cho màn hình chờ tùy chỉnh"
@@ -1065,13 +1065,13 @@
     "message": "Đã định cấu hình cho màn hình chờ tùy chỉnh"
   },
   "lighthouse-core/audits/themed-omnibox.js | description": {
-    "message": "Bạn có thể đặt màu chủ đề cho thanh địa chỉ trên trình duyệt để phù hợp với trang web của mình. [Tìm hiểu thêm](https://developers.google.com/web/tools/lighthouse/audits/address-bar)"
+    "message": "Bạn có thể đặt giao diện cho thanh địa chỉ trên trình duyệt để phù hợp với trang web của mình. [Tìm hiểu thêm](https://developers.google.com/web/tools/lighthouse/audits/address-bar)"
   },
   "lighthouse-core/audits/themed-omnibox.js | failureTitle": {
-    "message": "Không đặt màu chủ đề cho thanh địa chỉ."
+    "message": "Không đặt màu giao diện cho thanh địa chỉ."
   },
   "lighthouse-core/audits/themed-omnibox.js | title": {
-    "message": "Đặt màu chủ đề cho thanh địa chỉ."
+    "message": "Đặt màu giao diện cho thanh địa chỉ."
   },
   "lighthouse-core/audits/third-party-summary.js | columnBlockingTime": {
     "message": "Thời gian chặn chuỗi chính"
@@ -1152,25 +1152,25 @@
     "message": "Có thẻ `<meta name=\"viewport\">` có `width` hoặc `initial-scale`"
   },
   "lighthouse-core/audits/without-javascript.js | description": {
-    "message": "Ứng dụng của bạn phải hiển thị nội dung nào đó khi JavaScript bị tắt, ngay cả khi đó chỉ là cảnh báo cho người dùng biết phải có JavaScript mới dùng được ứng dụng. [Tìm hiểu thêm](https://developers.google.com/web/tools/lighthouse/audits/no-js)."
+    "message": "Ứng dụng của bạn phải hiển thị một số nội dung khi JavaScript bị tắt, ngay cả khi đó chỉ là một cảnh báo cho người dùng biết phải có JavaScript mới dùng được ứng dụng. [Tìm hiểu thêm](https://developers.google.com/web/tools/lighthouse/audits/no-js)."
   },
   "lighthouse-core/audits/without-javascript.js | explanation": {
-    "message": "Phần nội dung trang phải hiển thị nội dung nào đó ngay cả khi không tải được tập lệnh"
+    "message": "Phần nội dung trang phải hiển thị một số nội dung nếu không có sẵn tập lệnh."
   },
   "lighthouse-core/audits/without-javascript.js | failureTitle": {
-    "message": "Không cung cấp nội dung dự phòng khi JavaScript không hoạt động"
+    "message": "Không cung cấp nội dung dự phòng khi JavaScript không có sẵn"
   },
   "lighthouse-core/audits/without-javascript.js | title": {
-    "message": "Chứa nội dung nào đó khi JavaScript không hoạt động"
+    "message": "Chứa một số nội dung khi JavaScript không có sẵn"
   },
   "lighthouse-core/audits/works-offline.js | description": {
     "message": "Nếu bạn đang tạo một Ứng dụng web tiến bộ, hãy cân nhắc dùng trình chạy dịch vụ để ứng dụng có thể hoạt động khi không có mạng. [Tìm hiểu thêm](https://developers.google.com/web/tools/lighthouse/audits/http-200-when-offline)"
   },
   "lighthouse-core/audits/works-offline.js | failureTitle": {
-    "message": "Trang hiện tại không phản hồi kèm mã trạng thái 200 khi không có mạng"
+    "message": "Trang hiện tại không trả về mã trạng thái 200 khi không có mạng"
   },
   "lighthouse-core/audits/works-offline.js | title": {
-    "message": "Trang hiện tại phản hồi kèm mã trạng thái 200 khi không có mạng"
+    "message": "Trang hiện tại trả về mã trạng thái 200 khi không có mạng"
   },
   "lighthouse-core/audits/works-offline.js | warningNoLoad": {
     "message": "Trang này có thể không tải được khi không có mạng vì URL kiểm tra ({requested}) đã được chuyển hướng tới \"{final}\". Hãy thử kiểm tra trực tiếp URL thứ hai."
@@ -1275,7 +1275,7 @@
     "message": "Những hoạt động kiểm tra này sẽ xác thực các khía cạnh của một Ứng dụng web tiến bộ. [Tìm hiểu thêm](https://developers.google.com/web/progressive-web-apps/checklist)."
   },
   "lighthouse-core/config/default-config.js | pwaCategoryManualDescription": {
-    "message": "Bạn phải tiến hành những hoạt động kiểm tra mà Lighthouse không tự động thực hiện trong [Danh sách kiểm tra ứng dụng web tiến bộ (PWA)](https://developers.google.com/web/progressive-web-apps/checklist). Các hoạt động kiểm tra này không ảnh hưởng đến điểm số của bạn, nhưng bạn phải xác minh theo cách thủ công."
+    "message": "Đây là những hoạt động kiểm tra được chỉ định trong [Danh sách kiểm tra ứng dụng web tiến bộ (PWA)](https://developers.google.com/web/progressive-web-apps/checklist) cơ bản, nhưng Lighthouse không tự động kiểm tra các mục này. Các hoạt động kiểm tra này không ảnh hưởng đến điểm số của bạn, nhưng bạn nên xác minh theo cách thủ công."
   },
   "lighthouse-core/config/default-config.js | pwaCategoryTitle": {
     "message": "Ứng dụng web tiến bộ"
diff --git a/lighthouse-core/lib/tracehouse/main-thread-tasks.js b/lighthouse-core/lib/tracehouse/main-thread-tasks.js
index 78ce49637..653ac3930 100644
--- a/lighthouse-core/lib/tracehouse/main-thread-tasks.js
+++ b/lighthouse-core/lib/tracehouse/main-thread-tasks.js
@@ -31,6 +31,7 @@ const {taskGroups, taskNameToGroup} = require('./task-groups.js');
  * @prop {LH.TraceEvent} event
  * @prop {TaskNode[]} children
  * @prop {TaskNode|undefined} parent
+ * @prop {boolean} unbounded Indicates that the task had an endTime that was inferred rather than specified in the trace. i.e. in the source trace this task was unbounded.
  * @prop {number} startTime
  * @prop {number} endTime
  * @prop {number} duration
@@ -64,6 +65,7 @@ class MainThreadTasks {
       duration: endTime - startTime,
 
       // These properties will be filled in later
+      unbounded: false,
       parent: undefined,
       children: [],
       attributableURLs: [],
@@ -181,10 +183,12 @@ class MainThreadTasks {
 
       /** @type {Pick<LH.TraceEvent, 'ph'|'ts'>} */
       let taskEndEvent;
+      let unbounded = false;
       if (matchedEventIndex === -1) {
         // If we couldn't find an end event, we'll assume it's the end of the trace.
         // If this creates invalid parent/child relationships it will be caught in the next step.
         taskEndEvent = {ph: 'E', ts: traceEndTs};
+        unbounded = true;
       } else if (matchedEventIndex === taskEndEventsReverseQueue.length - 1) {
         // Use .pop() in the common case where the immediately next event is needed.
         // It's ~25x faster, https://jsperf.com/pop-vs-splice.
@@ -193,7 +197,9 @@ class MainThreadTasks {
         taskEndEvent = taskEndEventsReverseQueue.splice(matchedEventIndex, 1)[0];
       }
 
-      tasks.push(MainThreadTasks._createNewTaskNode(taskStartEvent, taskEndEvent));
+      const task = MainThreadTasks._createNewTaskNode(taskStartEvent, taskEndEvent);
+      task.unbounded = unbounded;
+      tasks.push(task);
     }
 
     if (taskEndEventsReverseQueue.length) {
@@ -247,18 +253,29 @@ class MainThreadTasks {
         if (nextTask.endTime > currentTask.endTime) {
           const timeDelta = nextTask.endTime - currentTask.endTime;
           // The child task is taking longer than the parent task, which should be impossible.
-          //    If it's less than 1ms, we'll let it slide by increasing the duration of the parent.
-          //    If it's more, throw an error.
+          // In reality these situations happen, so we allow for some flexibility in trace event times.
           if (timeDelta < 1000) {
+            // It's less than 1ms, we'll let it slide by increasing the duration of the parent.
             currentTask.endTime = nextTask.endTime;
             currentTask.duration += timeDelta;
+          } else if (nextTask.unbounded) {
+            // It's ending at traceEndTs, it means we were missing the end event. We'll truncate it to the parent.
+            nextTask.endTime = currentTask.endTime;
+            nextTask.duration = nextTask.endTime - nextTask.startTime;
           } else {
-            // If we fell into this error, it's usually because of one of three reasons.
-            //    - We were missing an E event for a child task and we assumed the child ended at the end of the trace.
+            // None of our workarounds matched. It's time to throw an error.
+            // When we fall into this error, it's usually because of one of two reasons.
             //    - There was slop in the opposite direction (child started 1ms before parent) and the child was assumed to be parent instead.
             //    - The child timestamp ended more than 1ms after tha parent.
             // These have more complicated fixes, so handling separately https://github.com/GoogleChrome/lighthouse/pull/9491#discussion_r327331204.
-            throw new Error('Fatal trace logic error - child cannot end after parent');
+            /** @type {any} */
+            const error = new Error('Fatal trace logic error - child cannot end after parent');
+            error.timeDelta = timeDelta;
+            error.nextTaskEvent = nextTask.event;
+            error.nextTaskEndTime = nextTask.endTime;
+            error.currentTaskEvent = currentTask.event;
+            error.currentTaskEndTime = currentTask.endTime;
+            throw error;
           }
         }
 
diff --git a/lighthouse-core/report/html/renderer/report-ui-features.js b/lighthouse-core/report/html/renderer/report-ui-features.js
index 7de3a0566..e848b3f7e 100644
--- a/lighthouse-core/report/html/renderer/report-ui-features.js
+++ b/lighthouse-core/report/html/renderer/report-ui-features.js
@@ -63,7 +63,6 @@ class ReportUIFeatures {
     this.onCopy = this.onCopy.bind(this);
     this.onDropDownMenuClick = this.onDropDownMenuClick.bind(this);
     this.onKeyUp = this.onKeyUp.bind(this);
-    this.onChevronClick = this.onChevronClick.bind(this);
     this.collapseAllDetails = this.collapseAllDetails.bind(this);
     this.expandAllDetails = this.expandAllDetails.bind(this);
     this._toggleDarkTheme = this._toggleDarkTheme.bind(this);
@@ -361,16 +360,6 @@ class ReportUIFeatures {
     }
   }
 
-  onChevronClick() {
-    const toggle = this._dom.find('.lh-config__settings-toggle', this._document);
-
-    if (toggle.hasAttribute('open')) {
-      toggle.removeAttribute('open');
-    } else {
-      toggle.setAttribute('open', 'true');
-    }
-  }
-
   /**
    * Resets the state of page before capturing the page for export.
    * When the user opens the exported HTML page, certain UI elements should
diff --git a/lighthouse-core/report/html/templates.html b/lighthouse-core/report/html/templates.html
index 3cd8cdefc..57462c176 100644
--- a/lighthouse-core/report/html/templates.html
+++ b/lighthouse-core/report/html/templates.html
@@ -359,11 +359,34 @@ limitations under the License.
   </style>
 
   <div class="lh-topbar">
-    <!-- Flat Lighthouse logo.  -->
-    <svg class="lh-topbar__logo" viewBox="0 0 192 192">
+    <!-- Lighthouse logo.  -->
+    <svg class="lh-topbar__logo" viewBox="0 0 24 24">
+      <defs>
+        <linearGradient x1="57.456%" y1="13.086%" x2="18.259%" y2="72.322%" id="lh-topbar__logo--a">
+          <stop stop-color="#262626" stop-opacity=".1" offset="0%"/>
+          <stop stop-color="#262626" stop-opacity="0" offset="100%"/>
+        </linearGradient>
+        <linearGradient x1="100%" y1="50%" x2="0%" y2="50%" id="lh-topbar__logo--b">
+          <stop stop-color="#262626" stop-opacity=".1" offset="0%"/>
+          <stop stop-color="#262626" stop-opacity="0" offset="100%"/>
+        </linearGradient>
+        <linearGradient x1="58.764%" y1="65.756%" x2="36.939%" y2="50.14%" id="lh-topbar__logo--c">
+          <stop stop-color="#262626" stop-opacity=".1" offset="0%"/>
+          <stop stop-color="#262626" stop-opacity="0" offset="100%"/>
+        </linearGradient>
+        <linearGradient x1="41.635%" y1="20.358%" x2="72.863%" y2="85.424%" id="lh-topbar__logo--d">
+          <stop stop-color="#FFF" stop-opacity=".1" offset="0%"/>
+          <stop stop-color="#FFF" stop-opacity="0" offset="100%"/>
+        </linearGradient>
+      </defs>
       <g fill="none" fill-rule="evenodd">
-        <path d="M0 0h192v192H0z"/>
-        <path class="shape" d="M67.705 179.352l2.603-20.82 49.335-16.39 4.652 37.21A87.893 87.893 0 0 1 96 184a87.893 87.893 0 0 1-28.295-4.648zM52.44 172.48C25.894 157.328 8 128.754 8 96 8 47.399 47.399 8 96 8s88 39.399 88 88c0 32.754-17.894 61.328-44.44 76.48L130 96h6V80h-8V48L96 28 64 48v32h-8v16h6l-9.56 76.48zM113.875 96l2.882 23.05-43.318 14.433L78.125 96h35.75zM80 80V56.868l16-10 16 10V80H80z"/>
+        <path d="M12 3l4.125 2.625v3.75H18v2.25h-1.688l1.5 9.375H6.188l1.5-9.375H6v-2.25h1.875V5.648L12 3zm2.201 9.938L9.54 14.633 9 18.028l5.625-2.062-.424-3.028zM12.005 5.67l-1.88 1.207v2.498h3.75V6.86l-1.87-1.19z" fill="#F44B21"/>
+        <path fill="#FFF" d="M14.201 12.938L9.54 14.633 9 18.028l5.625-2.062z"/>
+        <path d="M6 18c-2.042 0-3.95-.01-5.813 0l1.5-9.375h4.326L6 18z" fill="url(#lh-topbar__logo--a)" fill-rule="nonzero" transform="translate(6 3)"/>
+        <path fill="#FFF176" fill-rule="nonzero" d="M13.875 9.375v-2.56l-1.87-1.19-1.88 1.207v2.543z"/>
+        <path fill="url(#lh-topbar__logo--b)" fill-rule="nonzero" d="M0 6.375h6v2.25H0z" transform="translate(6 3)"/>
+        <path fill="url(#lh-topbar__logo--c)" fill-rule="nonzero" d="M6 6.375H1.875v-3.75L6 0z" transform="translate(6 3)"/>
+        <path fill="url(#lh-topbar__logo--d)" fill-rule="nonzero" d="M6 0l4.125 2.625v3.75H12v2.25h-1.688l1.5 9.375H.188l1.5-9.375H0v-2.25h1.875V2.648z" transform="translate(6 3)"/>
       </g>
     </svg>
 
@@ -394,29 +417,6 @@ limitations under the License.
 <!-- Lighthouse header -->
 <template id="tmpl-lh-heading">
   <style>
-/*
-    TODO: Enable animating the clouds
-    .lh-lighthouse__clouds {
-      animation: panacross 30s linear infinite;
-      animation-play-state: paused;
-    }
-    @keyframes panacross {
-      0% { transform: translateX(0px); }
-      77% { transform: translateX(-680px); }
-      77.0001% { transform: translateX(195px); }
-      100% { transform: translateX(0px); }
-    } */
-
-    .score100 .lh-header-bg {
-      background-color: hsl(234, 64%, 19%);
-    }
-    .score100 .lh-metadata, .score100 .lh-toolbar__metadata, .score100 .lh-product-info {
-      color: #fff;
-    }
-    .score100 .lh-config {
-      color: #eee;
-    }
-
     /* CSS Fireworks. Originally by Eddie Lin
        https://codepen.io/paulirish/pen/yEVMbP
     */
diff --git a/lighthouse-core/scripts/compare-timings.js b/lighthouse-core/scripts/compare-timings.js
new file mode 100644
index 000000000..a8f6f8d4a
--- /dev/null
+++ b/lighthouse-core/scripts/compare-timings.js
@@ -0,0 +1,288 @@
+/**
+ * @license Copyright 2019 Google Inc. All Rights Reserved.
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ */
+'use strict';
+
+// Example:
+//     node lighthouse-core/scripts/compare-timings.js --name my-collection --collect -n 3 --lh-flags='--only-audits=unminified-javascript' --urls https://www.example.com https://www.nyt.com
+//     node lighthouse-core/scripts/compare-timings.js --name my-collection --summarize --measure-filter 'loadPage|connect'
+//     node lighthouse-core/scripts/compare-timings.js --name base --name pr --compare
+
+const fs = require('fs');
+const {execSync} = require('child_process');
+const yargs = require('yargs');
+
+const LH_ROOT = `${__dirname}/../..`;
+const ROOT_OUTPUT_DIR = `${LH_ROOT}/timings-data`;
+
+const argv = yargs
+  .help('help')
+  .describe({
+    // common flags
+    'name': 'Unique identifier, makes the folder for storing LHRs. Not a path',
+    'report-exclude': 'Regex of properties to exclude. Set to "none" to disable default',
+    // --collect
+    'collect': 'Saves LHRs to disk',
+    'lh-flags': 'Lighthouse flags',
+    'urls': 'Urls to run',
+    'n': 'Number of times to run',
+    // --summarize
+    'summarize': 'Prints statistics report',
+    'measure-filter': 'Regex of measures to include. Optional',
+    'output': 'table, json',
+    // --compare
+    'compare': 'Compare two sets of LHRs',
+    'delta-property-sort': 'Property to sort by its delta',
+    'desc': 'Set to override default ascending sort',
+  })
+  .string('measure-filter')
+  .default('report-exclude', 'min|max|stdev|^n$')
+  .default('delta-property-sort', 'mean')
+  .default('output', 'table')
+  .array('urls')
+  .string('lh-flags')
+  .default('desc', false)
+  .default('lh-flags', '')
+  .wrap(yargs.terminalWidth())
+.argv;
+
+const reportExcludeRegex =
+  argv.reportExclude !== 'none' ? new RegExp(argv.reportExclude, 'i') : null;
+
+/**
+ * @param {string} name
+ */
+function dir(name) {
+  return `${ROOT_OUTPUT_DIR}/${name}`;
+}
+
+/**
+ * @param {number[]} values
+ */
+function sum(values) {
+  return values.reduce((sum, value) => sum + value);
+}
+
+/**
+ * @param {number[]} values
+ */
+function average(values) {
+  return sum(values) / values.length;
+}
+
+/**
+ * @param {number[]} values
+ */
+function sampleStdev(values) {
+  const mean = average(values);
+  const variance = sum(values.map(value => (value - mean) ** 2)) / (values.length - 1);
+  return Math.sqrt(variance);
+}
+
+/**
+ * Round to the tenth.
+ * @param {number} value
+ */
+function round(value) {
+  return Math.round(value * 10) / 10;
+}
+
+function collect() {
+  const outputDir = dir(argv.name);
+  if (!fs.existsSync(ROOT_OUTPUT_DIR)) fs.mkdirSync(ROOT_OUTPUT_DIR);
+  if (fs.existsSync(outputDir)) throw new Error(`folder already exists: ${outputDir}`);
+  fs.mkdirSync(outputDir);
+
+  for (const url of argv.urls) {
+    for (let i = 0; i < argv.n; i++) {
+      const cmd = [
+        'node',
+        `${LH_ROOT}/lighthouse-cli`,
+        url,
+        `--output-path=${outputDir}/lhr-${url.replace(/[^a-zA-Z0-9]/g, '_')}-${i}.json`,
+        '--output=json',
+        argv.lhFlags,
+      ].join(' ');
+      execSync(cmd, {stdio: 'ignore'});
+    }
+  }
+}
+
+/**
+ * @param {string} name
+ */
+function aggregateResults(name) {
+  const outputDir = dir(name);
+
+  // `${url}@@@${entry.name}` -> duration
+  /** @type {Map<string, number[]>} */
+  const durationsMap = new Map();
+  const measureFilter = argv.measureFilter ? new RegExp(argv.measureFilter, 'i') : null;
+
+  for (const lhrPath of fs.readdirSync(outputDir)) {
+    const lhrJson = fs.readFileSync(`${outputDir}/${lhrPath}`, 'utf-8');
+    /** @type {LH.Result} */
+    const lhr = JSON.parse(lhrJson);
+
+    // Group the durations of each entry of the same name.
+    /** @type {Record<string, number[]>} */
+    const durationsByName = {};
+    for (const entry of lhr.timing.entries) {
+      if (measureFilter && !measureFilter.test(entry.name)) {
+        continue;
+      }
+
+      const durations = durationsByName[entry.name] = durationsByName[entry.name] || [];
+      durations.push(entry.duration);
+    }
+
+    // Push the aggregate time of each unique (by name) entry.
+    for (const [name, durationsForSingleRun] of Object.entries(durationsByName)) {
+      const key = `${lhr.requestedUrl}@@@${name}`;
+      let durations = durationsMap.get(key);
+      if (!durations) {
+        durations = [];
+        durationsMap.set(key, durations);
+      }
+      durations.push(sum(durationsForSingleRun));
+    }
+  }
+
+  return [...durationsMap].map(([key, durations]) => {
+    const [url, entryName] = key.split('@@@');
+    const mean = average(durations);
+    const min = Math.min(...durations);
+    const max = Math.max(...durations);
+    const stdev = sampleStdev(durations);
+    return {
+      key,
+      measure: entryName,
+      url,
+      n: durations.length,
+      mean: round(mean),
+      stdev: round(stdev),
+      min: round(min),
+      max: round(max),
+    };
+  }).sort((a, b) => {
+    // sort by {measure, url}
+    const measureComp = a.measure.localeCompare(b.measure);
+    if (measureComp !== 0) return measureComp;
+    return a.url.localeCompare(b.url);
+  });
+}
+
+/**
+ * @param {*[]} results
+ */
+function filter(results) {
+  if (!reportExcludeRegex) return;
+
+  for (const result of results) {
+    for (const key in result) {
+      if (reportExcludeRegex.test(key)) delete result[key];
+    }
+  }
+}
+
+/**
+ * @param {number=} value
+ * @return {value is number}
+ */
+function exists(value) {
+  return typeof value !== 'undefined';
+}
+
+function summarize() {
+  const results = aggregateResults(argv.name);
+  filter(results);
+  print(results);
+}
+
+/**
+ * @param {number=} base
+ * @param {number=} other
+ */
+function compareValues(base, other) {
+  const basePart = exists(base) ? base : 'N/A';
+  const otherPart = exists(other) ? other : 'N/A';
+  return {
+    description: `${basePart} -> ${otherPart}`,
+    delta: exists(base) && exists(other) ? (other - base) : undefined,
+  };
+}
+
+function compare() {
+  if (!Array.isArray(argv.name) || argv.name.length !== 2) {
+    throw new Error('expected two entries for name option');
+  }
+
+  const baseResults = aggregateResults(argv.name[0]);
+  const otherResults = aggregateResults(argv.name[1]);
+
+  const keys = [...new Set([...baseResults.map(r => r.key), ...otherResults.map(r => r.key)])];
+  const results = keys.map(key => {
+    const baseResult = baseResults.find(result => result.key === key);
+    const otherResult = otherResults.find(result => result.key === key);
+
+    const someResult = baseResult || otherResult;
+    if (!someResult) throw new Error('impossible');
+
+    const mean = compareValues(baseResult && baseResult.mean, otherResult && otherResult.mean);
+    const stdev = compareValues(baseResult && baseResult.stdev, otherResult && otherResult.stdev);
+    const min = compareValues(baseResult && baseResult.min, otherResult && otherResult.min);
+    const max = compareValues(baseResult && baseResult.max, otherResult && otherResult.max);
+
+    return {
+      'measure': someResult.measure,
+      'url': someResult.url,
+      'mean': mean.description,
+      'mean Δ': exists(mean.delta) ? round(mean.delta) : undefined,
+      'stdev': stdev.description,
+      'stdev Δ': exists(stdev.delta) ? round(stdev.delta) : undefined,
+      'min': min.description,
+      'min Δ': exists(min.delta) ? round(min.delta) : undefined,
+      'max': max.description,
+      'max Δ': exists(max.delta) ? round(max.delta) : undefined,
+    };
+  });
+
+  const sortByKey = `${argv.deltaPropertySort} Δ`;
+  results.sort((a, b) => {
+    // @ts-ignore - shhh tsc.
+    const aValue = a[sortByKey];
+    // @ts-ignore - shhh tsc.
+    const bValue = b[sortByKey];
+
+    // Always put the keys missing a result at the bottom of the table.
+    if (!exists(aValue)) return 1;
+    else if (!exists(bValue)) return -1;
+
+    return (argv.desc ? 1 : -1) * (Math.abs(aValue) - Math.abs(bValue));
+  });
+  filter(results);
+  print(results);
+}
+
+/**
+ * @param {*[]} results
+ */
+function print(results) {
+  if (argv.output === 'table') {
+    // eslint-disable-next-line no-console
+    console.table(results);
+  } else if (argv.output === 'json') {
+    // eslint-disable-next-line no-console
+    console.log(JSON.stringify(results, null, 2));
+  }
+}
+
+function main() {
+  if (argv.collect) collect();
+  if (argv.summarize) summarize();
+  if (argv.compare) compare();
+}
+
+main();
diff --git a/package.json b/package.json
index 56c82ebe1..08a421912 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "lighthouse",
-  "version": "5.4.0",
+  "version": "5.5.0",
   "description": "Lighthouse",
   "main": "./lighthouse-core/index.js",
   "bin": {
diff --git a/proto/sample_v2_round_trip.json b/proto/sample_v2_round_trip.json
index 06c55d351..63b56c509 100644
--- a/proto/sample_v2_round_trip.json
+++ b/proto/sample_v2_round_trip.json
@@ -3986,7 +3986,7 @@
             "warningHeader": "Warnings: "
         }
     },
-    "lighthouseVersion": "5.4.0",
+    "lighthouseVersion": "5.5.0",
     "requestedUrl": "http://localhost:10200/dobetterweb/dbw_tester.html",
     "runWarnings": [],
     "stackPacks": [
diff --git a/readme.md b/readme.md
index 925c123e4..efea1341d 100644
--- a/readme.md
+++ b/readme.md
@@ -301,6 +301,8 @@ This section details services that have integrated Lighthouse data. If you're wo
 
 * **[Web Page Test](https://www.webpagetest.org)** — An [open source](https://github.com/WPO-Foundation/webpagetest) tool for measuring and analyzing the performance of web pages on real devices. Users can choose to produce a Lighthouse report alongside the analysis of WebPageTest results.
 
+* **[is-website-vulnerable](https://github.com/lirantal/is-website-vulnerable)** - An open source Node.js CLI tool that finds publicly known security vulnerabilities in a website's frontend JavaScript libraries.
+
 ## Plugins
 
 * **[lighthouse-plugin-field-performance](https://github.com/treosh/lighthouse-plugin-field-performance)** - a plugin that adds real-user performance metrics for the URL using the data from [Chrome UX Report](https://developers.google.com/web/tools/chrome-user-experience-report/).
@@ -309,11 +311,14 @@ This section details services that have integrated Lighthouse data. If you're wo
 Other awesome open source projects that use Lighthouse.
 
 * **[Exthouse](https://github.com/treosh/exthouse)** - Analyze the impact of a browser extension on web performance.
-* **[Garie](https://github.com/boyney123/garie)** — An open source tool for monitoring performance using Lighthouse,  PageSpeed Insights, [Prometheus](https://prometheus.io/), [Grafana](https://grafana.com/) and [Docker](https://www.docker.com/).
+* **[Garie](https://github.com/boyney123/garie)** - An open source tool for monitoring performance using Lighthouse,  PageSpeed Insights, [Prometheus](https://prometheus.io/), [Grafana](https://grafana.com/) and [Docker](https://www.docker.com/).
 * **[Gimbal](https://labs.moduscreate.com/gimbal-web-performance-audit-budgeting)** - An [open source (MIT licensed)](https://github.com/ModusCreateOrg/gimbal) tool used to measure, analyze, and budget aspects of a web application. Gimbal also integrates reports with GitHub pull requests.
+* **[Gradle Lighthouse Plugin](https://github.com/Cognifide/gradle-lighthouse-plugin)** - An open source Gradle plugin that runs Lighthouse tests on multiple URLs and asserts category score thresholds (useful in continuous integration).
 * **[lightcrawler](https://github.com/github/lightcrawler)** - Crawl a website and run each page found through Lighthouse.
 * **[lighthouse-badges](https://github.com/emazzotta/lighthouse-badges)** - Generate gh-badges (shields.io) based on Lighthouse performance.
 * **[lighthouse-batch](https://www.npmjs.com/package/lighthouse-batch)** - Run Lighthouse over a number of sites and generate a summary of their metrics/scores.
+* **[lighthouse-check-action](https://github.com/foo-software/lighthouse-check-action)** - A Github Action to run Lighthouse in a workflow, featuring Slack notifications and report upload to S3.
+* **[lighthouse-check-orb](https://circleci.com/orbs/registry/orb/foo-software/lighthouse-check)** - A CircleCI Orb to run Lighthouse in a workflow, featuring Slack notifications and report upload to S3.
 * **[lighthouse-ci](https://github.com/andreasonny83/lighthouse-ci)** - Run Lighthouse and assert scores satisfy your custom thresholds.
 * **[lighthouse-ci-action](https://github.com/treosh/lighthouse-ci-action)** - A Github Action that makes it easy to run Lighthouse in CI and keep your pages small using performance budgets.
 * **[lighthouse-cron](https://github.com/thearegee/lighthouse-cron)** - Cron multiple batch Lighthouse audits and emit results for sending to remote server.
diff --git a/third-party/snyk/snapshot.json b/third-party/snyk/snapshot.json
index 79284f279..1765ffeba 100644
--- a/third-party/snyk/snapshot.json
+++ b/third-party/snyk/snapshot.json
@@ -1,25 +1,28 @@
 {
   "npm":{
     "angular":[
+      {"id":"SNYK-JS-ANGULAR-471885","severity":"medium","semver":{"vulnerable":["<1.6.3"]}},
+      {"id":"SNYK-JS-ANGULAR-471882","severity":"medium","semver":{"vulnerable":["<1.6.5"]}},
+      {"id":"SNYK-JS-ANGULAR-471879","severity":"medium","semver":{"vulnerable":["<1.6.0-rc.0"]}},
       {"id":"npm:angular:20180202","severity":"medium","semver":{"vulnerable":["<1.6.9"]}},
       {"id":"npm:angular:20171018","severity":"medium","semver":{"vulnerable":["<1.6.7"]}},
-      {"id":"npm:angular:20160527","severity":"medium","semver":{"vulnerable":["<1.2.30 >=1.0.0"]}},
-      {"id":"npm:angular:20160122","severity":"medium","semver":{"vulnerable":["<1.5.0-rc.2 >=1.3.0"]}},
+      {"id":"npm:angular:20160527","severity":"medium","semver":{"vulnerable":[">=1.0.0 <1.2.30"]}},
+      {"id":"npm:angular:20160122","severity":"medium","semver":{"vulnerable":[">=1.3.0 <1.5.0-rc.2"]}},
       {"id":"npm:angular:20140608","severity":"low","semver":{"vulnerable":["<1.3.0"]}},
       {"id":"npm:angular:20131113","severity":"high","semver":{"vulnerable":["<1.2.2"]}},
       {"id":"npm:angular:20140908","severity":"medium","semver":{"vulnerable":["<1.3.0-rc.4"]}},
-      {"id":"npm:angular:20161101","severity":"medium","semver":{"vulnerable":["<1.5.9 >=1.5.0"]}},
+      {"id":"npm:angular:20161101","severity":"medium","semver":{"vulnerable":[">=1.5.0 <1.5.9"]}},
       {"id":"npm:angular:20150909","severity":"high","semver":{"vulnerable":["<1.5.0-beta.2"]}},
       {"id":"npm:angular:20151205","severity":"medium","semver":{"vulnerable":["<1.5.0-rc.0"]}},
       {"id":"npm:angular:20151130","severity":"medium","semver":{"vulnerable":["<1.4.10"]}},
-      {"id":"npm:angular:20130622","severity":"medium","semver":{"vulnerable":["<1.2.0 >=1.0.0"]}},
-      {"id":"npm:angular:20150807-1","severity":"medium","semver":{"vulnerable":["<1.5.0-beta.0 >=1.3.1"]}},
-      {"id":"npm:angular:20150807","severity":"high","semver":{"vulnerable":["<1.5.0-beta.0 >=1.0.0"]}},
+      {"id":"npm:angular:20130622","severity":"medium","semver":{"vulnerable":[">=1.0.0 <1.2.0"]}},
+      {"id":"npm:angular:20150807-1","severity":"medium","semver":{"vulnerable":[">=1.3.1 <1.5.0-beta.0"]}},
+      {"id":"npm:angular:20150807","severity":"high","semver":{"vulnerable":[">=1.0.0 <1.5.0-beta.0"]}},
       {"id":"npm:angular:20150315","severity":"medium","semver":{"vulnerable":["<1.6.1"]}},
       {"id":"npm:angular:20150310","severity":"high","semver":{"vulnerable":["<1.5.0-beta.2"]}},
       {"id":"npm:angular:20141104","severity":"medium","semver":{"vulnerable":["<1.3.2"]}},
-      {"id":"npm:angular:20130621","severity":"medium","semver":{"vulnerable":["<=1.1.5"]}},
-      {"id":"npm:angular:20140909","severity":"high","semver":{"vulnerable":["<1.2.24 >=1.2.19"]}},
+      {"id":"npm:angular:20130621","severity":"medium","semver":{"vulnerable":["<1.2.0"]}},
+      {"id":"npm:angular:20140909","severity":"high","semver":{"vulnerable":[">=1.2.19 <1.2.24"]}},
       {"id":"npm:angular:20130625","severity":"high","semver":{"vulnerable":["<1.1.5"]}}
     ],
     "backbone":[
@@ -36,9 +39,11 @@
       {"id":"npm:bootstrap:20120510","severity":"medium","semver":{"vulnerable":["<2.1.0"]}}
     ],
     "dojo":[
+      {"id":"SNYK-JS-DOJO-174934","severity":"medium","semver":{"vulnerable":[">=1.0.0 <1.0.3",">=1.1.0 <1.1.2",">=1.2.0 <1.2.4",">=1.3.0 <1.3.3",">=1.4.0 <1.4.2"]}},
+      {"id":"SNYK-JS-DOJO-174933","severity":"medium","semver":{"vulnerable":["<1.2.0"]}},
       {"id":"SNYK-JS-DOJO-72305","severity":"medium","semver":{"vulnerable":["<1.14"]}},
       {"id":"npm:dojo:20180818","severity":"medium","semver":{"vulnerable":["<1.10.10 || >=1.11.0 <1.11.6 || >=1.12.0 <1.12.4 || >=1.13.0 <1.13.1"]}},
-      {"id":"npm:dojo:20160523","severity":"medium","semver":{"vulnerable":["<= 1.0.0"]}},
+      {"id":"npm:dojo:20160523","severity":"medium","semver":{"vulnerable":["<1.1.0"]}},
       {"id":"npm:dojo:20100614-6","severity":"medium","semver":{"vulnerable":["<1.4.2"]}},
       {"id":"npm:dojo:20100614","severity":"high","semver":{"vulnerable":[">=0.4 <0.4.4 || >=1.0 <1.0.3 || >=1.1 <1.1.2 || >=1.2 <1.2.4 || >=1.3 <1.3.3 || >=1.4 <1.4.2"]}},
       {"id":"npm:dojo:20090409","severity":"medium","semver":{"vulnerable":["<1.1"]}}
@@ -48,8 +53,12 @@
       {"id":"npm:foundation-sites:20150619","severity":"medium","semver":{"vulnerable":["<5.5.3"]}},
       {"id":"npm:foundation-sites:20120717","severity":"medium","semver":{"vulnerable":["<3.0.6 >=3.0.0"]}}
     ],
+    "google-closure-library":[
+      {"id":"SNYK-JS-GOOGLECLOSURELIBRARY-174519","severity":"medium","semver":{"vulnerable":[">=20190121.0.0 <20190301.0.0"]}}
+    ],
     "handlebars":[
-      {"id":"SNYK-JS-HANDLEBARS-174183","severity":"high","semver":{"vulnerable":[">=4.1.0 <4.1.2","<4.0.14"]}},
+      {"id":"SNYK-JS-HANDLEBARS-469063","severity":"high","semver":{"vulnerable":["<4.3.0"]}},
+      {"id":"SNYK-JS-HANDLEBARS-174183","severity":"high","semver":{"vulnerable":["<3.0.7",">=4.1.0 <4.1.2","<4.0.14"]}},
       {"id":"SNYK-JS-HANDLEBARS-173692","severity":"high","semver":{"vulnerable":["<4.0.13"]}},
       {"id":"npm:handlebars:20151207","severity":"medium","semver":{"vulnerable":["<4.0.0"]}},
       {"id":"npm:handlebars:20110425","severity":"medium","semver":{"vulnerable":["<=1.0.0-beta.3"]}}
@@ -59,25 +68,27 @@
     ],
     "jquery":[
       {"id":"SNYK-JS-JQUERY-174006","severity":"medium","semver":{"vulnerable":["<3.4.0"]}},
-      {"id":"npm:jquery:20160529","severity":"low","semver":{"vulnerable":["=3.0.0-rc1"]}},
+      {"id":"npm:jquery:20160529","severity":"low","semver":{"vulnerable":[">=3.0.0-rc1 <3.0.0"]}},
       {"id":"npm:jquery:20150627","severity":"medium","semver":{"vulnerable":["<1.12.2",">=1.12.3 <2.2.2",">=2.2.3 <3.0.0"]}},
       {"id":"npm:jquery:20140902","severity":"medium","semver":{"vulnerable":[">=1.4.2 <1.6.2"]}},
       {"id":"npm:jquery:20120206","severity":"medium","semver":{"vulnerable":[">=1.7.1 <1.9.0"]}},
       {"id":"npm:jquery:20110606","severity":"medium","semver":{"vulnerable":["<1.6.3"]}}
     ],
     "jquery-mobile":[
+      {"id":"SNYK-JS-JQUERYMOBILE-174599","severity":"medium","semver":{"vulnerable":["<=1.5.0-alpha.1"]}},
       {"id":"npm:jquery-mobile:20120802","severity":"medium","semver":{"vulnerable":["<1.2.0"]}}
     ],
     "jquery-ui":[
       {"id":"npm:jquery-ui:20121127","severity":"medium","semver":{"vulnerable":["<1.10.0"]}},
       {"id":"npm:jquery-ui:20100903","severity":"medium","semver":{"vulnerable":["<1.10.0"]}},
-      {"id":"npm:jquery-ui:20160721","severity":"high","semver":{"vulnerable":["<=1.11.4"]}}
+      {"id":"npm:jquery-ui:20160721","severity":"high","semver":{"vulnerable":["<1.12.0"]}}
     ],
     "knockout":[
       {"id":"npm:knockout:20180213","severity":"medium","semver":{"vulnerable":["<3.5.0-beta"]}},
       {"id":"npm:knockout:20130701","severity":"medium","semver":{"vulnerable":["<3.0.0 >=2.1.0-pre"]}}
     ],
     "lodash":[
+      {"id":"SNYK-JS-LODASH-450202","severity":"high","semver":{"vulnerable":["<4.17.12"]}},
       {"id":"SNYK-JS-LODASH-73639","severity":"medium","semver":{"vulnerable":["<4.17.11"]}},
       {"id":"SNYK-JS-LODASH-73638","severity":"high","semver":{"vulnerable":["<4.17.11"]}},
       {"id":"npm:lodash:20180130","severity":"medium","semver":{"vulnerable":["<4.17.5"]}}
@@ -85,7 +96,7 @@
     "moment":[
       {"id":"npm:moment:20170905","severity":"low","semver":{"vulnerable":["<2.19.3"]}},
       {"id":"npm:moment:20161019","severity":"medium","semver":{"vulnerable":["<2.15.2"]}},
-      {"id":"npm:moment:20160126","severity":"medium","semver":{"vulnerable":["<=2.11.1"]}}
+      {"id":"npm:moment:20160126","severity":"medium","semver":{"vulnerable":["<2.11.2"]}}
     ],
     "mustache":[
       {"id":"npm:mustache:20151207","severity":"medium","semver":{"vulnerable":["<2.2.1"]}},
@@ -106,7 +117,7 @@
       {"id":"npm:vue:20170829","severity":"medium","semver":{"vulnerable":["<2.4.3"]}},
       {"id":"npm:vue:20170401","severity":"medium","semver":{"vulnerable":["<2.3.0-beta.1"]}},
       {"id":"npm:vue:20180802","severity":"medium","semver":{"vulnerable":["<2.5.17"]}},
-      {"id":"npm:vue:20180222","severity":"low","semver":{"vulnerable":["<=2.5.14"]}}
+      {"id":"npm:vue:20180222","severity":"low","semver":{"vulnerable":["<2.5.14"]}}
     ],
     "yui":[
       {"id":"npm:yui:20130604","severity":"medium","semver":{"vulnerable":[">=3.0.0 <3.10.1 || =3.10.2"]}},
diff --git a/types/artifacts.d.ts b/types/artifacts.d.ts
index a97a30d09..a3ff14433 100644
--- a/types/artifacts.d.ts
+++ b/types/artifacts.d.ts
@@ -217,7 +217,7 @@ declare global {
         /** The `as` attribute of the link */
         as: string
         /** The `crossOrigin` attribute of the link */
-        crossOrigin: 'anonymous'|'use-credentials'|null
+        crossOrigin: string | null
         /** Where the link was found, either in the DOM or in the headers of the main document */
         source: 'head'|'body'|'headers'
       }
diff --git a/types/smokehouse.d.ts b/types/smokehouse.d.ts
index aff855384..a512b481d 100644
--- a/types/smokehouse.d.ts
+++ b/types/smokehouse.d.ts
@@ -19,17 +19,26 @@
     diff?: Difference | null;
   }
 
-  export type ExpectedLHR = Pick<LH.Result, 'audits' | 'finalUrl' | 'requestedUrl' | 'runWarnings' | 'runtimeError'>
+  interface ExpectedLHR {
+    audits: Record<string, any>;
+    requestedUrl: string;
+    finalUrl: string;
+    runWarnings?: Array<string>;
+    runtimeError?: {
+      code?: any;
+      message?: any;
+    };
+  }
 
   export type ExpectedRunnerResult = {
     lhr: ExpectedLHR,
-    artifacts?: Partial<LH.Artifacts>
+    artifacts?: Partial<Record<keyof LH.Artifacts, any>>
   }
 
   export interface TestDfn {
     id: string;
-    expectations: string;
-    config: string;
+    expectations: ExpectedRunnerResult[];
+    config: LH.Config.Json;
     batch: string;
   }
 }


Test patch:
diff --git a/lighthouse-cli/test/fixtures/dobetterweb/dbw_tester.html b/lighthouse-cli/test/fixtures/dobetterweb/dbw_tester.html
index 308d9eb04..0ab54e3eb 100644
--- a/lighthouse-cli/test/fixtures/dobetterweb/dbw_tester.html
+++ b/lighthouse-cli/test/fixtures/dobetterweb/dbw_tester.html
@@ -149,6 +149,13 @@
 <div>
   <h2>Do better web tester page</h2>
   <span>Hi there!</span>
+
+  <!-- Invalid SVG with a link just to ensure the `LinkElements` gatherer can handle it. -->
+  <svg role="img" class="social-facebook" aria-labelledby="social-facebook-5">
+    <title id="social-facebook-5">Facebook</title>
+    <link rel="preload" href="https://fonts.googleapis.com/made-up-url"></link>
+    <use xlink:href=""></use>
+  </svg>
 </div>
 
 <section id="touchmove-section">touchmove section</section>
diff --git a/lighthouse-cli/test/smokehouse/a11y/expectations.js b/lighthouse-cli/test/smokehouse/a11y/expectations.js
index d8692e30e..9c84cf5c3 100644
--- a/lighthouse-cli/test/smokehouse/a11y/expectations.js
+++ b/lighthouse-cli/test/smokehouse/a11y/expectations.js
@@ -8,9 +8,10 @@
 /* eslint-disable max-len */
 
 /**
+ * @type {Array<Smokehouse.ExpectedRunnerResult>}
  * Expected Lighthouse audit values for byte efficiency tests
  */
-module.exports = [
+const expectations = [
   {
     lhr: {
       requestedUrl: 'http://localhost:10200/a11y/a11y_tester.html',
@@ -462,3 +463,5 @@ module.exports = [
     },
   },
 ];
+
+module.exports = expectations;
diff --git a/lighthouse-cli/test/smokehouse/byte-config.js b/lighthouse-cli/test/smokehouse/byte-config.js
index d3b2977e4..e41d5136f 100644
--- a/lighthouse-cli/test/smokehouse/byte-config.js
+++ b/lighthouse-cli/test/smokehouse/byte-config.js
@@ -6,9 +6,10 @@
 'use strict';
 
 /**
+ * @type {LH.Config.Json}
  * Config file for running byte efficiency smokehouse audits.
  */
-module.exports = {
+const config = {
   extends: 'lighthouse:full',
   settings: {
     onlyAudits: [
@@ -27,3 +28,5 @@ module.exports = {
     throttlingMethod: 'devtools',
   },
 };
+
+module.exports = config;
diff --git a/lighthouse-cli/test/smokehouse/byte-efficiency/expectations.js b/lighthouse-cli/test/smokehouse/byte-efficiency/expectations.js
index 722090bc0..990fd774f 100644
--- a/lighthouse-cli/test/smokehouse/byte-efficiency/expectations.js
+++ b/lighthouse-cli/test/smokehouse/byte-efficiency/expectations.js
@@ -6,9 +6,10 @@
 'use strict';
 
 /**
+ * @type {Array<Smokehouse.ExpectedRunnerResult>}
  * Expected Lighthouse audit values for byte efficiency tests
  */
-module.exports = [
+const expectations = [
   {
     lhr: {
       requestedUrl: 'http://localhost:10200/byte-efficiency/tester.html',
@@ -150,3 +151,5 @@ module.exports = [
     },
   },
 ];
+
+module.exports = expectations;
diff --git a/lighthouse-cli/test/smokehouse/dbw-config.js b/lighthouse-cli/test/smokehouse/dbw-config.js
index 7226e3f3e..c4f87d835 100644
--- a/lighthouse-cli/test/smokehouse/dbw-config.js
+++ b/lighthouse-cli/test/smokehouse/dbw-config.js
@@ -19,6 +19,7 @@ module.exports = {
       'render-blocking-resources',
       'errors-in-console',
       'efficient-animated-content',
+      'apple-touch-icon', // pull in apple touch icon to test `LinkElements`
     ],
   },
 };
diff --git a/lighthouse-cli/test/smokehouse/dobetterweb/dbw-expectations.js b/lighthouse-cli/test/smokehouse/dobetterweb/dbw-expectations.js
index d04756bba..20a5f71d6 100644
--- a/lighthouse-cli/test/smokehouse/dobetterweb/dbw-expectations.js
+++ b/lighthouse-cli/test/smokehouse/dobetterweb/dbw-expectations.js
@@ -6,9 +6,10 @@
 'use strict';
 
 /**
+ * @type {Array<Smokehouse.ExpectedRunnerResult>}
  * Expected Lighthouse audit values for Do Better Web tests.
  */
-module.exports = [
+const expectations = [
   {
     artifacts: {
       Stacks: [{
@@ -16,6 +17,107 @@ module.exports = [
       }, {
         id: 'wordpress',
       }],
+      LinkElements: [
+        {
+          rel: 'stylesheet',
+          href: 'http://localhost:10200/dobetterweb/dbw_tester.css?delay=100',
+          hrefRaw: 'http://localhost:10200/dobetterweb/dbw_tester.css?delay=100',
+          hreflang: '',
+          as: '',
+          crossOrigin: null,
+          source: 'head',
+        },
+        {
+          rel: 'stylesheet',
+          href: 'http://localhost:10200/dobetterweb/unknown404.css?delay=200',
+          hrefRaw: 'http://localhost:10200/dobetterweb/unknown404.css?delay=200',
+          hreflang: '',
+          as: '',
+          crossOrigin: null,
+          source: 'head',
+        },
+        {
+          rel: 'stylesheet',
+          href: 'http://localhost:10200/dobetterweb/dbw_tester.css?delay=2200',
+          hrefRaw: 'http://localhost:10200/dobetterweb/dbw_tester.css?delay=2200',
+          hreflang: '',
+          as: '',
+          crossOrigin: null,
+          source: 'head',
+        },
+        {
+          rel: 'stylesheet',
+          href: 'http://localhost:10200/dobetterweb/dbw_disabled.css?delay=200&isdisabled',
+          hrefRaw: 'http://localhost:10200/dobetterweb/dbw_disabled.css?delay=200&isdisabled',
+          hreflang: '',
+          as: '',
+          crossOrigin: null,
+          source: 'head',
+        },
+        {
+          rel: 'import',
+          href: 'http://localhost:10200/dobetterweb/dbw_partial_a.html?delay=200',
+          hrefRaw: 'http://localhost:10200/dobetterweb/dbw_partial_a.html?delay=200',
+          hreflang: '',
+          as: '',
+          crossOrigin: null,
+          source: 'head',
+        },
+        {
+          rel: 'import',
+          href: 'http://localhost:10200/dobetterweb/dbw_partial_b.html?delay=200&isasync',
+          hrefRaw: 'http://localhost:10200/dobetterweb/dbw_partial_b.html?delay=200&isasync',
+          hreflang: '',
+          as: '',
+          crossOrigin: null,
+          source: 'head',
+        },
+        {
+          rel: 'stylesheet',
+          href: 'http://localhost:10200/dobetterweb/dbw_tester.css?delay=3000&capped',
+          hrefRaw: 'http://localhost:10200/dobetterweb/dbw_tester.css?delay=3000&capped',
+          hreflang: '',
+          as: '',
+          crossOrigin: null,
+          source: 'head',
+        },
+        {
+          rel: 'stylesheet',
+          href: 'http://localhost:10200/dobetterweb/dbw_tester.css?delay=2000&async=true',
+          hrefRaw: 'http://localhost:10200/dobetterweb/dbw_tester.css?delay=2000&async=true',
+          hreflang: '',
+          as: 'style',
+          crossOrigin: null,
+          source: 'head',
+        },
+        {
+          rel: 'stylesheet',
+          href: 'http://localhost:10200/dobetterweb/dbw_tester.css?delay=3000&async=true',
+          hrefRaw: 'http://localhost:10200/dobetterweb/dbw_tester.css?delay=3000&async=true',
+          hreflang: '',
+          as: '',
+          crossOrigin: null,
+          source: 'head',
+        },
+        {
+          rel: 'alternate stylesheet',
+          href: 'http://localhost:10200/dobetterweb/empty.css',
+          hrefRaw: 'http://localhost:10200/dobetterweb/empty.css',
+          hreflang: '',
+          as: '',
+          crossOrigin: null,
+          source: 'head',
+        },
+        {
+          rel: 'stylesheet',
+          href: 'http://localhost:10200/dobetterweb/dbw_tester.css?scriptActivated&delay=200',
+          hrefRaw: 'http://localhost:10200/dobetterweb/dbw_tester.css?scriptActivated&delay=200',
+          hreflang: '',
+          as: '',
+          crossOrigin: null,
+          source: 'head',
+        },
+      ],
       TagsBlockingFirstPaint: [
         {
           tag: {
@@ -261,11 +363,11 @@ module.exports = [
         },
         'dom-size': {
           score: 1,
-          numericValue: 137,
+          numericValue: 141,
           details: {
             items: [
-              {statistic: 'Total DOM Elements', value: '137'},
-              {statistic: 'Maximum DOM Depth', value: '3'},
+              {statistic: 'Total DOM Elements', value: '141'},
+              {statistic: 'Maximum DOM Depth', value: '4'},
               {
                 statistic: 'Maximum Child Elements',
                 value: '100',
@@ -278,3 +380,5 @@ module.exports = [
     },
   },
 ];
+
+module.exports = expectations;
diff --git a/lighthouse-cli/test/smokehouse/error-expectations.js b/lighthouse-cli/test/smokehouse/error-expectations.js
index b462fd665..586f60a85 100644
--- a/lighthouse-cli/test/smokehouse/error-expectations.js
+++ b/lighthouse-cli/test/smokehouse/error-expectations.js
@@ -12,9 +12,10 @@ const NONEMPTY_ARRAY = {
 };
 
 /**
+ * @type {Array<Smokehouse.ExpectedRunnerResult>}
  * Expected Lighthouse audit values for sites with various errors.
  */
-module.exports = [
+const expectations = [
   {
     lhr: {
       requestedUrl: 'http://localhost:10200/infinite-loop.html',
@@ -84,3 +85,5 @@ module.exports = [
     },
   },
 ];
+
+module.exports = expectations;
diff --git a/lighthouse-cli/test/smokehouse/perf/expectations.js b/lighthouse-cli/test/smokehouse/perf/expectations.js
index 4ea41b4d5..0ca81582e 100644
--- a/lighthouse-cli/test/smokehouse/perf/expectations.js
+++ b/lighthouse-cli/test/smokehouse/perf/expectations.js
@@ -6,6 +6,7 @@
 'use strict';
 
 /**
+ * @type {Array<Smokehouse.ExpectedRunnerResult>}
  * Expected Lighthouse audit values for perf tests.
  */
 module.exports = [
diff --git a/lighthouse-cli/test/smokehouse/perf/lantern-expectations.js b/lighthouse-cli/test/smokehouse/perf/lantern-expectations.js
index 64b1ebc9f..e6ce9e2d6 100644
--- a/lighthouse-cli/test/smokehouse/perf/lantern-expectations.js
+++ b/lighthouse-cli/test/smokehouse/perf/lantern-expectations.js
@@ -6,6 +6,7 @@
 'use strict';
 
 /**
+ * @type {Array<Smokehouse.ExpectedRunnerResult>}
  * Expected Lighthouse audit values for lantern smoketests
  */
 module.exports = [
diff --git a/lighthouse-cli/test/smokehouse/redirects/expectations.js b/lighthouse-cli/test/smokehouse/redirects/expectations.js
index 6abd8c746..06b66ac63 100644
--- a/lighthouse-cli/test/smokehouse/redirects/expectations.js
+++ b/lighthouse-cli/test/smokehouse/redirects/expectations.js
@@ -5,12 +5,13 @@
  */
 'use strict';
 
+const cacheBuster = Number(new Date());
+
 /**
+ * @type {Array<Smokehouse.ExpectedRunnerResult>}
  * Expected Lighthouse audit values for redirects tests
  */
-const cacheBuster = Number(new Date());
-
-module.exports = [
+const expectations = [
   {
     lhr: {
       requestedUrl: `http://localhost:10200/online-only.html?delay=500&redirect=%2Foffline-only.html%3Fcb=${cacheBuster}%26delay=500%26redirect%3D%2Fredirects-final.html`,
@@ -46,3 +47,5 @@ module.exports = [
     },
   },
 ];
+
+module.exports = expectations;
diff --git a/lighthouse-cli/test/smokehouse/run-smoke.js b/lighthouse-cli/test/smokehouse/run-smoke.js
index f82e27d64..874d2fd5d 100644
--- a/lighthouse-cli/test/smokehouse/run-smoke.js
+++ b/lighthouse-cli/test/smokehouse/run-smoke.js
@@ -14,7 +14,7 @@ const log = require('lighthouse-logger');
 
 /** @param {string} str */
 const purpleify = str => `${log.purple}${str}${log.reset}`;
-const SMOKETESTS = require('./smoke-test-dfns.js').SMOKE_TEST_DFNS;
+const smokeTests = require('./smoke-test-dfns.js');
 
 /**
  * Display smokehouse output from child process
@@ -33,20 +33,19 @@ function displaySmokehouseOutput(result) {
 }
 
 /**
- * Run smokehouse in child processes for selected smoketests
+ * Run smokehouse in child processes for the selected smoke tests
  * Display output from each as soon as they finish, but resolve function when ALL are complete
- * @param {Array<Smokehouse.TestDfn>} smokes
+ * @param {Array<Smokehouse.TestDfn>} smokeTests
  * @return {Promise<Array<{id: string, error?: Error}>>}
  */
-async function runSmokehouse(smokes) {
+async function runSmokehouse(smokeTests) {
   const cmdPromises = [];
-  for (const {id, expectations, config} of smokes) {
+  for (const {id} of smokeTests) {
     console.log(`${purpleify(id)} smoketest starting…`);
     console.time(`smoketest-${id}`);
     const cmd = [
       'node lighthouse-cli/test/smokehouse/smokehouse.js',
-      `--config-path=${config}`,
-      `--expectations-path=${expectations}`,
+      `--smoke-id=${id}`,
     ].join(' ');
 
     // The promise ensures we output immediately, even if the process errors
@@ -72,18 +71,18 @@ async function runSmokehouse(smokes) {
  */
 function getSmoketestBatches(argv) {
   let smokes = [];
-  const usage = `    ${log.dim}yarn smoke ${SMOKETESTS.map(t => t.id).join(' ')}${log.reset}\n`;
+  const usage = `    ${log.dim}yarn smoke ${smokeTests.map(t => t.id).join(' ')}${log.reset}\n`;
 
   if (argv.length === 0) {
-    smokes = SMOKETESTS;
+    smokes = smokeTests;
     console.log('Running ALL smoketests. Equivalent to:');
     console.log(usage);
   } else {
-    smokes = SMOKETESTS.filter(test => argv.includes(test.id));
+    smokes = smokeTests.filter(test => argv.includes(test.id));
     console.log(`Running ONLY smoketests for: ${smokes.map(t => t.id).join(' ')}\n`);
   }
 
-  const unmatchedIds = argv.filter(requestedId => !SMOKETESTS.map(t => t.id).includes(requestedId));
+  const unmatchedIds = argv.filter(requestedId => !smokeTests.map(t => t.id).includes(requestedId));
   if (unmatchedIds.length) {
     console.log(log.redify(`Smoketests not found for: ${unmatchedIds.join(' ')}`));
     console.log(usage);
diff --git a/lighthouse-cli/test/smokehouse/seo/expectations.js b/lighthouse-cli/test/smokehouse/seo/expectations.js
index 18c66eef5..1ecc918b4 100644
--- a/lighthouse-cli/test/smokehouse/seo/expectations.js
+++ b/lighthouse-cli/test/smokehouse/seo/expectations.js
@@ -4,8 +4,8 @@
  * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
  */
 'use strict';
+
 const BASE_URL = 'http://localhost:10200/seo/';
-const URLSearchParams = require('url').URLSearchParams;
 
 /**
  * @param {[string, string][]} headers
@@ -94,9 +94,10 @@ const passHeaders = headersParam([[
 ]]);
 
 /**
+ * @type {Array<Smokehouse.ExpectedRunnerResult>}
  * Expected Lighthouse audit values for seo tests
  */
-module.exports = [
+const expectations = [
   {
     lhr: {
       requestedUrl: BASE_URL + 'seo-tester.html?' + passHeaders,
@@ -392,3 +393,5 @@ module.exports = [
     },
   },
 ];
+
+module.exports = expectations;
diff --git a/lighthouse-cli/test/smokehouse/smoke-test-dfns.js b/lighthouse-cli/test/smokehouse/smoke-test-dfns.js
index c12b14fcd..f5db176d9 100644
--- a/lighthouse-cli/test/smokehouse/smoke-test-dfns.js
+++ b/lighthouse-cli/test/smokehouse/smoke-test-dfns.js
@@ -5,129 +5,77 @@
  */
 'use strict';
 
-const path = require('path');
-const smokehouseDir = 'lighthouse-cli/test/smokehouse/';
-
 /** @type {Array<Smokehouse.TestDfn>} */
-const SMOKE_TEST_DFNS = [{
+const smokeTests = [{
   id: 'a11y',
-  config: smokehouseDir + 'a11y/a11y-config.js',
-  expectations: 'a11y/expectations.js',
+  expectations: require('./a11y/expectations.js'),
+  config: require('./a11y/a11y-config.js'),
   batch: 'parallel-first',
 }, {
   id: 'errors',
-  expectations: smokehouseDir + 'error-expectations.js',
-  config: smokehouseDir + 'error-config.js',
+  expectations: require('./error-expectations.js'),
+  config: require('./error-config.js'),
   batch: 'errors',
 }, {
   id: 'oopif',
-  expectations: smokehouseDir + 'oopif-expectations.js',
-  config: smokehouseDir + 'oopif-config.js',
+  expectations: require('./oopif-expectations.js'),
+  config: require('./oopif-config.js'),
   batch: 'parallel-first',
 }, {
   id: 'pwa',
-  expectations: smokehouseDir + 'pwa-expectations.js',
-  config: smokehouseDir + 'pwa-config.js',
+  expectations: require('./pwa-expectations.js'),
+  config: require('./pwa-config.js'),
   batch: 'parallel-second',
 }, {
   id: 'pwa2',
-  expectations: smokehouseDir + 'pwa2-expectations.js',
-  config: smokehouseDir + 'pwa-config.js',
+  expectations: require('./pwa2-expectations.js'),
+  config: require('./pwa-config.js'),
   batch: 'parallel-second',
 }, {
   id: 'pwa3',
-  expectations: smokehouseDir + 'pwa3-expectations.js',
-  config: smokehouseDir + 'pwa-config.js',
+  expectations: require('./pwa3-expectations.js'),
+  config: require('./pwa-config.js'),
   batch: 'parallel-first',
 }, {
   id: 'dbw',
-  expectations: 'dobetterweb/dbw-expectations.js',
-  config: smokehouseDir + 'dbw-config.js',
+  expectations: require('./dobetterweb/dbw-expectations.js'),
+  config: require('./dbw-config.js'),
   batch: 'parallel-second',
 }, {
   id: 'redirects',
-  expectations: 'redirects/expectations.js',
-  config: smokehouseDir + 'redirects-config.js',
+  expectations: require('./redirects/expectations.js'),
+  config: require('./redirects-config.js'),
   batch: 'parallel-first',
 }, {
   id: 'seo',
-  expectations: 'seo/expectations.js',
-  config: smokehouseDir + 'seo-config.js',
+  expectations: require('./seo/expectations.js'),
+  config: require('./seo-config.js'),
   batch: 'parallel-first',
 }, {
   id: 'offline',
-  expectations: 'offline-local/offline-expectations.js',
-  config: smokehouseDir + 'offline-config.js',
+  expectations: require('./offline-local/offline-expectations.js'),
+  config: require('./offline-config.js'),
   batch: 'offline',
 }, {
   id: 'byte',
-  expectations: 'byte-efficiency/expectations.js',
-  config: smokehouseDir + 'byte-config.js',
+  expectations: require('./byte-efficiency/expectations.js'),
+  config: require('./byte-config.js'),
   batch: 'perf-opportunity',
 }, {
   id: 'perf',
-  expectations: 'perf/expectations.js',
-  config: 'perf/perf-config.js',
+  expectations: require('./perf/expectations.js'),
+  config: require('./perf/perf-config.js'),
   batch: 'perf-metric',
 }, {
   id: 'lantern',
-  expectations: 'perf/lantern-expectations.js',
-  config: smokehouseDir + 'lantern-config.js',
+  expectations: require('./perf/lantern-expectations.js'),
+  config: require('./lantern-config.js'),
   batch: 'parallel-first',
 }, {
   id: 'metrics',
-  expectations: 'tricky-metrics/expectations.js',
-  config: 'lighthouse-core/config/perf-config.js',
+  expectations: require('./tricky-metrics/expectations.js'),
+  config: require('../../../lighthouse-core/config/perf-config.js'),
   batch: 'parallel-second',
 }];
 
-/**
- * Attempt to resolve a path relative to the smokehouse folder.
- * If this fails, attempts to locate the path
- * relative to the project root.
- * @param {string} payloadPath
- * @return {string}
- */
-function resolveLocalOrProjectRoot(payloadPath) {
-  let resolved;
-  try {
-    resolved = require.resolve(__dirname + '/' + payloadPath);
-  } catch (e) {
-    const cwdPath = path.resolve(__dirname + '/../../../', payloadPath);
-    resolved = require.resolve(cwdPath);
-  }
-
-  return resolved;
-}
-
-/**
- * @param {string} configPath
- * @return {LH.Config.Json}
- */
-function loadConfig(configPath) {
-  return require(configPath);
-}
-
-/**
- * @param {string} expectationsPath
- * @return {Smokehouse.ExpectedRunnerResult[]}
- */
-function loadExpectations(expectationsPath) {
-  return require(expectationsPath);
-}
-
-function getSmokeTests() {
-  return SMOKE_TEST_DFNS.map(smokeTestDfn => {
-    return {
-      id: smokeTestDfn.id,
-      config: loadConfig(resolveLocalOrProjectRoot(smokeTestDfn.config)),
-      expectations: loadExpectations(resolveLocalOrProjectRoot(smokeTestDfn.expectations)),
-      batch: smokeTestDfn.batch,
-    };
-  });
-}
-
-module.exports = {
-  SMOKE_TEST_DFNS,
-  getSmokeTests,
-};
+module.exports = smokeTests;
diff --git a/lighthouse-cli/test/smokehouse/smokehouse.js b/lighthouse-cli/test/smokehouse/smokehouse.js
index c39b4f481..f133da828 100755
--- a/lighthouse-cli/test/smokehouse/smokehouse.js
+++ b/lighthouse-cli/test/smokehouse/smokehouse.js
@@ -9,7 +9,6 @@
 /* eslint-disable no-console */
 
 const fs = require('fs');
-const path = require('path');
 const spawnSync = require('child_process').spawnSync;
 const yargs = require('yargs');
 const log = require('lighthouse-logger');
@@ -21,24 +20,6 @@ const assetSaver = require('../../../lighthouse-core/lib/asset-saver.js');
 const PROTOCOL_TIMEOUT_EXIT_CODE = 67;
 const RETRIES = 3;
 
-/**
- * Attempt to resolve a path locally. If this fails, attempts to locate the path
- * relative to the current working directory.
- * @param {string} payloadPath
- * @return {string}
- */
-function resolveLocalOrCwd(payloadPath) {
-  let resolved;
-  try {
-    resolved = require.resolve('./' + payloadPath);
-  } catch (e) {
-    const cwdPath = path.resolve(process.cwd(), payloadPath);
-    resolved = require.resolve(cwdPath);
-  }
-
-  return resolved;
-}
-
 /**
  * Launch Chrome and do a full Lighthouse run.
  * @param {string} url
@@ -129,23 +110,28 @@ function runLighthouse(url, configPath, isDebug) {
 const cli = yargs
   .help('help')
   .describe({
-    'config-path': 'The path to the config JSON file',
-    'expectations-path': 'The path to the expected audit results file',
+    'smoke-id': 'The id of the smoke test to run',
     'debug': 'Save the artifacts along with the output',
   })
-  .require('config-path', true)
-  .require('expectations-path', true)
+  .require('smoke-id', true)
   .argv;
 
-const configPath = resolveLocalOrCwd(cli['config-path']);
-/** @type {Smokehouse.ExpectedRunnerResult[]} */
-const expectations = require(resolveLocalOrCwd(cli['expectations-path']));
+const smokeId = cli['smoke-id'];
+const smokeTest = require('./smoke-test-dfns.js').find(smoke => smoke.id === smokeId);
+
+if (!smokeTest) {
+  process.exit(1);
+  throw new Error(`could not find smoke ${smokeId}`);
+}
+
+const configPath = `./.tmp/smoke-config-${smokeTest.id}.json`;
+fs.writeFileSync(configPath, JSON.stringify(smokeTest.config));
 
 // Loop sequentially over expectations, comparing against Lighthouse run, and
 // reporting result.
 let passingCount = 0;
 let failingCount = 0;
-expectations.forEach(expected => {
+smokeTest.expectations.forEach(expected => {
   console.log(`Doing a run of '${expected.lhr.requestedUrl}'...`);
   const results = runLighthouse(expected.lhr.requestedUrl, configPath, cli.debug);
 
diff --git a/lighthouse-cli/test/smokehouse/tricky-metrics/expectations.js b/lighthouse-cli/test/smokehouse/tricky-metrics/expectations.js
index 1aafb8e72..730f0cd97 100644
--- a/lighthouse-cli/test/smokehouse/tricky-metrics/expectations.js
+++ b/lighthouse-cli/test/smokehouse/tricky-metrics/expectations.js
@@ -6,6 +6,7 @@
 'use strict';
 
 /**
+ * @type {Array<Smokehouse.ExpectedRunnerResult>}
  * Expected Lighthouse audit values for tricky metrics tests
  */
 module.exports = [
diff --git a/lighthouse-core/scripts/release/test.sh b/lighthouse-core/scripts/release/test.sh
index fb568567c..7ca22095f 100755
--- a/lighthouse-core/scripts/release/test.sh
+++ b/lighthouse-core/scripts/release/test.sh
@@ -23,9 +23,6 @@ yarn build-all
 echo "Running the standard test suite..."
 yarn test
 
-echo "Running the smoke tests...."
-yarn smoke || yarn smoke || yarn smoke
-
 echo "Testing the CLI..."
 yarn start "https://example.com" --view
 
@@ -39,7 +36,7 @@ cd /tmp/lighthouse-local-test
 
 npm init -y
 npm install "$LH_PRISTINE_ROOT/lighthouse-$VERSION.tgz"
-npm explore lighthouse -- npm run smoke
+npm explore lighthouse -- npm run smoke || npm explore lighthouse -- npm run smoke
 npm explore lighthouse -- npm run chrome # try the manual launcher
 npm explore lighthouse -- npm run fast -- http://example.com
 
diff --git a/lighthouse-core/test/lib/tracehouse/main-thread-tasks-test.js b/lighthouse-core/test/lib/tracehouse/main-thread-tasks-test.js
index a4a28283c..ad8bd8b5f 100644
--- a/lighthouse-core/test/lib/tracehouse/main-thread-tasks-test.js
+++ b/lighthouse-core/test/lib/tracehouse/main-thread-tasks-test.js
@@ -99,6 +99,7 @@ describe('Main Thread Tasks', () => {
       duration: 100,
       selfTime: 50,
       group: taskGroups.other,
+      unbounded: false,
     });
 
     expect(taskB).toEqual({
@@ -112,6 +113,7 @@ describe('Main Thread Tasks', () => {
       duration: 50,
       selfTime: 20,
       group: taskGroups.other,
+      unbounded: false,
     });
   });
 
@@ -232,6 +234,7 @@ describe('Main Thread Tasks', () => {
       duration: 110,
       selfTime: 5,
       group: taskGroups.other,
+      unbounded: true,
     });
 
     expect(taskB).toEqual({
@@ -245,6 +248,7 @@ describe('Main Thread Tasks', () => {
       duration: 105,
       selfTime: 95,
       group: taskGroups.other,
+      unbounded: true,
     });
   });
 
@@ -362,6 +366,7 @@ describe('Main Thread Tasks', () => {
         duration: 100,
         selfTime: 50,
         group: taskGroups.other,
+        unbounded: false,
       },
       {
         parent: taskA,
@@ -374,6 +379,7 @@ describe('Main Thread Tasks', () => {
         duration: 50,
         selfTime: 50,
         group: taskGroups.other,
+        unbounded: false,
       },
     ]);
   });
@@ -406,6 +412,7 @@ describe('Main Thread Tasks', () => {
         duration: 100,
         selfTime: 100,
         group: taskGroups.other,
+        unbounded: false,
       },
       {
         parent: undefined,
@@ -418,6 +425,7 @@ describe('Main Thread Tasks', () => {
         duration: 0,
         selfTime: 0,
         group: taskGroups.other,
+        unbounded: false,
       },
     ]);
   });
@@ -452,6 +460,7 @@ describe('Main Thread Tasks', () => {
         duration: 100,
         selfTime: 25,
         group: taskGroups.other,
+        unbounded: false,
       },
       {
         parent: taskA,
@@ -464,10 +473,61 @@ describe('Main Thread Tasks', () => {
         duration: 75,
         selfTime: 75,
         group: taskGroups.other,
+        unbounded: false,
       },
     ]);
   });
 
+  it('should handle child events that extend >1ms beyond parent event because missing E', () => {
+    /*
+    An artistic rendering of the below trace:
+    ████████████████TaskA██████████████████
+            █████████TaskB██████████████████
+    */
+    const traceEvents = [
+      ...boilerplateTrace,
+      {ph: 'B', name: 'TaskA', pid, tid, ts: baseTs, args},
+      {ph: 'B', name: 'TaskB', pid, tid, ts: baseTs + 25e3, args},
+      {ph: 'E', name: 'TaskA', pid, tid, ts: baseTs + 100e3, args},
+      {ph: 'I', name: 'MarkerToPushOutTraceEnd', pid, tid, ts: baseTs + 110e3, args},
+    ];
+
+    traceEvents.forEach(evt => Object.assign(evt, {cat: 'devtools.timeline'}));
+
+    const tasks = run({traceEvents});
+    const [taskA, taskB] = tasks;
+    expect(tasks).toEqual([
+      {
+        parent: undefined,
+        attributableURLs: [],
+
+        children: [taskB],
+        event: traceEvents.find(event => event.name === 'TaskA'),
+        startTime: 0,
+        endTime: 100,
+        duration: 100,
+        selfTime: 25,
+        group: taskGroups.other,
+        unbounded: false,
+      },
+      {
+        parent: taskA,
+        attributableURLs: [],
+
+        children: [],
+        event: traceEvents.find(event => event.name === 'TaskB' && event.ph === 'B'),
+        startTime: 25,
+        endTime: 100,
+        duration: 75,
+        selfTime: 75,
+        group: taskGroups.other,
+        unbounded: true,
+      },
+    ]);
+  });
+
+  // Invalid sets of events.
+  // All of these should have `traceEnd` pushed out to avoid falling into one of our mitigation scenarios.
   const invalidEventSets = [
     [
       // TaskA overlaps with TaskB, X first
@@ -499,12 +559,6 @@ describe('Main Thread Tasks', () => {
       {ph: 'X', name: 'TaskA', pid, tid, ts: baseTs, dur: 100e3, args},
       {ph: 'E', name: 'TaskB', pid, tid, ts: baseTs + 10e3, args},
     ],
-    [
-      {ph: 'I', name: 'MarkerToPushOutTraceEnd', pid, tid, ts: baseTs + 110e3, args},
-      // TaskB is missing an E event within an X
-      {ph: 'X', name: 'TaskA', pid, tid, ts: baseTs, dur: 100e3, args},
-      {ph: 'B', name: 'TaskB', pid, tid, ts: baseTs + 10e3, args},
-    ],
   ];
 
   for (const invalidEvents of invalidEventSets) {
diff --git a/lighthouse-core/test/results/sample_v2.json b/lighthouse-core/test/results/sample_v2.json
index f40a3462d..c3ba3a1f9 100644
--- a/lighthouse-core/test/results/sample_v2.json
+++ b/lighthouse-core/test/results/sample_v2.json
@@ -5,7 +5,7 @@
     "hostUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3358.0 Safari/537.36",
     "benchmarkIndex": 1000
   },
-  "lighthouseVersion": "5.4.0",
+  "lighthouseVersion": "5.5.0",
   "fetchTime": "2018-03-13T00:55:45.840Z",
   "requestedUrl": "http://localhost:10200/dobetterweb/dbw_tester.html",
   "finalUrl": "http://localhost:10200/dobetterweb/dbw_tester.html",