DEV Community

loading...

Zero Cost Abstractions in Web Development

fctorial profile image fctorial Originally published at fctorial.github.io ・3 min read

What is constexpr?

Constexpr is a feature found in statically compiled programming languages that allows evaluation of expressions in a program at compile time. Different languages have different terminology for it. For example, in zig lang, it's called comptime. Common lisp macros, in lisps that compile to native code, might also be grouped in this category.

This feature allows automatic generation of complex static data at compile time, and the runtime code can just use the result of compile time evaluated data. Variable inlining is a simple form of compile time evaluation.
Ideally, the language/compiler should allow the users to turn any eligible piece of code "constexpr" with some annotations. The eligibility criteria being that the code must not depend on any runtime data.

What is constexpr.js?

constexpr.js is a tool that allows you to execute parts of javascript in your website before deployment. You can use it like a static site generator, as I do for this website. It's different from SSG's like Jakyll in that it doesn't force you to learn a dedicated domain specific language. There already exists a dedicated languages for dealing with DOM and webpages, javascript. With constexpr.js, you use javascript and usual DOM manipulation methods to generate the website. The whole browser runtime is available at your disposal when generating sites with constexpr.js.

Demo

This website

How does it work?

The compiler renders the pages using chrome, and once they finish rendering, it saves the rendered state as new pages. It also strips out the javascript that was used for generating HTML, potentially reducing download size for the website users drastically. Any piece of javascript code that just generates some HTML can be made constexpr.

The generated pages don't have to be completely static. For example, disqus integration in this page.

The new website will look exactly like the original website after the pages finish rendering. This is one of the basic principles of constexpr.js. So you can build your website as usual and run the compiler once you're happy with the results, and you'll get a leaner, faster version of your website as output.

How to use it?

You will have to divide the javascript being used in your page into two groups. Runtime javascript and compile time javascript, and annotate all compile time script tags with constexpr attribute:

<script constexpr>
...
</script>
<script constexpr src="/generate_page.js"></script>
Enter fullscreen mode Exit fullscreen mode

Runtime code must not depend on the compile time code, since that code will be stripped out before writing the output file. See this guide for code organization tips for constexpr.js.

Once the HTML generation code has finished rendering, it must call the window._ConstexprJS_.compile() function. This function is injected into the page by the compiler.

The compiler can be installed from npm:

npm i -g constexpr.js@latest
Enter fullscreen mode Exit fullscreen mode

Command line usage:

$ constexpr.js --help
usage: constexpr.js [-h] [-v] --input INPUT_DIRECTORY --output OUTPUT_DIRECTORY [--entry ENTRYPOINTS] [--skip-resources] [--jobcount JOBCOUNT] [--jobtimeout JOBTIMEOUT] [--depfile DEPFILE] [--noheadless] [--verbose]

Zero cost abstractions for web development

optional arguments:
  -h, --help            show this help message and exit
  -v, --version         show program's version number and exit
  --input INPUT_DIRECTORY
                        Input website root directory
  --output OUTPUT_DIRECTORY
                        Output directory
  --entry ENTRYPOINTS   Add an HTML file to be used as entry point, paths must be relative to the website root, can be used multiple times, must provide at least one entry point
  --skip-resources      Do not copy resources to the output directory
  --jobcount JOBCOUNT   Number of compilation jobs to run in parallel
  --jobtimeout JOBTIMEOUT
                        Time in milliseconds for which the compiler will wait for the pages to render
  --depfile DEPFILE     A JSON object containing the command line arguments, file dependency, compilation results will be written to this path
  --noheadless          Do not run chrome in headless mode, can be used for debugging using browser console
  --verbose             Enable verbose logging
Enter fullscreen mode Exit fullscreen mode

The compiler also copies resources (css, images etcetra) that are requested by pages being rendered (unless --skip-resources option is specified).

Plugins

You can use any web development technology (and any number of technologies) to generate the HTML without any fear of bloat. The demo website uses a total of 6mb of javascript for stuff like syntax highlighting, latex rendering, and graphviz that you don't have to download or execute because it's constexpr.

See pages tagged with constexpr.js for documentation.

Discussion (0)

pic
Editor guide