Configuring Ubuntu 17.10 to behave like Unity

I've recently upgraded from Ubuntu 16.04 to Ubuntu 17.10. The new Ubuntu uses Gnome desktop by default instead of Unity. Gnome is quite different but luckily can be customized to match Unity's behaviour very closely. Here is how.

Ubuntu17 like unity

Read more

Database-agnostic case-insensitive equality, full text search

Different relational databases treat text search very differently. The new DbTextSearch gem provides a unified interface on top of ActiveRecord for SQLite, MySQL, and PostgreSQL to do:

  • Case-insensitive string-in-set querying, and CI index creation.
  • Basic full-text search for a list of terms, and FTS index creation.

DbTextSearch does all the heavy lifting under the hood, hiding the complexity of handling each database differently away, which is great for gem authors, when migrating an application from one database to another, or writing code that must support multiple databases.

Read more

Internationalization made easier with static analysis

i18n-tasks finds and manages missing and unused translations in your application. The default approach to locale data management with gems such as i18n is flawed. If you use a key that does not exist, this will only blow up at runtime. Keys left over from removed code accumulate in the resource files and introduce unnecessary overhead on the translators. Translation files can quickly turn to disarray.

i18n-tasks improves this by using static analysis. It scans calls such as I18n.t('some.key') and provides reports on key usage, missing, and unused keys. It can also can pre-fill missing keys, including from Google Translate, and it can remove unused keys as well.

i18n-tasks can be used with any project using i18n (default in Rails).

Read more

Save Redis memory with large list packing

Redis is great for storing certain types of data that do not do well in a relational database. It is great for storing caches and statistics too. However, the storage capacity of redis is capped by RAM size, so care is required when storing large amounts of data in it.

I will show you a trick to reduce memory usage and improve the speed of the redis list type for storing series-type data (e.g. time series). Redis packs small lists of ints, reducing their memory usage by 10-40%. The exact list size threshold at which redis stops compressing is defined by the list-max-ziplist-entries setting and defaults to 512.

Here is the trick: we will transparently partition a list into many small lists of list-max-ziplist-entries size. By storing lists under the threshold, we take advantage of redis' ability to pack them.

Read more

Inline CSS web fonts

If you serve web fonts via URL, the browser makes a separate request for every web font.

This is what the timeline looks like for a URL referenced font:

Tl body

Ready Load

Fonts included from stylesheets cause extra requests that only starts once the DOM has loaded. This causes a delay and flash of missing text or a font change flash while the fonts are loading.

However, you can avoid extra requests and rendering issues if you inline the fonts as data-uris.

Read more

Store screenshots of your web app in Git

Have you ever had a change break your site? Even when the tests pass?

  • Testing functionality is hard
  • Testing UI is even harder

What if every time you commit, you got a visual diff of every web page that changed? It is surprisingly easy to do.

Gh img diff 1

Read more