A few days ago I updated a blog entry by adding a new screenshot of a StackOverflow page. I got to thinking about the size of that image, and that in 2016 we should be able to do better with a markup language, for such things, for faster page loads.

Here is the JPEG of the screenshot from the previous blog entry:

That was 190KB originally as a PNG, and 109KB as the JPEG after being transformed on my Mac.

A workflow for HTML screehshots.

In Chrome you can select bits and pieces of a page and paste them elsewhere. Most receiving destinations for that clipbaord action only accept the plain text, which is not what we want. Chrome though can accept the pasting of the actual HTML. Better yet Chrome:

  1. fixes the html to be balanced
  2. processes it to use inlined styles rather than CSS
  3. drops all JavaScript

At least it does as you’re pasting it into the “new email” dialog in Gmail on a PC/Mac. If you send it to yourself in Gmail you get to see a preview of what that looks like.

Now, in Gmail you can use “show original” to see the source for that. The thing you want is in the wmail twice - once as plain text (mobile clients prefer that) and once as HTML. That’s the one you want.

You’ll see it with a weird encoding, though:

Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Using a webapp at webatic.com you can turn that encoded HTML chunk back into something that’s more regular.

Your next problem is that anchors (hyperlinks) are still in the HTML. As you’re wanting a screenshot for a blog entry, you don’t want those. I just removed them with a regex find/replace operation in a decent editor (WebStorm for me). I also removed some classes that only Gmail needed, and left it at that.

With a final addition of “unstyle” as a class on the outmost div (the coresponding css is ‘all: revert;’) to get bootstrap out of the way, I pasted it into a markdown blog entry (Github-Pages Jekyll supports inlined HTML), and here it is:

Type to find tags:

× 213640
an open-source JavaScript framework. Its goal is to augment browser-based applications with Model–View–Whatever (MV*) capability and reduce the amount of JavaScript n…
× 30189
The second version of the AngularJS web framework. Angular 2 takes a web component-based approach to building powerful applications for the web. It is used along with TypeScript which provides suppor…
× 15336
a way to teach HTML new tricks by extending the HTML vocabulary. Directives allow you to manage DOM elements in a declarative pattern, freeing you from low level DOM manipulat…
× 7963
an object that refers to the application model. It is an execution context for expressions.
× 7710
UI-Router evolves the concept of an AngularJS Route into a more general concept of a State for managing complex application UI states. Most notably, it allows nested state/view hierarchies and multipl…
× 5959
The `ngRepeat` directive instantiates a template once per item from a collection. Each template instance gets its own scope, where the given loop variable is set to the current collection item, and `$…
× 3679
A set of AngularJS directives based on Twitter Bootstrap's markup and CSS
× 2670
an implementation of Material Design in Angular.js. This project provides a set of reusable, well-tested, and accessible UI components based on the Material Design syst…
× 2665
the enhancement companion suite to the AngularJS framework. It contains UI widgets and directives that are not part of the AngularJS core but are commonly needed in a project.
× 2095
a feature under Angular 2 focusing on routing your users' requests to load different pages and components based on user action, It also provides feature to update the URL on the b…
× 1720
an officially supported AngularJS binding for Firebase which is a cloud database designed to power real-time, collaborative applications. So you don't need servers to build your Angular…
× 1630
a datagrid written in AngularJS by the AngularUI Team. This is the 3.x version of the former ng-grid. It is a high-performant datagrid using virtualization for rendering row…
× 1401
singletons that carry out specific tasks common to web apps. AngularJS provides a range of built-in services, along with the ability to create custom services as required. Servi…
× 1394
Angular's $q promises provide a powerful abstraction over flow control - see [the official documentation](https://docs.angularjs.org/api/ng/service/$q). If you tag your question with this tag consider…
× 1192
The built-in routing module in AngularJS, which can map the browser URL to a defined route.
× 1084
The AngularJS controller exposes the data that is to be displayed into the HTML view. It plays the essential role of the ModelView in the MVVM design pattern. The view is a part of the HTML template…

The blog page is under 10K gzipped, including the screenshot, so that’s good.

My new problem is it doesn’t look pixel perfect. Perhaps it never could be perfect with a markup language rather than bitmap. But some basics like getting the height of rows correct would be nice. I suspect I could do some magic with viewports and getting the thing to scale to the container of my blog. That would get it closer to an ideal, but it is a lot of work.

I will also be annoying the DZone people who syndicate a lot of my blog entries. I think copy/paste is part of their workflow, and nothing about copying a html table into another CMS is going to be easy.

SVG, browser plugins/add-ons ?

Maybe SVG is a better markup for this than HTML, if a precise replication is needed. Maybe too it should really be a browser plugin, and a single operation.


January 1st, 2017