It's not that I don't like the templating format. In fact I really like the format.
But I'm obsessed with performance and changes in how nodejs is done (thanks to ES6) has made me start to think more critically about how I code in terms of how I measure performance.
The measure I use for performance is different than other people. My criteria for a properly built applications are...
- Uses the bare minimum ram except for things cached that actually improve performance.
- Instant upstart, usualying involving what I call lazy starting.
- Product delivered to the client is correct.
- Is always asynchronous
So I had coded my own wrapper to pug a long time ago, back when it was called jade, and I'm glad I did for reasons I will get into later. But what it does is returns a function that takes (httprequest, httpresult, options) and compiles the file when it is first needed.
This means that the server is ready to run right away in spite of the fact that there is a lot of pug on it that won't get used that often but still might get used.
Well this has become a problem with ES6 because I do have a little bit of inline javascript (conditional javascript that either exists or doesn't based on an option fed to the template).
Well I like ES6 features but I noticed that it was breaking some devices. So I needed to put babel into the mix. It's pretty easy.
In terms of pug it's just converting:
doctype html
html
head
script.
$(()=>{
//do something
});
to
doctype html
html
head
script
:babel
$(()=>{
//do something
});
You only have to configure your babel rc to do the correct conversion. This would also allow you to embed react. Also with some more babel you can actually embed pug into react so you could embed pugish react into your pug.
But this is a problem for my lazy compilation. Now the first user to access a particular page on a server after a restart has to wait about 10 seconds which makes it seem like the host just isn't working. Unacceptable.
So long to the short I started digging through the code to try to code a solution around this. I wanted to create something I would call a .pugs file that is pug but could be simplified down into something the server could load lazy very fast. Ideally I would like it to output an es5 version of the pug but I don't need that and I've realized that can't be done. All I really care is that it can be loaded into a functioning template.
So then the goal was to look at what the internal representation of the template is after it is compiled. You can't read that without looking at the code because the returned function is a clousure.
So what do I find when I read the code? fs.readFileSync. It's been violating my performance standards this whole time and it's creating a mess for maintaining them with es6.
So what I'm tempted to do is rewrite pug to my standards, including asynronous file reads, automatic lazy file compilation and watching, the ability to cache internal representation to disk for quick restart, and I'll even throw lazy requires in there while I'm at it...
Or I could just pick up a new template engine that does 90% of what I need without doing that.
(post is archived)