Skip to content

Add script import option#952

Open
wherewhere wants to merge 8 commits intonext-theme:masterfrom
wherewhere:script-option
Open

Add script import option#952
wherewhere wants to merge 8 commits intonext-theme:masterfrom
wherewhere:script-option

Conversation

@wherewhere
Copy link
Copy Markdown
Contributor

@wherewhere wherewhere commented Mar 14, 2026

PR Checklist

  • The changes have been tested (for bug fixes / features).
  • Docs in NexT website have been added / updated (for features).

PR Type

  • Bugfix.
  • Feature.
  • Improvement.
  • Code style update (e.g. formatting, linting).
  • Refactoring (no changes to functionality and APIs).
  • Documentation.
  • Translation.
  • Other... Please describe:

What is the current behavior?

Issue resolved: #951

What is the new behavior?

Add options for next_js and next_vendors, and set defer manually.

How to use?

Every script which at the bottom of body before #882 should set defer, which dependences also should be loaded on or before defer.
Every script which at head before #882 should not set defer, because these dependences maybe used by users in script blocks. Set async or defer will make it become a broken change.
Every script which does not working as a dependence such as google_analytics can set async, because it won't working for anyone but only itself.

@coveralls
Copy link
Copy Markdown

coveralls commented Mar 14, 2026

Pull Request Test Coverage Report for Build 23105395144

Details

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage remained the same at 97.451%

Totals Coverage Status
Change from base Build 20737144410: 0.0%
Covered Lines: 400
Relevant Lines: 405

