Skip to content

Commit 9d44789

Browse files
perf optimisations (5~7 seconds shaved off (windows)) (#1278)
1 parent f0bf4b2 commit 9d44789

File tree

8 files changed

+126
-79
lines changed

8 files changed

+126
-79
lines changed

_config.ts

Lines changed: 50 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,14 @@ import createGAMiddleware from "./middleware/googleAnalytics.ts";
3030
import redirectsMiddleware, {
3131
toFileAndInMemory,
3232
} from "./middleware/redirects.ts";
33+
import { cliNow } from "./timeUtils.ts";
34+
import { log } from "lume/core/utils/log.ts";
3335

3436
const site = lume(
3537
{
3638
location: new URL("https://docs.deno.com"),
3739
caseSensitiveUrls: true,
40+
emptyDest: false,
3841
server: {
3942
middlewares: [
4043
redirectsMiddleware,
@@ -46,6 +49,14 @@ const site = lume(
4649
],
4750
page404: "/404",
4851
},
52+
watcher: {
53+
ignore: [
54+
"/.git",
55+
"/.github",
56+
"/.vscode",
57+
],
58+
debounce: 1_000,
59+
},
4960
},
5061
{
5162
markdown: {
@@ -77,12 +88,20 @@ const site = lume(
7788
options: {
7889
linkify: true,
7990
langPrefix: "highlight notranslate language-",
91+
highlight: (code, lang) => {
92+
if (!lang || !Prism.languages[lang]) {
93+
return code;
94+
}
95+
const result = Prism.highlight(code, Prism.languages[lang], lang);
96+
return result || code;
97+
},
8098
},
8199
},
82100
},
83101
);
84102

85103
site.copy("static", ".");
104+
site.copy("timeUtils.ts");
86105
site.copy("subhosting/api/images");
87106
site.copy("deploy/docs-images");
88107
site.copy("deploy/kv/manual/images");
@@ -107,6 +126,7 @@ site.use(
107126
output: toFileAndInMemory,
108127
}),
109128
);
129+
110130
site.use(search());
111131
site.use(jsx());
112132

@@ -115,6 +135,7 @@ site.use(
115135
plugins: [tw(tailwindConfig)],
116136
}),
117137
);
138+
118139
site.use(
119140
esbuild({
120141
extensions: [".client.ts", ".client.js"],
@@ -125,22 +146,6 @@ site.use(
125146
}),
126147
);
127148

128-
// This is a work-around due to deno-dom's dependency of nwsapi not supporting
129-
// :has selectors, nor having intention of supporting them, so using `body:not(:has(.ddoc))`
130-
// is not possible. This works around by adding an `apply-prism` class on pages that
131-
// don't use a ddoc class.
132-
site.process([".html"], (pages) => {
133-
for (const page of pages) {
134-
const document = page.document!;
135-
if (!document.querySelector(".ddoc")) {
136-
document.body.classList.add("apply-prism");
137-
document
138-
.querySelectorAll("body.apply-prism pre code")
139-
.forEach((element) => Prism.highlightElement(element));
140-
}
141-
}
142-
});
143-
144149
site.use(toc({ anchor: false }));
145150
site.use(title());
146151
site.use(sitemap());
@@ -161,44 +166,6 @@ site.copy("reference_gen/gen/node/page.css", "/api/node/page.css");
161166
site.copy("reference_gen/gen/node/styles.css", "/api/node/styles.css");
162167
site.copy("reference_gen/gen/node/script.js", "/api/node/script.js");
163168

164-
site.process([".html"], (pages) => {
165-
for (const page of pages) {
166-
const document = page.document;
167-
if (document) {
168-
const tabGroups = document.querySelectorAll("deno-tabs");
169-
for (const tabGroup of tabGroups) {
170-
const newGroup = document.createElement("div");
171-
newGroup.classList.add("deno-tabs");
172-
newGroup.dataset.id = tabGroup.getAttribute("group-id")!;
173-
const buttons = document.createElement("ul");
174-
buttons.classList.add("deno-tabs-buttons");
175-
newGroup.appendChild(buttons);
176-
const tabs = document.createElement("div");
177-
tabs.classList.add("deno-tabs-content");
178-
newGroup.appendChild(tabs);
179-
for (const tab of tabGroup.children) {
180-
if (tab.tagName === "DENO-TAB") {
181-
const selected = tab.getAttribute("default") !== null;
182-
const buttonContainer = document.createElement("li");
183-
buttons.appendChild(buttonContainer);
184-
const button = document.createElement("button");
185-
button.textContent = tab.getAttribute("label")!;
186-
button.dataset.tab = tab.getAttribute("value")!;
187-
button.dataset.active = String(selected);
188-
buttonContainer.appendChild(button);
189-
const content = document.createElement("div");
190-
content.innerHTML = tab.innerHTML;
191-
content.dataset.tab = tab.getAttribute("value")!;
192-
content.dataset.active = String(selected);
193-
tabs.appendChild(content);
194-
}
195-
}
196-
tabGroup.replaceWith(newGroup);
197-
}
198-
}
199-
}
200-
});
201-
202169
site.ignore(
203170
"old",
204171
"README.md",
@@ -210,13 +177,35 @@ site.ignore(
210177
// "subhosting",
211178
);
212179

213-
site.scopedUpdates((path) => path == "/overrides.css");
214-
site.use(
215-
checkUrls({
216-
external: false, // Set to true to check external links
217-
output: "_broken_links.json",
218-
ignore: ["https://www.googletagmanager.com"],
219-
}),
180+
site.scopedUpdates(
181+
(path) => path == "/overrides.css",
182+
(path) => /\.(js|ts)$/.test(path),
183+
(path) => path.startsWith("/api/deno/"),
220184
);
221185

186+
const SKIP_CHECK_URLS = (Deno.env.get("SKIP_CHECK_URLS") || "false")
187+
.toLowerCase();
188+
189+
if (SKIP_CHECK_URLS !== "true") {
190+
log.info(`${cliNow()} Enabling broken-link checker`);
191+
192+
site.use(
193+
checkUrls({
194+
external: false, // Set to true to check external links
195+
output: "_broken_links.json",
196+
ignore: ["https://www.googletagmanager.com"],
197+
}),
198+
);
199+
} else {
200+
log.warn(
201+
`${cliNow()} <cyan>checkUrls</cyan>: Skipping broken link check for local performance.`,
202+
);
203+
}
204+
205+
site.addEventListener("afterStartServer", () => {
206+
log.warn(
207+
`${cliNow()} Server available at <green>http://localhost:3000</green>`,
208+
);
209+
});
210+
222211
export default site;

deno.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
},
1515
"tasks": {
1616
"serve": "deno run -A lume.ts -s",
17+
"serve:no_logs": "LUME_LOGS=WARN SKIP_CHECK_URLS=true deno run -A lume.ts -s",
1718
"start": "deno task serve",
1819
"dev": "deno task serve",
1920
"build": "deno run -A lume.ts",

examples/_components/SnippetComponent.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { ExampleSnippet } from "../types.ts";
2+
import Prism from "prismjs";
23

34
export default function SnippetComponent(props: {
45
filename: string;
@@ -7,6 +8,8 @@ export default function SnippetComponent(props: {
78
lastOfFile: boolean;
89
snippet: ExampleSnippet;
910
}) {
11+
const html = Prism.highlight(props.snippet.code, Prism.languages.js, "js");
12+
1013
return (
1114
<div class="grid grid-cols-1 sm:grid-cols-10 gap-x-8">
1215
<div
@@ -49,7 +52,7 @@ export default function SnippetComponent(props: {
4952
: "middle"}
5053
>
5154
<code
52-
dangerouslySetInnerHTML={{ __html: props.snippet.code }}
55+
dangerouslySetInnerHTML={{ __html: html }}
5356
></code>
5457
</pre>
5558
</div>

middleware/googleAnalytics.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,24 @@ import { type Event } from "ga4";
99
import type { RequestHandler } from "lume/core/server.ts";
1010
import type Server from "lume/core/server.ts";
1111
import nullMiddleware from "./null.ts";
12+
import { cliNow } from "../timeUtils.ts";
13+
import { log } from "lume/core/utils/log.ts";
1214

1315
const GA4_MEASUREMENT_ID = Deno.env.get("GA4_MEASUREMENT_ID");
1416

1517
export default function createGAMiddleware(
1618
server: Server | { addr?: Deno.Addr } | null = null,
1719
) {
1820
if (GA4_MEASUREMENT_ID == null) {
19-
console.warn(
20-
"createGAMiddleware: GA4_MEASUREMENT_ID is not set. Google Analytics middleware will be disabled.",
21+
log.warn(
22+
`${cliNow()} <cyan>createGAMiddleware</cyan>: GA4_MEASUREMENT_ID is not set. Google Analytics middleware will be disabled.`,
2123
);
2224
return nullMiddleware;
2325
}
2426

2527
if (server == null) {
26-
console.warn(
27-
"createGAMiddleware: Server object is not provided. Google Analytics middleware will be disabled.",
28+
log.warn(
29+
`${cliNow()} <cyan>createGAMiddleware</cyan>: Server object is not provided. Google Analytics middleware will be disabled.`,
2830
);
2931
return nullMiddleware;
3032
}

middleware/redirects.ts

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import type { RequestHandler } from "lume/core/server.ts";
44
import type Site from "lume/core/site.ts";
55
import GO_LINKS from "../go.json" with { type: "json" };
66
import REDIRECT_LINKS from "../oldurls.json" with { type: "json" };
7+
import { cliNow } from "../timeUtils.ts";
8+
import { log } from "lume/core/utils/log.ts";
79

810
type Status = 301 | 302 | 307 | 308;
911
type Redirect = [string, string, Status];
@@ -59,18 +61,20 @@ function loadFromJson() {
5961
let redirects: Record<string, string> = {};
6062

6163
if (existsSync("./_redirects.json")) {
62-
console.log(
63-
`redirectsMiddleware: Reading redirects from '_redirects.json'...`,
64+
log.debug(
65+
`${cliNow()} <cyan>redirectsMiddleware</cyan>: Reading redirects from '_redirects.json'...`,
6466
);
6567
const redirectsAsBytes = Deno.readFileSync("./_redirects.json");
6668
const redirectsAsString = new TextDecoder().decode(redirectsAsBytes);
6769
redirects = JSON.parse(redirectsAsString) as Record<string, string>;
6870
} else {
69-
console.log(`redirectsMiddleware: No './_redirects.json' found.`);
71+
log.warn(
72+
`${cliNow()} <cyan>redirectsMiddleware</cyan>: No './_redirects.json' found.`,
73+
);
7074
}
7175

72-
console.log(
73-
`redirectsMiddleware: Total number of redirects loaded: ${
76+
log.info(
77+
`${cliNow()} <cyan>redirectsMiddleware</cyan>: Total number of redirects loaded: ${
7478
Object.keys(redirects).length
7579
}.`,
7680
);
@@ -79,24 +83,30 @@ function loadFromJson() {
7983
}
8084

8185
function addGoLinksAndRedirectLinks(redirects: Record<string, string>) {
82-
console.log(`addGoLinksAndRedirectLinks: Adding additional redirects...`);
86+
log.debug(
87+
`${cliNow()} addGoLinksAndRedirectLinks: Adding additional redirects...`,
88+
);
8389

8490
redirects["/api/"] = "/api/deno/";
8591

86-
console.log(`redirectsMiddleware: Reading redirects from 'go.json'...`);
92+
log.debug(
93+
`${cliNow()} <cyan>redirectsMiddleware</cyan>: Reading redirects from 'go.json'...`,
94+
);
8795
for (const [name, url] of Object.entries(GO_LINKS)) {
8896
redirects[`/go/${name}/`] = url;
8997
}
9098

91-
console.log(`redirectsMiddleware: Reading redirects from 'oldurls.json'...`);
99+
log.debug(
100+
`${cliNow()} <cyan>redirectsMiddleware</cyan>: Reading redirects from 'oldurls.json'...`,
101+
);
92102
for (const [name, url] of Object.entries(REDIRECT_LINKS)) {
93103
redirects[name] = url;
94104
}
95105

96-
console.log(
97-
`addGoLinksAndRedirectLinks: Total number of redirects loaded: ${
106+
log.warn(
107+
`${cliNow()} <cyan>addGoLinksAndRedirectLinks</cyan>: Total number of redirects loaded: <green>${
98108
Object.keys(redirects).length
99-
}.`,
109+
}</green>.`,
100110
);
101111
}
102112

@@ -111,7 +121,9 @@ export function toFileAndInMemory(redirects: Redirect[], site: Site): void {
111121
redirectsSingleton[from] = to;
112122
}
113123

114-
console.log(`toFileAndInMemory: Added ${redirects.length} redirects.`);
124+
log.warn(
125+
`${cliNow()} <cyan>toFileAndInMemory</cyan> Added <green>${redirects.length}</green> redirects.`,
126+
);
115127

116128
addGoLinksAndRedirectLinks(redirectsSingleton);
117129
}

sidebar.client.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ for (const el of document.querySelectorAll("[data-accordion-trigger]")) {
1818
}
1919

2020
const sidebar = document.getElementById("sidebar");
21-
console.log(sidebar);
2221

2322
if (sidebar) {
2423
const sidebarNav = sidebar.querySelector("nav")!;

tabs.client.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,40 @@
1+
const tabGroups = document.querySelectorAll("deno-tabs");
2+
3+
for (const tabGroup of tabGroups) {
4+
const newGroup = document.createElement("div");
5+
newGroup.classList.add("deno-tabs");
6+
newGroup.dataset.id = tabGroup.getAttribute("group-id")!;
7+
8+
const buttons = document.createElement("ul");
9+
buttons.classList.add("deno-tabs-buttons");
10+
newGroup.appendChild(buttons);
11+
12+
const tabs = document.createElement("div");
13+
tabs.classList.add("deno-tabs-content");
14+
newGroup.appendChild(tabs);
15+
16+
for (const tab of tabGroup.children) {
17+
if (tab.tagName === "DENO-TAB") {
18+
const selected = tab.getAttribute("default") !== null;
19+
const buttonContainer = document.createElement("li");
20+
buttons.appendChild(buttonContainer);
21+
22+
const button = document.createElement("button");
23+
button.textContent = tab.getAttribute("label")!;
24+
button.dataset.tab = tab.getAttribute("value")!;
25+
button.dataset.active = String(selected);
26+
buttonContainer.appendChild(button);
27+
28+
const content = document.createElement("div");
29+
content.innerHTML = tab.innerHTML;
30+
content.dataset.tab = tab.getAttribute("value")!;
31+
content.dataset.active = String(selected);
32+
tabs.appendChild(content);
33+
}
34+
}
35+
tabGroup.replaceWith(newGroup);
36+
}
37+
138
class GroupSelectEvent extends Event {
239
groupId: string;
340
tabId: string;

timeUtils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export function cliNow() {
2+
const timeOnly = new Date().toLocaleTimeString();
3+
return `[${timeOnly}]`;
4+
}

0 commit comments

Comments
 (0)