mirror of
https://github.com/discourse/discourse.git
synced 2025-03-04 10:19:40 +00:00
PERF: Stop eagerly-loading core helper modules (#24015)
Now that core has a file structure and default imports, Ember's resolver can load helpers lazily. So we can remove the lazy loading, and helpers in ember templates will continue to work. This should provide a slight performance improvement for initial boot. However, there is a slight complication: some of our helpers are also registered with our Raw Handlebars system as a side-effect of loading the module. Therefore, this commit adds a `helperMissing` helper to our RawHandlebars system. This looks up the helper by name in the ember resolver, which triggers the relevant module to be evaluated, and the raw helper to be registered as a side effect. For backwards-compatibility, plugin and theme helpers continue to be eagerly evaluated. Once the `discourse.register-unbound` deprecation is resolved, we can safely remove this eager loading.
This commit is contained in:
parent
98cb14dd82
commit
7ed6195f19
@ -4,10 +4,13 @@ export const RUNTIME_OPTIONS = {
|
||||
allowProtoPropertiesByDefault: true,
|
||||
};
|
||||
|
||||
export function registerRawHelpers(hbs, handlebarsClass) {
|
||||
export function registerRawHelpers(hbs, handlebarsClass, owner) {
|
||||
if (!hbs.helpers) {
|
||||
hbs.helpers = Object.create(handlebarsClass.helpers);
|
||||
}
|
||||
|
||||
lazyLoadHelpers(hbs, owner);
|
||||
|
||||
if (hbs.__helpers_registered) {
|
||||
return;
|
||||
}
|
||||
@ -85,3 +88,24 @@ export function registerRawHelpers(hbs, handlebarsClass) {
|
||||
stringCompatHelper("if");
|
||||
stringCompatHelper("with");
|
||||
}
|
||||
|
||||
function lazyLoadHelpers(hbs, owner) {
|
||||
// Reimplements `helperMissing` so that it triggers a lookup() for
|
||||
// a helper of that name. Means we don't need to eagerly load all
|
||||
// helpers/* files during boot.
|
||||
hbs.registerHelper("helperMissing", function (...args) {
|
||||
const opts = args[args.length - 1];
|
||||
if (opts?.name) {
|
||||
// Lookup and evaluate the relevant module. Raw helpers may be registed as a side effect
|
||||
owner.lookup(`helper:${opts.name}`);
|
||||
|
||||
if (hbs.helpers[opts.name]) {
|
||||
// Helper now exists, invoke it
|
||||
return hbs.helpers[opts.name]?.call(this, ...arguments);
|
||||
} else {
|
||||
// Not a helper, treat as property
|
||||
return hbs.helpers["get"].call(this, ...arguments);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -7,12 +7,22 @@ import {
|
||||
import RawHandlebars from "discourse-common/lib/raw-handlebars";
|
||||
import { registerRawHelpers } from "discourse-common/lib/raw-handlebars-helpers";
|
||||
|
||||
function isThemeOrPluginHelper(path) {
|
||||
return (
|
||||
path.includes("/helpers/") &&
|
||||
(path.startsWith("discourse/theme-") ||
|
||||
path.startsWith("discourse/plugins/")) &&
|
||||
!path.endsWith("-test")
|
||||
);
|
||||
}
|
||||
|
||||
export function autoLoadModules(owner, registry) {
|
||||
Object.keys(requirejs.entries).forEach((entry) => {
|
||||
if (/\/helpers\//.test(entry) && !/-test/.test(entry)) {
|
||||
if (isThemeOrPluginHelper(entry)) {
|
||||
// Once the discourse.register-unbound deprecation is resolved, we can remove this eager loading
|
||||
requirejs(entry, null, null, true);
|
||||
}
|
||||
if (/\/widgets\//.test(entry) && !/-test/.test(entry)) {
|
||||
if (entry.includes("/widgets/") && !entry.endsWith("-test")) {
|
||||
requirejs(entry, null, null, true);
|
||||
}
|
||||
});
|
||||
@ -31,7 +41,7 @@ export function autoLoadModules(owner, registry) {
|
||||
|
||||
createHelperContext(context);
|
||||
registerHelpers(registry);
|
||||
registerRawHelpers(RawHandlebars, Handlebars);
|
||||
registerRawHelpers(RawHandlebars, Handlebars, owner);
|
||||
}
|
||||
|
||||
export default {
|
||||
|
Loading…
x
Reference in New Issue
Block a user