💛 - Coveralls

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds explicit script loading attribute control (defer / async) to NexT’s next_js and next_vendors helpers to address script execution order regressions introduced by always-deferred vendor scripts (Issue #951 / PR #882 context).

Changes:

  • Extend next_js / next_vendors helpers to accept { defer, async } options and stop forcing defer by default.
  • Update multiple third-party template includes to explicitly set defer: true (and in a few places async: true).
  • Adjust search/statistics integrations to use the new helper options.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
scripts/helpers/engine.js Adds defer/async options to helper-generated <script> tags; changes default loading behavior.
layout/_scripts/index.njk Switches most theme scripts to explicit defer: true.
layout/_third-party/tags/wavedrom.njk Explicitly defers the tag script.
layout/_third-party/tags/pdf.njk Explicitly defers the tag script.
layout/_third-party/tags/mermaid.njk Explicitly defers the tag script.
layout/_third-party/statistics/lean-analytics.njk Explicitly defers the statistics script.
layout/_third-party/statistics/firestore.njk Changes Firebase vendor loading attributes and defers the Firestore script.
layout/_third-party/search/localsearch.njk Changes LocalSearch vendor loading attributes and defers the integration script.
layout/_third-party/search/algolia-search.njk Changes Algolia vendor loading attributes and defers the integration script.
layout/_third-party/pace.njk Explicitly defers the third-party script.
layout/_third-party/fancybox.njk Explicitly defers the third-party script.
layout/_third-party/chat/tidio.njk Explicitly defers the theme-side integration script.
layout/_third-party/chat/chatra.njk Explicitly defers the theme-side integration script.
layout/_third-party/addtoany.njk Explicitly defers the third-party script.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

config.js may used by users so treat it as dependence
comments.js utils.js motion.js sidebar.js next-boot.js bookmark.js pjax.js should load by order
@wherewhere
Copy link
Copy Markdown
Contributor Author

Copilot is very useful.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces configurable script loading attributes in the NexT Hexo helpers to address script dependency/load-order issues (notably around defer in <head>), and updates many theme/third-party templates to explicitly choose defer vs async.

Changes:

  • Extend next_js / next_vendors helpers to support { defer, async } options (instead of always forcing defer).
  • Update core theme scripts to explicitly use defer.
  • Update many third-party integrations to use either defer or async depending on expected dependency/initialization behavior.

Reviewed changes

Copilot reviewed 30 out of 30 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
scripts/helpers/engine.js Adds defer/async options for generated <script> tags in next_js and next_vendors.
layout/_scripts/index.njk Sets defer: true for core theme scripts loaded in <head>.
layout/_partials/page/schedule.njk Switches schedule script to async with PJAX attribute.
layout/_partials/comments.njk Switches comments-buttons script to async with PJAX attribute.
layout/_third-party/tags/wavedrom.njk Marks WaveDrom initializer script as deferred.
layout/_third-party/tags/pdf.njk Marks PDF initializer script as deferred.
layout/_third-party/tags/mermaid.njk Marks Mermaid initializer script as deferred.
layout/_third-party/statistics/lean-analytics.njk Marks LeanCloud analytics initializer as deferred.
layout/_third-party/statistics/firestore.njk Marks Firebase vendor scripts + initializer as deferred.
layout/_third-party/search/localsearch.njk Marks LocalSearch vendor + initializer as deferred.
layout/_third-party/search/algolia-search.njk Marks Algolia vendor + initializer as deferred.
layout/_third-party/quicklink.njk Marks Quicklink initializer as async.
layout/_third-party/pace.njk Marks Pace initializer as deferred.
layout/_third-party/math/mathjax.njk Marks MathJax initializer as async.
layout/_third-party/math/katex.njk Marks KaTeX copy-tex initializer as async.
layout/_third-party/fancybox.njk Marks Fancybox initializer as deferred.
layout/_third-party/comments/utterances.njk Marks Utterances initializer as async.
layout/_third-party/comments/livere.njk Marks Livere initializer as async.
layout/_third-party/comments/isso.njk Marks Isso initializer as async.
layout/_third-party/comments/gitalk.njk Marks Gitalk initializer as async.
layout/_third-party/comments/disqusjs.njk Marks DisqusJS initializer as async.
layout/_third-party/comments/disqus.njk Marks Disqus initializer as async.
layout/_third-party/comments/changyan.njk Marks Changyan initializer as async.
layout/_third-party/chat/tidio.njk Marks Tidio initializer as deferred.
layout/_third-party/chat/chatra.njk Marks Chatra initializer as deferred.
layout/_third-party/analytics/matomo.njk Marks Matomo initializer as async.
layout/_third-party/analytics/growingio.njk Marks GrowingIO initializer as async.
layout/_third-party/analytics/google-analytics.njk Marks Google Analytics initializer as async.
layout/_third-party/analytics/baidu-analytics.njk Marks Baidu Analytics initializer as async.
layout/_third-party/addtoany.njk Marks AddToAny initializer as deferred.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds per-script loading control to NexT’s script tag helpers to address ordering regressions introduced by moving scripts into <head> (notably for vendor dependencies vs inline script blocks).

Changes:

  • Extend next_js and next_vendors helpers to accept { defer, async } options (and stop forcing defer unconditionally).
  • Update most layout call sites to explicitly opt into defer (or async for analytics-like scripts).
  • Adjust a couple of PJAX-scoped scripts to use async.

Reviewed changes

Copilot reviewed 30 out of 30 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
scripts/helpers/engine.js Adds { defer, async } options to next_js / next_vendors script rendering.
layout/_third-party/tags/wavedrom.njk Marks tag script as deferred.
layout/_third-party/tags/pdf.njk Marks tag script as deferred.
layout/_third-party/tags/mermaid.njk Marks tag script as deferred.
layout/_third-party/statistics/lean-analytics.njk Marks statistics script as deferred.
layout/_third-party/statistics/firestore.njk Defers Firebase vendor scripts and Firestore integration script.
layout/_third-party/search/localsearch.njk Defers local search vendor + integration script.
layout/_third-party/search/algolia-search.njk Defers Algolia vendor + integration script.
layout/_third-party/quicklink.njk Defers the integration script (vendor call site not updated).
layout/_third-party/pace.njk Marks pace integration script as deferred.
layout/_third-party/math/mathjax.njk Marks MathJax integration script as deferred.
layout/_third-party/math/katex.njk Marks KaTeX copy-tex integration script as deferred.
layout/_third-party/fancybox.njk Marks Fancybox integration script as deferred.
layout/_third-party/comments/utterances.njk Marks Utterances integration script as deferred.
layout/_third-party/comments/livere.njk Marks Livere integration script as deferred.
layout/_third-party/comments/isso.njk Marks Isso integration script as deferred.
layout/_third-party/comments/gitalk.njk Marks Gitalk integration script as deferred.
layout/_third-party/comments/disqusjs.njk Marks DisqusJS integration script as deferred.
layout/_third-party/comments/disqus.njk Marks Disqus integration script as deferred.
layout/_third-party/comments/changyan.njk Marks Changyan integration script as deferred.
layout/_third-party/chat/tidio.njk Marks Tidio integration script as deferred.
layout/_third-party/chat/chatra.njk Marks Chatra integration script as deferred.
layout/_third-party/analytics/matomo.njk Marks Matomo integration script as async.
layout/_third-party/analytics/growingio.njk Marks GrowingIO integration script as async.
layout/_third-party/analytics/google-analytics.njk Marks Google Analytics integration script as async.
layout/_third-party/analytics/baidu-analytics.njk Marks Baidu Analytics integration script as async.
layout/_third-party/addtoany.njk Marks AddToAny integration script as deferred.
layout/_scripts/index.njk Explicitly defers core NexT scripts (utils/boot/etc).
layout/_partials/page/schedule.njk Loads schedule script with async + PJAX attribute.
layout/_partials/comments.njk Loads comments-buttons script with async + PJAX attribute.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces per-script loading controls (defer / async) for NexT’s script tag helpers to address script execution order issues (notably #951) while allowing selective performance optimizations (related to the defer-in-<head> change from #882).

Changes:

  • Extend next_js and next_vendors helpers to accept defer / async options (with a warning when both are set).
  • Update many theme/third-party templates to explicitly opt into defer: true for scripts that should remain deferred.
  • Switch some analytics/tag scripts to async: true where they are intended to be non-blocking.

Reviewed changes

Copilot reviewed 30 out of 30 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
scripts/helpers/engine.js Adds defer/async options to script helpers and adjusts generated <script> tags.
layout/_third-party/tags/wavedrom.njk Explicitly defers Wavedrom init script.
layout/_third-party/tags/pdf.njk Explicitly defers PDF tag script.
layout/_third-party/tags/mermaid.njk Explicitly defers Mermaid tag script.
layout/_third-party/statistics/lean-analytics.njk Explicitly defers LeanCloud analytics script.
layout/_third-party/statistics/firestore.njk Explicitly defers Firebase vendors and Firestore integration script.
layout/_third-party/search/localsearch.njk Explicitly defers Local Search vendor + integration script.
layout/_third-party/search/algolia-search.njk Explicitly defers Algolia vendor + integration script.
layout/_third-party/quicklink.njk Explicitly defers Quicklink integration script.
layout/_third-party/pace.njk Explicitly defers Pace integration script.
layout/_third-party/math/mathjax.njk Explicitly defers MathJax integration script.
layout/_third-party/math/katex.njk Explicitly defers KaTeX copy-tex integration script.
layout/_third-party/fancybox.njk Explicitly defers Fancybox integration script.
layout/_third-party/comments/utterances.njk Explicitly defers Utterances integration script.
layout/_third-party/comments/livere.njk Explicitly defers LiveRe integration script.
layout/_third-party/comments/isso.njk Explicitly defers Isso integration script.
layout/_third-party/comments/gitalk.njk Explicitly defers Gitalk integration script.
layout/_third-party/comments/disqusjs.njk Explicitly defers DisqusJS integration script.
layout/_third-party/comments/disqus.njk Explicitly defers Disqus integration script.
layout/_third-party/comments/changyan.njk Explicitly defers Changyan integration script.
layout/_third-party/chat/tidio.njk Explicitly defers Tidio integration script.
layout/_third-party/chat/chatra.njk Explicitly defers Chatra integration script.
layout/_third-party/analytics/matomo.njk Marks Matomo integration script as async.
layout/_third-party/analytics/growingio.njk Marks GrowingIO integration script as async.
layout/_third-party/analytics/google-analytics.njk Marks Google Analytics integration script as async.
layout/_third-party/analytics/baidu-analytics.njk Marks Baidu Analytics integration script as async.
layout/_third-party/addtoany.njk Explicitly defers AddToAny integration script.
layout/_scripts/index.njk Explicitly defers core theme scripts loaded from <head>.
layout/_partials/page/schedule.njk Marks schedule page script as async for PJAX execution.
layout/_partials/comments.njk Marks comment-buttons script as async for PJAX execution.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +37 to 60
if (defer && async) {
hexo.log.warn('Both `defer` and `async` are set to true for', file, 'in next_js helper. `defer` will be ignored.');
defer = false;
}
return `<script ${pjax ? 'data-pjax ' : ''}${module ? 'type="module" ' : ''}${defer ? 'defer ' : ''}${async ? 'async ' : ''}src="${src}"></script>`;
});

