aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorValentin Gagarin <valentin.gagarin@tweag.io>2022-09-08 11:57:49 +0200
committerValentin Gagarin <valentin.gagarin@tweag.io>2022-09-08 11:58:43 +0200
commit548c904d4007bbf6d03ebe06d700af0b96e976f1 (patch)
treea7a7466b1f5804719be94e3843148ba390cb8ab8
parent59be1e500a24c9e7970fabcc97bad5280300061c (diff)
optimize performance
remove loops and function calls, modify arrays in place this makes the whole thing harder to read, and probably only marginally faster.
-rw-r--r--doc/manual/redirects.js141
1 files changed, 75 insertions, 66 deletions
diff --git a/doc/manual/redirects.js b/doc/manual/redirects.js
index 45fbfffab..af3fc8782 100644
--- a/doc/manual/redirects.js
+++ b/doc/manual/redirects.js
@@ -1,9 +1,12 @@
-// Redirect rules for anchors ensure backwards compatibility of URLs.
-// This must be done on the client side, as web servers do not see the anchor part of the URL.
+// redirect rules for anchors ensure backwards compatibility of URLs.
+// this must be done on the client side, as web servers do not see the anchor part of the URL.
-// Redirections are declared as follows:
-// Each entry has as key the matched URL path relative to the mdBook document root.
-// Each entry is a set of key-value pairs, where
+// redirections are declared as follows:
+// each entry has as key the matched URL path relative to the mdBook document root.
+//
+// IMPORTANT: it must specify the full path with file name and suffix
+//
+// each entry is a set of key-value pairs, where
// - keys are anchors on to the matched path.
// - values are redirection targets relative to the current path.
@@ -332,7 +335,7 @@ var redirects = {
"ssec-relnotes-2.2": "release-notes/rl-2.2.html",
"ssec-relnotes-2.3": "release-notes/rl-2.3.html"
},
- "language/values": {
+ "language/values.html": {
"simple-values": "#primitives",
"lists": "#list",
"strings": "#string",
@@ -341,73 +344,79 @@ var redirects = {
}
};
+// the following code matches the current page's URL against the set of redirects.
+//
+// it is written to minimize the latency between page load and redirect.
+// therefore we avoid function calls, copying data, and unnecessary loops.
+// IMPORTANT: we use stateful array operations and their order matters!
+//
+// matching URLs is more involved than it should be:
+//
+// 1. `document.location.pathname` can have an have an arbitrary prefix.
+//
+// 2. `path_to_root` is set by mdBook and consists only of `../`s and
+// determines the depth of `<path>` relative to the prefix:
+//
+// `document.location.pathname`
+// |------------------------------|
+// /<prefix>/<path>/[<file>[.html]][#<anchor>]
+// |----|
+// `path_to_root` has same number of segments
+//
+// source: https://phaiax.github.io/mdBook/format/theme/index-hbs.html#data
+//
+// 3. the following paths are equivalent:
+//
+// /foo/bar/
+// /foo/bar/index.html
+// /foo/bar/index
+//
+// 4. the following paths are also equivalent:
+//
+// /foo/bar/baz
+// /foo/bar/baz.html
+//
-function pathsMatch(a, b, path_to_root) {
- // Do paths `a` and `b` match?
- //
- // This is more involved than it should be:
- //
- // 1. Path `b` can have an have an arbitrary prefix.
- //
- // 2. `path_to_root` consists only of `../`s and determines the depth
- // of `b` relative to the prefix:
- //
- // `document.location.pathname`
- // |-----------------------------|
- // <prefix>/<path>/[<file>[.html]][#<anchor>]
- // |----|
- // `path_to_root` has same number of segments
- //
- // 3. The following paths are equivalent:
- //
- // foo/bar/
- // foo/bar/index.html
- // foo/bar/index
- //
- // 4. The following paths are also equivalent:
- //
- // foo/bar/baz
- // foo/bar/baz.html
- //
- // We can use `path_to_root` to discern prefix from path.
- //
- // The last element of the following split is always empty.
- // Example: '../../'.split('/') -> [ '..', '..', '' ]
- const depth = path_to_root.split('/').length - 1;
- var segmentsB = b.split('/');
- // get file name of `b`
- const fileB = segmentsB.pop(); // mutates `segmentsB`!
- // get path of `b` without prefix and file name
- const pathB = segmentsB.slice(segmentsB.length - depth).join('/');
+var segments = document.location.pathname.split('/');
- var segmentsA = a.split('/');
- const fileA = segmentsA.pop(); // mutates `segmentsA`!
- const pathA = segmentsA.join('/')
+var file = segments.pop();
- function normalize(file) {
- if (file === '') { return "index.html"; }
- if (!file.endsWith('.html')) { return file + '.html'; }
- return file;
- }
+// normalize file name
+if (file === '') { file = "index.html"; }
+else if (!file.endsWith('.html')) { file = file + '.html'; }
- return pathA === pathB && normalize(fileA) === normalize(fileB);
-}
+segments.push(file);
+
+// use `path_to_root` to discern prefix from path.
+const depth = path_to_root.split('/').length;
+
+// remove segments containing prefix. the following works because
+// 1. the original `document.location.pathname` is absolute,
+// hence first element of `segments` is always empty.
+// 2. last element of splitting `path_to_root` is also always empty.
+// 3. last element of `segments` is the file name.
+//
+// visual example:
+//
+// '/foo/bar/baz.html'.split('/') -> [ '', 'foo', 'bar', 'baz.html' ]
+// '../'.split('/') -> [ '..', '' ]
+//
+// the following operations will then result in
+//
+// path = 'bar/baz.html'
+//
+segments.splice(0, segments.length - depth);
+const path = segments.join('/');
-// The anchor starts with the hash character (`#`),
+// anchor starts with the hash character (`#`),
// but our redirect declarations don't, so we strip it.
-// Example: document.location.hash -> '#foo'
+// example: document.location.hash -> '#foo'
const anchor = document.location.hash.substring(1);
-for (const [path, redirect] of Object.entries(redirects)) {
- // The global variable `path_to_root` is set by `mdBook`:
- //
- // > This is a path containing exclusively `../`'s that points to the root of the
- // > book from the current file. Since the original directory structure is
- // > maintained, it is useful to prepend relative links with this `path_to_root`.
- //
- // Source: https://phaiax.github.io/mdBook/format/theme/index-hbs.html#data
- if (pathsMatch(path, document.location.pathname, path_to_root) && redirect[anchor]) {
- document.location.href = redirect[anchor];
- break;
+const redirect = redirects[path];
+if (redirect) {
+ const target = redirect[anchor];
+ if (target) {
+ document.location.href = target;
}
}