Skip to content
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

perf: reduce query selector #9437

Closed
wants to merge 1 commit into from

Conversation

gajus
Copy link
Contributor

@gajus gajus commented Jul 29, 2022

Description

Reduces use of unnecessary querySelector use.

Additional context

It is faster to read DOM once.


What is the purpose of this pull request?

  • Bug fix
  • New Feature
  • Documentation update
  • Other

Before submitting the PR, please make sure you do the following

  • Read the Contributing Guidelines.
  • Read the Pull Request Guidelines and follow the Commit Convention.
  • Check that there isn't already a PR that solves the problem the same way to avoid creating a duplicate.
  • Provide a description in this PR that addresses what the PR is solving, or reference the issue that it solves (e.g. fixes #123).
  • Ideally, include relevant tests that fail without this PR but pass with it.

@gajus
Copy link
Contributor Author

gajus commented Jul 29, 2022

Related, though I didn't want to add it to this PR, why is this being awaited in the first place?

I didn't try this, but it should be just:

-  return Promise.all(
-    deps.map((dep) => {
-      // @ts-ignore
-      dep = assetsURL(dep, importerUrl)
-      // @ts-ignore
-      if (dep in seen) return
-      // @ts-ignore
-      seen[dep] = true
-      const isCss = dep.endsWith('.css')
-      // @ts-ignore check if the file is already preloaded by SSR markup
-      if (documentLinkUrls.includes(dep)) {
-        return
-      }
-      // @ts-ignore
-      const link = document.createElement('link')
-      // @ts-ignore
-      link.rel = isCss ? 'stylesheet' : scriptRel
-      if (!isCss) {
-        link.as = 'script'
-        link.crossOrigin = ''
-      }
-      link.href = dep
-      // @ts-ignore
-      document.head.appendChild(link)
-      if (isCss) {
-        return new Promise((res, rej) => {
-          link.addEventListener('load', res)
-          link.addEventListener('error', () =>
-            rej(new Error(`Unable to preload CSS for ${dep}`))
-          )
-        })
-      }
-    })
-  ).then(() => baseModule())
+  for (const dep of deps) {
+    // @ts-ignore
+    dep = assetsURL(dep, importerUrl)
+    // @ts-ignore
+    if (dep in seen) return
+    // @ts-ignore
+    seen[dep] = true
+    const isCss = dep.endsWith('.css')
+    // @ts-ignore check if the file is already preloaded by SSR markup
+    if (documentLinkUrls.includes(dep)) {
+      return
+    }
+    // @ts-ignore
+    const link = document.createElement('link')
+    // @ts-ignore
+    link.rel = isCss ? 'stylesheet' : scriptRel
+    if (!isCss) {
+      link.as = 'script'
+      link.crossOrigin = ''
+    }
+    link.href = dep
+    // @ts-ignore
+    document.head.appendChild(link)
+  }
+
+  return baseModule();

Waiting for scripts to be actually loaded is not needed for any logic that follows, as far as I can tell.

@gajus
Copy link
Contributor Author

gajus commented Jul 29, 2022

Please re-run tests. It looks like it is a CI/CD failure.

@gajus
Copy link
Contributor Author

gajus commented Aug 1, 2022

@1yyx990803 @patak-dev can someone re-run tests?

@tony19
Copy link
Contributor

tony19 commented Aug 1, 2022

@gajus A couple notes about your proposed code below:

for (const dep of deps) {
  // @ts-ignore
  dep = assetsURL(dep, importerUrl)
  // @ts-ignore
  if (dep in seen) return
  // @ts-ignore
  seen[dep] = true
  const isCss = dep.endsWith('.css')
  // @ts-ignore check if the file is already preloaded by SSR markup
  if (documentLinkUrls.includes(dep)) {
    return
  }
  // @ts-ignore
  const link = document.createElement('link')
  // @ts-ignore
  link.rel = isCss ? 'stylesheet' : scriptRel
  if (!isCss) {
    link.as = 'script'
    link.crossOrigin = ''
  }
  link.href = dep
  // @ts-ignore
  document.head.appendChild(link)
}

return baseModule();
  • Only the first @ts-ignore is needed to silence the error for assetsURL, which is dynamically generated.
  • const dep of deps should be let dep of deps, since dep is re-assigned.

@gajus
Copy link
Contributor Author

gajus commented Aug 1, 2022

@gajus A couple notes about your proposed code below:

for (const dep of deps) {
  // @ts-ignore
  dep = assetsURL(dep, importerUrl)
  // @ts-ignore
  if (dep in seen) return
  // @ts-ignore
  seen[dep] = true
  const isCss = dep.endsWith('.css')
  // @ts-ignore check if the file is already preloaded by SSR markup
  if (documentLinkUrls.includes(dep)) {
    return
  }
  // @ts-ignore
  const link = document.createElement('link')
  // @ts-ignore
  link.rel = isCss ? 'stylesheet' : scriptRel
  if (!isCss) {
    link.as = 'script'
    link.crossOrigin = ''
  }
  link.href = dep
  // @ts-ignore
  document.head.appendChild(link)
}

return baseModule();
  • Only the first @ts-ignore is needed to silence the error for assetsURL, which is dynamically generated.
  • const dep of deps should be let dep of deps, since dep is re-assigned.

None of the code that you reference is added by this PR.

@tony19
Copy link
Contributor

tony19 commented Aug 1, 2022

Yeah, I'm aware 😄 Otherwise, I would've noted it in a PR review. I was merely commenting.

Comment on lines -77 to +81
const cssSelector = isCss ? '[rel="stylesheet"]' : ''
// @ts-ignore check if the file is already preloaded by SSR markup
if (document.querySelector(`link[href="${dep}"]${cssSelector}`)) {
if (documentLinkUrls.includes(dep)) {
Copy link
Member

Choose a reason for hiding this comment

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

This now skips checking [rel="stylesheet"] if isCss is true, which would regress #1734. We should probably check the href and rel="stylsheet" too for css.

@bluwy
Copy link
Member

bluwy commented Aug 2, 2022

Related, though I didn't want to add it to this PR, why is this being awaited in the first place?

It's likely to prevent FOUC if the preload links aren't properly loaded yet, and also to prevent runtime race conditions between preload deps and base module.

@bluwy
Copy link
Member

bluwy commented Feb 26, 2023

Closing as this PR brings in breaking changes.

@bluwy bluwy closed this Feb 26, 2023
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.

3 participants