hexo.extend.helper.register('next_vendors', function(name) {
hexo.extend.helper.register('next_vendors', function(name, {
defer = false,
async = false
} = {}) {
const { url, integrity } = this.theme.vendors[name];
const type = url.endsWith('css') ? 'css' : 'js';
if (type === 'css') {
if (integrity) return `<link rel="stylesheet" href="${url}" integrity="${integrity}" crossorigin="anonymous">`;
return `<link rel="stylesheet" href="${url}">`;
}
if (integrity) return `<script src="${url}" integrity="${integrity}" crossorigin="anonymous" defer></script>`;
return `<script src="${url}" defer></script>`;
if (defer && async) {
hexo.log.warn('Both `defer` and `async` are set to true for', name, 'in next_vendors helper. `defer` will be ignored.');
defer = false;
}
if (integrity) return `<script ${defer ? 'defer ' : ''}${async ? 'async ' : ''}src="${url}" integrity="${integrity}" crossorigin="anonymous"></script>`;
return `<script ${defer ? 'defer ' : ''}${async ? 'async ' : ''}src="${url}"></script>`;
});
@wherewhere
Copy link
Copy Markdown
Contributor Author

OK, Copilot said no more wrong.

Set fontawesome to defer since it usually used only as CSS parser
Set pace_js to async since this should only set by this theme
Set katex to defer since it's document said that
Set quicklink to defer since it's document also said that
Set pjax to defer since it should only create one instance which it created by this theme
Set lazyload to defer since it usually  used after DOM is loaded
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

next_vendors 默认 defer 破坏了 script 块加载顺序

4 participants