perf: compute mapping of folder name to file data for faster breadcrumbs
This commit is contained in:
parent
d1551872ff
commit
43d638a6de
@ -16,10 +16,10 @@ For example, here's what the default configuration looks like:
|
|||||||
|
|
||||||
```typescript title="quartz.layout.ts"
|
```typescript title="quartz.layout.ts"
|
||||||
Component.Breadcrumbs({
|
Component.Breadcrumbs({
|
||||||
spacerSymbol: ">", // symbol between crumbs
|
spacerSymbol: "❯", // symbol between crumbs
|
||||||
rootName: "Home", // name of first/root element
|
rootName: "Home", // name of first/root element
|
||||||
resolveFrontmatterTitle: false, // wether to resolve folder names through frontmatter titles (more computationally expensive)
|
resolveFrontmatterTitle: true, // whether to resolve folder names through frontmatter titles
|
||||||
hideOnRoot: true, // wether to hide breadcrumbs on root `index.md` page
|
hideOnRoot: true, // whether to hide breadcrumbs on root `index.md` page
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -41,25 +41,13 @@ function formatCrumb(displayName: string, baseSlug: FullSlug, currentSlug: Simpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// given a folderName (e.g. "features"), search for the corresponding `index.md` file
|
|
||||||
function findCurrentFile(allFiles: QuartzPluginData[], folderName: string) {
|
|
||||||
return allFiles.find((file) => {
|
|
||||||
if (file.slug?.endsWith("index")) {
|
|
||||||
const folderParts = file.filePath?.split("/")
|
|
||||||
if (folderParts) {
|
|
||||||
const name = folderParts[folderParts?.length - 2]
|
|
||||||
if (name === folderName) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ((opts?: Partial<BreadcrumbOptions>) => {
|
export default ((opts?: Partial<BreadcrumbOptions>) => {
|
||||||
// Merge options with defaults
|
// Merge options with defaults
|
||||||
const options: BreadcrumbOptions = { ...defaultOptions, ...opts }
|
const options: BreadcrumbOptions = { ...defaultOptions, ...opts }
|
||||||
|
|
||||||
|
// computed index of folder name to its associated file data
|
||||||
|
let folderIndex: Map<string, QuartzPluginData> | undefined
|
||||||
|
|
||||||
function Breadcrumbs({ fileData, allFiles, displayClass }: QuartzComponentProps) {
|
function Breadcrumbs({ fileData, allFiles, displayClass }: QuartzComponentProps) {
|
||||||
// Hide crumbs on root if enabled
|
// Hide crumbs on root if enabled
|
||||||
if (options.hideOnRoot && fileData.slug === "index") {
|
if (options.hideOnRoot && fileData.slug === "index") {
|
||||||
@ -70,28 +58,39 @@ export default ((opts?: Partial<BreadcrumbOptions>) => {
|
|||||||
const firstEntry = formatCrumb(options.rootName, fileData.slug!, "/" as SimpleSlug)
|
const firstEntry = formatCrumb(options.rootName, fileData.slug!, "/" as SimpleSlug)
|
||||||
const crumbs: CrumbData[] = [firstEntry]
|
const crumbs: CrumbData[] = [firstEntry]
|
||||||
|
|
||||||
|
if (!folderIndex && options.resolveFrontmatterTitle) {
|
||||||
|
folderIndex = new Map()
|
||||||
|
// construct the index for the first time
|
||||||
|
for (const file of allFiles) {
|
||||||
|
if (file.slug?.endsWith("index")) {
|
||||||
|
const folderParts = file.filePath?.split("/")
|
||||||
|
if (folderParts) {
|
||||||
|
const folderName = folderParts[folderParts?.length - 2]
|
||||||
|
folderIndex.set(folderName, file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Split slug into hierarchy/parts
|
// Split slug into hierarchy/parts
|
||||||
const slugParts = fileData.slug?.split("/")
|
const slugParts = fileData.slug?.split("/")
|
||||||
if (slugParts) {
|
if (slugParts) {
|
||||||
// full path until current part
|
// full path until current part
|
||||||
let currentPath = ""
|
let currentPath = ""
|
||||||
for (let i = 0; i < slugParts.length - 1; i++) {
|
for (let i = 0; i < slugParts.length - 1; i++) {
|
||||||
let currentTitle = slugParts[i]
|
let curPathSegment = slugParts[i]
|
||||||
|
|
||||||
// TODO: performance optimizations/memoizing
|
|
||||||
// Try to resolve frontmatter folder title
|
// Try to resolve frontmatter folder title
|
||||||
if (options?.resolveFrontmatterTitle) {
|
const currentFile = folderIndex?.get(curPathSegment)
|
||||||
// try to find file for current path
|
|
||||||
const currentFile = findCurrentFile(allFiles, currentTitle)
|
|
||||||
if (currentFile) {
|
if (currentFile) {
|
||||||
currentTitle = currentFile.frontmatter!.title
|
curPathSegment = currentFile.frontmatter!.title
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add current slug to full path
|
// Add current slug to full path
|
||||||
currentPath += slugParts[i] + "/"
|
currentPath += slugParts[i] + "/"
|
||||||
|
|
||||||
// Format and add current crumb
|
// Format and add current crumb
|
||||||
const crumb = formatCrumb(currentTitle, fileData.slug!, currentPath as SimpleSlug)
|
const crumb = formatCrumb(curPathSegment, fileData.slug!, currentPath as SimpleSlug)
|
||||||
crumbs.push(crumb)
|
crumbs.push(crumb)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user