Skip to content

Commit d2458e6

Browse files
committed
Small improvements
- Track head links in a Map, because Set doesn't deduplicate them properly - Make ServerHashedFileMapping independent of ThemeConfig - Make theme pre-fetching configurable (e.g. only prefetch the main theme CSS, but leave route-based theme CSS lazy)
1 parent 93da6ce commit d2458e6

File tree

4 files changed

+22
-20
lines changed

4 files changed

+22
-20
lines changed

config/config.example.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ cache:
7878
anonymousCache:
7979
# Maximum number of pages to cache. Default is zero (0) which means anonymous user cache is disabled.
8080
# As all pages are cached in server memory, increasing this value will increase memory needs.
81-
# Individual cached pages are usually small (<100KB), so a value of max=1000 would only require ~100MB of memory.
81+
# Individual cached pages are usually small (<100KB), so a value of max=1000 would only require ~100MB of memory.
8282
max: 0
8383
# Amount of time after which cached pages are considered stale (in ms). After becoming stale, the cached
8484
# copy is automatically refreshed on the next request.
@@ -327,6 +327,7 @@ themes:
327327
# - name: BASE_THEME_NAME
328328
#
329329
- name: dspace
330+
prefetch: true
330331
headTags:
331332
- tagName: link
332333
attributes:
@@ -379,7 +380,7 @@ vocabularies:
379380
vocabulary: 'srsc'
380381
enabled: true
381382

382-
# Default collection/community sorting order at Advanced search, Create/update community and collection when there are not a query.
383+
# Default collection/community sorting order at Advanced search, Create/update community and collection when there are not a query.
383384
comcolSelectionSort:
384385
sortField: 'dc.title'
385-
sortDirection: 'ASC'
386+
sortDirection: 'ASC'

server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ const cookieParser = require('cookie-parser');
7171
const configJson = join(DIST_FOLDER, 'assets/config.json');
7272
const hashedFileMapping = new ServerHashedFileMapping(DIST_FOLDER, 'index.html');
7373
const appConfig: AppConfig = buildAppConfig(configJson, hashedFileMapping);
74-
hashedFileMapping.addThemeStyles(appConfig.themes);
74+
appConfig.themes.forEach(themeConfig => hashedFileMapping.addThemeStyle(themeConfig.name, themeConfig.prefetch));
7575
hashedFileMapping.save();
7676

7777
// cache of SSR pages for known bots, only enabled in production mode

src/config/theme.model.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ export interface NamedThemeConfig extends Config {
2020
* A list of HTML tags that should be added to the HEAD section of the document, whenever this theme is active.
2121
*/
2222
headTags?: HeadTagConfig[];
23+
24+
/**
25+
* Whether this theme's CSS should be prefetched in CSR mode
26+
*/
27+
prefetch?: boolean;
2328
}
2429

2530
/**

src/modules/dynamic-hash/hashed-file-mapping.server.ts

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import {
2222
} from 'path';
2323
import zlib from 'zlib';
2424
import { hasValue } from '../../app/shared/empty.util';
25-
import { ThemeConfig } from '../../config/theme.model';
2625
import {
2726
HashedFileMapping,
2827
ID,
@@ -45,7 +44,7 @@ export class ServerHashedFileMapping extends HashedFileMapping {
4544
public readonly indexPath: string;
4645
private readonly indexContent: string;
4746

48-
protected readonly headLinks: Set<HeadLink> = new Set();
47+
protected readonly headLinks: Map<string, HeadLink> = new Map();
4948

5049
constructor(
5150
private readonly root: string,
@@ -70,7 +69,7 @@ export class ServerHashedFileMapping extends HashedFileMapping {
7069

7170
// remove previous files
7271
const ext = extname(path);
73-
glob.GlobSync(path.replace(`${ext}`, `.*${ext}*`))
72+
new glob.GlobSync(path.replace(`${ext}`, `.*${ext}*`))
7473
.found
7574
.forEach(p => rmSync(p));
7675

@@ -111,33 +110,30 @@ export class ServerHashedFileMapping extends HashedFileMapping {
111110
return hashPath;
112111
}
113112

114-
/**
115-
* Add CSS for all configured themes to the mapping
116-
* @param themeConfigurations
117-
*/
118-
addThemeStyles(themeConfigurations: ThemeConfig[]) {
119-
for (const themeConfiguration of themeConfigurations) {
120-
const path = `${this.root}/${themeConfiguration.name}-theme.css`;
121-
const hashPath = this.add(path);
113+
addThemeStyle(theme: string, prefetch = true) {
114+
const path = `${this.root}/${theme}-theme.css`;
115+
const hashPath = this.add(path);
122116

117+
if (prefetch) {
123118
// We know this CSS is likely needed, so we can avoid a FOUC by retrieving it in advance
124119
// Angular does the same for global styles, but doesn't "know" about our themes
125120
this.addHeadLink({
126121
path,
127122
rel: 'prefetch',
128123
as: 'style',
129124
});
130-
131-
this.ensureCompressedFilesAssumingUnchangedContent(path, hashPath, '.br');
132-
this.ensureCompressedFilesAssumingUnchangedContent(path, hashPath, '.gz');
133125
}
126+
127+
// We know theme CSS has been compressed already
128+
this.ensureCompressedFilesAssumingUnchangedContent(path, hashPath, '.br');
129+
this.ensureCompressedFilesAssumingUnchangedContent(path, hashPath, '.gz');
134130
}
135131

136132
/**
137133
* Include a head link for a given resource to the index HTML.
138134
*/
139135
addHeadLink(headLink: HeadLink) {
140-
this.headLinks.add(headLink);
136+
this.headLinks.set(headLink.path, headLink);
141137
}
142138

143139
private renderHeadLink(link: HeadLink): string {
@@ -175,7 +171,7 @@ export class ServerHashedFileMapping extends HashedFileMapping {
175171
root.querySelector('head')
176172
.appendChild(`<script id="${ID}" type="application/json">${JSON.stringify(out)}</script>` as any);
177173

178-
for (const headLink of this.headLinks) {
174+
for (const headLink of this.headLinks.values()) {
179175
root.querySelector('head')
180176
.appendChild(this.renderHeadLink(headLink) as any);
181177
}

0 commit comments

Comments
 (0)