diff --git a/dotcom-rendering/src/client/adaptiveSite.ts b/dotcom-rendering/src/client/adaptiveSite.ts index 9162bef68b9..aaab457db01 100644 --- a/dotcom-rendering/src/client/adaptiveSite.ts +++ b/dotcom-rendering/src/client/adaptiveSite.ts @@ -1,8 +1,12 @@ +import { log } from '@guardian/libs'; import { isServer } from '../lib/isServer'; +import { setSchedulerPriorityLastStartTime } from '../lib/scheduler'; /** * Whether we should adapt the current page to address poor performance issues. - * Initially this will only happen as part of a @guardian/open-journalism test. + * + * It will resolve immediately if `false`, but needs to wait for perf check to + * complete if you're in the adaptive site test variant. */ export const shouldAdapt = async (): Promise => { if (isServer) return false; @@ -18,3 +22,19 @@ export const shouldAdapt = async (): Promise => { return isPerformingPoorly(); }; + +/** Hide all placeholders of non-critical islands */ +const hideAdaptedIslands = () => { + const style = document.createElement('style'); + style.innerHTML = `gu-island:not([priority=critical]) [data-name=placeholder] { display: none; }`; + document.head.appendChild(style); +}; + +export const adaptSite = (): void => { + log('openJournalism', '🎛️ Adapting'); + + // disable all tasks except critical ones + setSchedulerPriorityLastStartTime('feature', 0); + setSchedulerPriorityLastStartTime('enhancement', 0); + hideAdaptedIslands(); +}; diff --git a/dotcom-rendering/src/client/index.ts b/dotcom-rendering/src/client/index.ts index 7d136769f18..701e4b2b4a0 100644 --- a/dotcom-rendering/src/client/index.ts +++ b/dotcom-rendering/src/client/index.ts @@ -1,145 +1,152 @@ import './webpackPublicPath'; +import { adaptSite, shouldAdapt } from './adaptiveSite'; import { startup } from './startup'; -/************************************************************* - * - * The following modules are bundled in the entry chunk, - * so they can be run immediately, but we still want to report - * on the duration of loading and evaluating them. - * - *************************************************************/ +void (async () => { + if (await shouldAdapt()) { + adaptSite(); + } -void startup( - 'bootCmp', - () => - import(/* webpackMode: "eager" */ './bootCmp').then(({ bootCmp }) => - bootCmp(), - ), - { - priority: 'critical', - }, -); + /************************************************************* + * + * The following modules are bundled in the entry chunk, + * so they can be run immediately, but we still want to report + * on the duration of loading and evaluating them. + * + *************************************************************/ -void startup( - 'recordInitialPageEvents', - () => - import( - /* webpackMode: "eager" */ './ophan/recordInitialPageEvents' - ).then(({ recordInitialPageEvents }) => recordInitialPageEvents()), - { - priority: 'critical', - }, -); + void startup( + 'bootCmp', + () => + import(/* webpackMode: "eager" */ './bootCmp').then(({ bootCmp }) => + bootCmp(), + ), + { + priority: 'critical', + }, + ); -void startup( - 'ga', - () => import(/* webpackMode: "eager" */ './ga').then(({ ga }) => ga()), - { - priority: 'critical', - }, -); + void startup( + 'recordInitialPageEvents', + () => + import( + /* webpackMode: "eager" */ './ophan/recordInitialPageEvents' + ).then(({ recordInitialPageEvents }) => recordInitialPageEvents()), + { + priority: 'critical', + }, + ); -void startup( - 'sentryLoader', - () => - import(/* webpackMode: "eager" */ './sentryLoader').then( - ({ sentryLoader }) => sentryLoader(), - ), - { - priority: 'critical', - }, -); + void startup( + 'ga', + () => import(/* webpackMode: "eager" */ './ga').then(({ ga }) => ga()), + { + priority: 'critical', + }, + ); -void startup( - 'dynamicImport', - () => - import(/* webpackMode: "eager" */ './dynamicImport').then( - ({ dynamicImport }) => dynamicImport(), - ), - { - priority: 'critical', - }, -); + void startup( + 'sentryLoader', + () => + import(/* webpackMode: "eager" */ './sentryLoader').then( + ({ sentryLoader }) => sentryLoader(), + ), + { + priority: 'critical', + }, + ); -void startup( - 'islands', - () => - import(/* webpackMode: "eager" */ './islands').then(({ islands }) => - islands(), - ), - { - priority: 'critical', - }, -); + void startup( + 'dynamicImport', + () => + import(/* webpackMode: "eager" */ './dynamicImport').then( + ({ dynamicImport }) => dynamicImport(), + ), + { + priority: 'critical', + }, + ); -void startup( - 'poorPerformanceMonitoring', - () => - import(/* webpackMode: "eager" */ './poorPerformanceMonitoring').then( - ({ recordPoorPerformance }) => recordPoorPerformance(), - ), - { - priority: 'critical', - }, -); + void startup( + 'islands', + () => + import(/* webpackMode: "eager" */ './islands').then(({ islands }) => + islands(), + ), + { + priority: 'critical', + }, + ); -/************************************************************* - * - * The following modules are lazy loaded, - * because they are lower priority and do not want to block - * the modules above on loading these. - * - * We are not assigning chunk name to allow Webpack - * to optimise chunking based on its algorithm. - * - *************************************************************/ + void startup( + 'poorPerformanceMonitoring', + () => + import( + /* webpackMode: "eager" */ './poorPerformanceMonitoring' + ).then(({ recordPoorPerformance }) => recordPoorPerformance()), + { + priority: 'critical', + }, + ); -void startup( - 'atomIframe', - () => - import( - /* webpackMode: 'lazy' */ - './atomIframe' - ).then(({ atomIframe }) => atomIframe()), - { priority: 'feature' }, -); + /************************************************************* + * + * The following modules are lazy loaded, + * because they are lower priority and do not want to block + * the modules above on loading these. + * + * We are not assigning chunk name to allow Webpack + * to optimise chunking based on its algorithm. + * + *************************************************************/ -void startup( - 'embedIframe', - () => - import( - /* webpackMode: 'lazy' */ - './embedIframe' - ).then(({ embedIframe }) => embedIframe()), - { priority: 'feature' }, -); + void startup( + 'atomIframe', + () => + import( + /* webpackMode: 'lazy' */ + './atomIframe' + ).then(({ atomIframe }) => atomIframe()), + { priority: 'feature' }, + ); -void startup( - 'newsletterEmbedIframe', - () => - import( - /* webpackMode: 'lazy' */ - './newsletterEmbedIframe' - ).then(({ newsletterEmbedIframe }) => newsletterEmbedIframe()), - { priority: 'feature' }, -); + void startup( + 'embedIframe', + () => + import( + /* webpackMode: 'lazy' */ + './embedIframe' + ).then(({ embedIframe }) => embedIframe()), + { priority: 'feature' }, + ); -void startup( - 'relativeTime', - () => - import( - /* webpackMode: 'lazy' */ - './relativeTime' - ).then(({ relativeTime }) => relativeTime()), - { priority: 'feature' }, -); + void startup( + 'newsletterEmbedIframe', + () => + import( + /* webpackMode: 'lazy' */ + './newsletterEmbedIframe' + ).then(({ newsletterEmbedIframe }) => newsletterEmbedIframe()), + { priority: 'feature' }, + ); -void startup( - 'initDiscussion', - () => - import( - /* webpackMode: 'lazy' */ - './discussion' - ).then(({ discussion }) => discussion()), - { priority: 'feature' }, -); + void startup( + 'relativeTime', + () => + import( + /* webpackMode: 'lazy' */ + './relativeTime' + ).then(({ relativeTime }) => relativeTime()), + { priority: 'feature' }, + ); + + void startup( + 'initDiscussion', + () => + import( + /* webpackMode: 'lazy' */ + './discussion' + ).then(({ discussion }) => discussion()), + { priority: 'feature' }, + ); +})();