I would like to propose a change to JBake that allows a much more incremental approach to baking changes, both with the existence of a cache, as well in watch mode. For instance, my local bakes for my personal blog/website take 39.6 seconds without a cache, 28.8 with a cache, and in watch mode, it takes 23 seconds to rebake, even if I changed a single css file. I see huge opportunities to improve this performance.
My proposal is to make two changes to how JBake builds: improve bake performance with a cache and single file bakes.
When looking at my bake performance numbers above, a third of that time is spent copying all of the assets to the output directory, everytime. I would like to identify a method of only copying assets that have changed. My initial look through the code shows me that that only changed content is re-rendered if a cached version exists, so I would like to apply this same approach to assets. Another third of the bake time is spent re-rendering content (like tags) that hasn't changed and doesn't need to be re-rendered. I would like to tag, archive, sitemap and other site-wide content to be generated only as needed. This change feels a bit more invasive, so I wanted to get thoughts before digging deep. This change will improve JBake's performance when running the bake command from a warm cache.
For the second change would be to enable the baking of a single file at a time. This change would be to improve the performance of watch mode. I went ahead and started making changes in this directory on a fork of JBake and also see huge performance improvements. Changing a single css file when running jbake in server mode goes from 23 second wait times to a bake time of 33 milliseconds! This is huge. Assets are the easiest to address since they only involve a copy. I will be looking into the content changes next, as this will drive me into more invasive changes. For template changes, we could also be smarter about only rebaking content that uses that template, but I will likely re-bake everything in my first sweep of this.
For both of these changes, I would like to implement them in a manner that would also enable the Gradle plugin to take advantage of the performance improvements as well.