Nov 28,
2016

Re-Design

In the last few days I've spent some time to create a new Pelican theme because what I was using before was unreadable on small screens. So the pages you are now reading are certified mobile-friendly1.

I started from scratch using Twitter's Bootstrap as a base, nonetheless what I thought would be a weekend project kept me busy more than I expected, as I found myself continually tweaking the CSS code for inane little details, again and again, like for example, deciding the right amount of space between text lines or choosing the proper shade of gray for a button or a heading.

It probably still has some rough edges as I didn't tested it on a wide range of platforms2.

Ugly hacks

Taming Bootstrap to do things only slightly differently than the default layout was quite time consuming as I didn't know the framework, but the only hack I've used was to override the grid-float-breakpoint variable with a "reasonable" high value to force the navigation bar to stay collapsed on large desktops; in other words I wanted the "hamburger" menu always displayed. If my reader is now thinking -"That's appearance over usability!"- I suppose I could agree with him, anyway I like it better this way.

That and the use of the grid system to force a "narrow" text column slightly off center on the page, and to be honest it doesn't work that well when re-sizing the browser window as the text is jumping a little too much for my taste.

On the Pelican front the development was much faster, in part because I decided for a simple layout and in part because I've only created a small subset of the templates that are listed in the documentation. This means that without some editing it couldn't be used as a drop in replacement for, as an example, the default theme. But that wasn't my objective. I would like to point out that I have enabled the UNIQUE_IDS option to use footnotes freely with the MarkDown's Footnotes extension; it wasn't difficult to find out but the class name to import lacks an "s":

# MarkDown extensions
from markdown.extensions.codehilite import CodeHiliteExtension
from markdown.extensions.footnotes import FootnoteExtension
MD_EXTENSIONS = [
    'markdown.extensions.extra',
    CodeHiliteExtension(css_class='highlight', linenums=False, pygments_style='monokai'),
    FootnoteExtension(UNIQUE_IDS=True),
]

To give a little more details about my workflow, I started drafting a mock index page using Bootply, but I soon ended up editing the HTML file directly as I was getting frustrated by the limitations of the visual approach. This wasn't painful as the Bootstrap documentation is top-notch, with basically every combination of widgets displayed. Once I was satisfied with the mock appearance, I started creating the Pelican's base.html template, adding the elements I needed for the index.html, so the header, the navigation bar, the articles content, a tag indexer, a pager and finally a footer. The archives page is a simple lists of all the articles in chronological order, and finally there are a couple of static pages like the about and HTML error pages like 403 and 404 codes.

Lean pages

I noticed that the CSS file was nearly 150 KiB of size, not outrageously huge, but nonetheless in my particular case it included a lot of unused descriptors. I was ready to tackle it programmatically, but first I searched if someone had solved this problem before. I've found a couple of Python utilities, anyway I tried with one available for Node.js called UnCSS, that seems to do its job, as the Bootstrap's CSS file was reduced to a more reasonable size of 20 KiB. My only advice when using UnCSS is to manually pass the option to ignore descriptors used by user's actions, for example collapsing or fading elements linked to input events as they are not examined by the utility.


  1. according to Google. ↩︎

  2. guess what? Broken on IE8, it chokes on Javascript. ↩︎

 
 

Sep 18,
2016

New Emacs

A new Emacs version was declared stable yesterday, the last major revision was released in 2012 so it's quite the occasion.

A few years ago I've started building it from source instead to depend on binary packages, mostly because I couldn't find a recent version on the Debian repositories. All things considered the process was less tedious than I feared.

The following is more of a personal note on what I need to remember the next time I decide do install a new version or minor release, but it can convince the reader that is not so scary.

To ensure I have a suitable build environment, I install the "dev" dependencies reported in the Debian packages, usually this is enough unless a new feature is integrated, for example the new release has support for Cairo drawing or Xwidgets. For sure all the required info can be found in the release notes. Once downloaded the sources and applied eventual patches, it's the usual configure; make; make install if extracted from a tar archive, autogen.sh should be required only when pulling directly from the git repository:

$ ./autogen.sh
$ ./configure --prefix=/opt/emacs25.1
$ make
$ sudo make install

Now the install part of the makefile should ask to set movemail as setuid root; I don't use Emacs to read email, but I usually run the command when prompted.

The last thing I do is creating a symbolic link for emacs and emacsclient in /usr/local/bin and checking that the path in my emacs.desktop and emacsclient.desktop files in ~/.local/share/applications are pointing to the correct executable.

Done.

 
 

Jul 11,
2016

Emacs startup time shaving

I wanted to streamline my Emacs configuration, so after a little of yak shaving, all the Emacs packages that I'm using are now configured to be lazy-loaded on demand. Basically I removed all the "require" instances, if we don't count the library that manages the packages.

This also took care of sensibly reducing the start-up time. I couldn't find my notes, but I think it went from around 2 seconds to probably 1.5 seconds, using emacs-init-time as reference.

I wasn't surprised to find available libraries to benchmark or trace Emacs' functions and ready made solutions to profile the start-up sequence like the The Emacs Startup Profiler (ESUP) or ProfileDotEmacs. So after using ProfileDotEmacs I've found out that, in my case, packages initialization is the most expensive operation with a combined 0.49 seconds or 64% of the total time, while my customization need 0.18 seconds to complete, 23% in percentage. This means that further tweaking the customization can give small gains.

Micromanagement

Recently I found a couple of suggestions to speed up the start-up sequence. One is to temporarily increase the activation threshold of the garbage collector, the other is to temporarily disable the handling of the magic file names when starting up.

The first one can be implemented like this:

;; temporarily increasing GC to speedup startup time
(setq gc-cons-threshold-default gc-cons-threshold)
(setq gc-cons-threshold (* 100 1024 1024))
(run-with-idle-timer
 2 nil
 (lambda ()
   ;; restore default GC value
   (setq gc-cons-threshold gc-cons-threshold-default)
   ;; clean up minibuffer
   (message nil)))

The value is increased from 800 KB to 100 MB and restored after a couple of seconds1. With this change I measured a reduction of around 0.3 seconds.

The second suggestion consists in wrapping the init.el file like this:

;; temporarily disable file name check to speedup startup time
(let ((file-name-handler-alist nil))
   ...
   the init file content
   ...
)

In my case this one removes about 0.1 seconds, the gain is quite modest but it doesn't clutter too much the init.el file so I decided to left it there.

In the end, according to emacs-init-time the start-up needs 1.1~1.2 seconds.

Dumping

After seeing that the biggest part of the start-up is spent enabling packages, I tried to include the package.el library in the dumped binary, but without success. Probably the reader is not aware how the Emacs executable is created, so in few words, during the build process a bare-bone Emacs instance called Temacs evaluate a file called loadup.el that loads the required elisp libraries and at the end the working environment is dumped in a file. This file is the executable that is run when Emacs is invoked.

After the little digression, package.el depends on cl-lib.el but this one fails on load with the error "Wrong type argument: stringp, 0". The problem is I'm not able to activate the Temacs' debugger, I'm surely doing something wrong because trying temacs -q doesn't drop me in the editor but insists always to evaluate the loadup.el file that triggers the error.

I'll look at it again another time, for the moment I'll stick with emacsclient.


  1. plenty of time to complete the start-up. ↩︎