Skip to content

Enable Speedometer to use an external config.json file #515

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: main
Choose a base branch
from

Conversation

flashdesignory
Copy link
Contributor

@flashdesignory flashdesignory commented Jun 2, 2025

This pr sets up Speedometer to use an optional config url param, to assign different workloads / tests to use with the benchmark.

The initial config.json enables the news site next workload, which is currently the only workload that opted into the postMessage api for it's experimental version. The test name in the config is optional, if the default tests are targeted.

The new `data-provider' checks an allowed list of external urls that the workloads can be pulled in from. Currently this just houses the netlify preview folder.

Other changes:
the suites and tags are not global anymore and the data-provider is the source of truth. This is to ensure that the data-provider can process the suites / tests, prior to running speedometer in any mode.

news-site dist folder changed, since I had to run the build again, after updating shared files from the benchmark.

Preview with config assigned:
https://deploy-preview-515--webkit-speedometer-preview.netlify.app/?config=https://deploy-preview-515--webkit-speedometer-preview.netlify.app/resources/config.json

Copy link

netlify bot commented Jun 2, 2025

Deploy Preview for webkit-speedometer-preview ready!

Name Link
🔨 Latest commit cb77ab0
🔍 Latest deploy log https://app.netlify.com/projects/webkit-speedometer-preview/deploys/683dffb1be71b0000882aa29
😎 Deploy Preview https://deploy-preview-515--webkit-speedometer-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Contributor

@julienw julienw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't test fully locally and I think I don't get the full picture yet, but here is a first set of comments.

function isValidJsonUrl(url) {
try {
return new URL(url) && url.toLowerCase().endsWith(".json");
} catch (_) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(optional) You can do this now:

Suggested change
} catch (_) {
} catch {

It's broadly supported.

return new URL(url) && url.toLowerCase().endsWith(".json");
} catch (_) {
return false;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the future we'll be able to use URL.parse but I think it's still a bit early.


_containsAllowedUrl(suite) {
// 1. Check for relative URL
if (!suite.url.startsWith("http://") && !suite.url.startsWith("https://") && !suite.url.startsWith("//") && !suite.url.startsWith("./")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good job checking for //. But I think we could reject this case at first, because it makes things more difficult and doesn't seem useful in this case.

Also I don't understand the last bit, why do you consider that ./ URLs are not relative?

Comment on lines +25 to +27
const parsedUrl = new URL(suite.url, baseUrl);
if (parsedUrl.origin === baseUrl)
return true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not clear to me why we need more checks than the first condition...
Or are you only checking that this is a proper URL?
If yes, it could be good to extract that bit to a separate function (like you did in params.mjs) such as isValidUrl, and we don't need to check the origin IMO.

return this._suites;
}

_containsAllowedUrl(suite) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: please add a comment explaining all the URLs we allow

});
const tagsSet = new Set(tags);
this._suites.forEach((suite) => {
suite.disabled = !suite.tags.some((tag) => tagsSet.has(tag));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe in a few months we'll be able to use Set's new methods for these sort of things, but it may be a bit too early.

} else {
console.warn("Neither names nor tags provided. Enabling all default suites.");
this._suites.forEach((suite) => {
suite.disabled = !("default" in suite.tags);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you want suite.tags.includes("default")?

export function createDeveloperModeContainer() {
let suites, tags;

export function createDeveloperModeContainer(_suites, _tags) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: usually prefixing with a _ means that it's unused.

You could call them aSuites and aTags...

import { renderMetricView } from "./metric-ui.mjs";
import { defaultParams, params } from "./shared/params.mjs";
import { createDeveloperModeContainer } from "./developer-mode.mjs";

const { dataProvider } = await import("../resources/data-provider.mjs");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like you use await here because you have the top level await in data-provider, but that's not necessary, I'd say to just use a static import.

see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await#top_level_await

Although we might want to avoid the top level await and instead have a promise we can wait for in the constructor below, or something like that.


constructor() {
window.addEventListener("DOMContentLoaded", () => this.prepareUI());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we're not waiting for DOMContentLoaded anymore?

Or is it because of the await above we're usually past this event... but this is racy so we should probably keep it but also check for document.readyState...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants