diff --git a/docs/eleventy.config.cjs b/docs/eleventy.config.cjs index 30742369..3bfe7412 100644 --- a/docs/eleventy.config.cjs +++ b/docs/eleventy.config.cjs @@ -21,6 +21,12 @@ const assetsDir = 'assets'; const allComponents = getAllComponents(); let hasBuiltSearchIndex = false; +function benchmark (callback) { + const time = performance.now() + callback() + return performance.now() - time +} + module.exports = function (eleventyConfig) { // // Global data @@ -104,6 +110,19 @@ module.exports = function (eleventyConfig) { // // Transforms // + + let transformTimers = { + activeLinks: 0, + anchorHeadings: 0, + tableOfContents: 0, + codePreviews: 0, + externalLinks: 0, + highlightCodeBlock: 0, + scrollingTables: 0, + copyCodeButtons: 0, + typography: 0, + prettier: 0, + } eleventyConfig.addTransform('html-transform', function (content) { // Parse the template and get a Document object const doc = new JSDOM(content, { @@ -113,28 +132,57 @@ module.exports = function (eleventyConfig) { }).window.document; // DOM transforms - activeLinks(doc, { pathname: this.page.url }); - anchorHeadings(doc, { - within: '#content .content__body', - levels: ['h2', 'h3', 'h4', 'h5'] - }); - tableOfContents(doc, { - levels: ['h2', 'h3'], - container: '#content .content__toc > ul', - within: '#content .content__body' - }); - codePreviews(doc); - externalLinks(doc, { target: '_blank' }); - highlightCodeBlocks(doc); - scrollingTables(doc); - copyCodeButtons(doc); // must be after codePreviews + highlightCodeBlocks - typography(doc, '#content'); + transformTimers.activeLinks += benchmark(() => { + activeLinks(doc, { pathname: this.page.url }); + }) + + transformTimers.anchorHeadings += benchmark(() => { + anchorHeadings(doc, { + within: '#content .content__body', + levels: ['h2', 'h3', 'h4', 'h5'] + }); + }) + + transformTimers.tableOfContents += benchmark(() => { + tableOfContents(doc, { + levels: ['h2', 'h3'], + container: '#content .content__toc > ul', + within: '#content .content__body' + }); + }) + + + transformTimers.codePreviews += benchmark(() => { + codePreviews(doc); + }) + + transformTimers.externalLinks += benchmark(() => { + externalLinks(doc, { target: '_blank' }); + }) + + transformTimers.highlightCodeBlock += benchmark(() => { + highlightCodeBlocks(doc); + }) + + transformTimers.scrollingTables += benchmark(() => { + scrollingTables(doc); + }) + + transformTimers.copyCodeButtons += benchmark(() => { + copyCodeButtons(doc); // must be after codePreviews + highlightCodeBlocks + }) + + transformTimers.typography += benchmark(() => { + typography(doc, '#content'); + }) // Serialize the Document object to an HTML string and prepend the doctype content = `\n${doc.documentElement.outerHTML}`; // String transforms - content = prettier(content); + transformTimers.prettier += benchmark(() => { + content = prettier(content); + }) return content; }); @@ -191,6 +239,13 @@ module.exports = function (eleventyConfig) { fs.writeFileSync(searchIndexFilename, JSON.stringify({ searchIndex, map }), 'utf-8'); hasBuiltSearchIndex = true; + let totalTime = 0 + Object.entries(transformTimers).forEach(([k,v]) => { + const rounded = Math.ceil(v) + console.log(k + ": " + rounded + "ms") + totalTime += rounded + }) + console.log("Total transform time: " + totalTime + "ms") }); // @@ -199,7 +254,9 @@ module.exports = function (eleventyConfig) { eleventyConfig.setServerOptions({ domDiff: false, // disable dom diffing so custom elements don't break on reload, port: 4000, // if port 4000 is taken, 11ty will use the next one available - watch: [] // additional files to watch that will trigger server updates (array of paths or globs) + watch: [ + "dist/**/*.*" + ] // additional files to watch that will trigger server updates (array of paths or globs) }); // diff --git a/scripts/build.js b/scripts/build.js index 75154cfe..5faeb5a3 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -1,4 +1,4 @@ -import { execSync } from 'child_process'; +import { spawn, execSync } from 'child_process'; import getPort, { portNumbers } from 'get-port'; import { globby } from 'globby'; import { deleteSync } from 'del'; @@ -9,8 +9,15 @@ import esbuild from 'esbuild'; import fs from 'fs'; import copy from 'recursive-copy'; -function buildTheDocs() { - execSync('npx @11ty/eleventy', { stdio: 'inherit', cwd: 'docs' }); +const abortController = new AbortController(); +const abortSignal = abortController.signal; + +function buildTheDocs({ watch = false }) { + if (!watch) { + return execSync('npx @11ty/eleventy', { stdio: 'inherit', cwd: 'docs' }); + } + + return spawn('npx', ['@11ty/eleventy', '--watch', '--incremental'], { stdio: 'inherit', cwd: 'docs', signal: abortSignal }); } const { bundle, copydir, dir, serve, types } = commandLineArgs([ @@ -26,10 +33,9 @@ const outdir = dir; deleteSync(outdir); fs.mkdirSync(outdir, { recursive: true }); -(async () => { +;(async () => { try { execSync(`node scripts/make-metadata.js --outdir "${outdir}"`, { stdio: 'inherit' }); - execSync(`node scripts/make-search.js --outdir "${outdir}"`, { stdio: 'inherit' }); execSync(`node scripts/make-react.js --outdir "${outdir}"`, { stdio: 'inherit' }); execSync(`node scripts/make-web-types.js --outdir "${outdir}"`, { stdio: 'inherit' }); execSync(`node scripts/make-themes.js --outdir "${outdir}"`, { stdio: 'inherit' }); @@ -102,7 +108,7 @@ fs.mkdirSync(outdir, { recursive: true }); if (serve) { // Dev - buildTheDocs(); + buildTheDocs({ watch: true }); const bs = browserSync.create(); const port = await getPort({ @@ -135,6 +141,7 @@ fs.mkdirSync(outdir, { recursive: true }); // Rebuild and reload when source files change bs.watch(['src/**/!(*.test).*']).on('change', async filename => { console.log(`Source file changed - ${filename}`); + buildResult // Rebuild and reload .rebuild() @@ -157,11 +164,11 @@ fs.mkdirSync(outdir, { recursive: true }); }); // Reload without rebuilding when the docs change - bs.watch(['docs/**/*']).on('change', filename => { + bs.watch(['_site/**/*.*']).on('change', async (filename) => { console.log(`File changed - ${filename}`); - execSync(`node scripts/make-search.js --outdir "${outdir}"`, { stdio: 'inherit' }); - buildTheDocs(); - bs.reload(); + + // TODO: I tried writing a debounce here, but it wasnt working -.- + bs.reload() }); } else { // Prod build @@ -169,5 +176,8 @@ fs.mkdirSync(outdir, { recursive: true }); } // Cleanup on exit - process.on('SIGTERM', () => buildResult.rebuild.dispose()); + process.on('SIGTERM', () => { + buildResult.rebuild.dispose() + abortController.abort(); // Stops the child process + }); })(); diff --git a/scripts/make-search.js b/scripts/make-search.js index ca03c6fa..c5c13d71 100644 --- a/scripts/make-search.js +++ b/scripts/make-search.js @@ -10,7 +10,7 @@ const metadata = JSON.parse(fs.readFileSync(path.join(outdir, 'custom-elements.j console.log('Generating search index for documentation'); -(async () => { +;(async () => { function getHeadings(markdown, maxLevel = 6) { const headings = []; const lines = markdown.split('\n');