This website looks very simple to the eye. Simple black/white color aesthetic and simple functionality (blog and gallery for the most part). But, I spent a considerable amount of time achieving the result shown today, and it will probably change in the future.
Every website requires some server space to host, receive, process, and deliver data. Originally, I developed a few smaller websites on free hosts such as 000webhost and YouHosting resellers (somewhat useful for testing production websites, but not really recommended). These shared hosts with simple PHP, MySQL, Apache, and cPanel worked well to host a forum I meddled around with. This was definitely easy to set-up and get running, but it was rather slow and offered very limited functionality. There were also glaring security breaches on these hosts, so it wasn't optimal for security.
Near the end of 2016, I was drawn by the holiday sales of webhosting. Magnitudes of discounts were being passed around like candy, and it became irrisistible to turn down one of the best offers of Winter 2016 on LowEndTalk. One provider, VirMach, was offering very cheap deals for virtual private servers (VPS). For a small website, a dedicated server was not required, and so I opted for a small VPS with the following specifications:
- 256MB RAM
- 1 vCore @ 1GHz
- 15GB Disk - SSD RAID 10
- 500GB Bandwidth @ 1Gbps
- 1 IPv4
- SolusVM/OpenVZ - Linux
- $5.00 USD/Year
This particular VPS is hosted in Chicago and is colocated (VirMach owns servers within someone else's datacenter) with ColoCrossing. Somethings to note about this VPS:
- OpenVZ is a particlar type of virtualization that enables a single server to host multiple smaller VPS that share a common kernel. The way in which this virtualization is implemented is that it allows for easy overselling, since the shared kernel allows for easy reallocation of resources. Not all VPS will consume 100% of their allocated RAM or CPU usage, so overselling allows the provider to maximize profit. This turned out to be an issue later.
- 1Gbps isn't really 1Gbps in that it is shared amongst the other users that are provisioned on the same server as I am. A few benchmarks give me approximately 30Mbps throughput average, which is completely fine since I likely won't have enough users to saturate it.
- No IPv6 support is a bummer, but not a dealbreaker since we are still reliant on the IPv4 address space.
My first iteration of a personal website was hosted on this server and because of its spectacular deal, it is still the host of choice.
After having the server, I needed to choose how I would be able to showcase my content. Since I had previous experience with WordPress, it was my first option. However, after spending tedious amounts of time looking through ThemeForest to identify a visual style that I enjoyed while having some of the capability I wanted: show my profile, have sections for blogs, and host my photos. So far, I had two options: perform all of these in WordPress or use a static HTML template, a separate image hosting software, and give up blog funtionality. I wanted to try something new, so I opted for the HTML template.
I chose the OKNO theme to start off with. I liked it. It looks clean, scrolls without stuttering, and generally feels both light and modern. I started off with the template and slowly used HTML to customize the way I wanted the site to feel like. After awhile, having little to no HTML and CSS experience, I learned that it was really difficult to produce quality layouts and user experience. In addition, any changes made to projects or portfolios would require me to append to the HTML, which I evaluated to be tedious to perform. I needed something else.
Another thing that was important to me was being able to showcase my photos. Sure, I could just use Flickr like any other photographer, but I personally believed it was important to have the user stay one one domain for the duraiton of their exploration of the site. Flickr also didn't have a great lightbox implementation. The first self-hosted solution I looked at was Lychee. This would have been the perfect implementation, if it were not for three things:
- Visual differences between the main site and the photography site
- The download button was hidden away, so most users would right-click and download, often producing a lower-quality image.
- I experimented with it and began uploading my photos to create albums. Now here is where that RAM issue came in. When uploding the large 24MP (6000x4000) photos to Lychee, or for any other software that requires the system to process the image, it needed to place the image in the RAM to process. It didn't place the photo as a data file in the RAM, but rather it requires 3 bytes per pixel to process (RGB representation). So for a single 24MP photo I required 72MB of RAM. This should have worked, but Lychee kept sprouting out HTTP 502 errors, and was eventually traced to a linux OOM (out of memory) error. To this day I am unsure where this error comes from as I had at least 100MB RAM free at all times. Perhaps concurrent threads attemting to process at the same time, or VPS overselling.
And so, I moved away from HTML templates and Lychee to the platform I knew: WordPress
WordPress is the most popular CMS today. With a huge community, a plethora of plugins and themes to extend functionality, it is easy to see why it is a compelling option. WordPress is also a very easy CMS for beginners to use and to learn, which is one of the reasons why I jumped to the WordPress ship.
First and foremost, visual appearance was the most important for me to select first, as all other functionality and content would be adapted to the theme. The most popular theme ever on WordPress is Avada. Offering a wide variety of customization without previous programming knowledge was very attractive, so I selected that to tool around with. I have used Avada previously, so having that familiarity made it easy for me to get going. The visual page building tool was very useful in creating modular pages, so I developed the website to make it look similar to the OKNO theme mentioned earlier. With a general theme layout and "site-feel" established, I moved on to other functionality to ensure that I would stick with WordPress.
For photos, I investgated a wide varity of image gallery plugins like NextGEN Gallery and Envira Gallery. The most important feature for me with these galleries was having a nice lightbox with simple navigation while being able to display the grid of photos without too much overhead. I ended my search with Justified Image Gallery, which supported both Flickr image linking, a masonry-style grid display, and PhotoSwipe 4 lightbox. It was a fantastic soluton. And so, I spent significant time building pages to show my photo albums and tuning the plugin. Notably, I wanted my visitors to be easily able to download a wide variety of sizes of my photos. Thus, I looked into the PhotoSwipe documentation, PhotoSwipe, and Flickr API documentation to embed a download link to the lightbox.
The implementation checked all the boxes. It looked visually appealing and had all the functionality to back it up (it looks similarly to the Photography section). However, the way in which Justified Image Gallery processed thumbnails to display in the gallery was through a PHP script called TimThumb. Loading these images undertook significant CPU load every time a user viewed the page for the first time, eventually caching the rest for a few days. This may not seem as an issue, but my use of CloudFlare with these TimThumb images, whose photo urls ended with "/timthumb.php?image=someimage.png&OtherQueries" didn't cache well with the CDN. I had no success in allievating this.
I eventually made the descision to move away from WordPress and the OKNO-esque visual style that I wanted. It was too much for a small personal website: tons of images, fancy scrolling, long page load times, slow backend, etc. And so, I looked at other CMS solutions for other ways to achieve what WordPress did, but for much less resource cost. After some time, I came to Grav.
Grav is the CMS that is currently powering this site. It is a flat-file CMS, meaning that no database is required, thereby allieviating much memory and CPU usage. The back-end is built with PHP and Twig templating, which I found easy to edit and modify themes. The theme this site uses is a modified version of the Medium theme which was clean and simple.
This CMS is was so fast compared to WordPress it's as if I was viewing a static HTML page. Using Loader.io, this website supports sustained 500 viewers per minute, even on this small, probably oversold VPS.
It was with this theme I did a bit more CSS and PHP adjustments to modify the site. With the use of frontmatter, I was able to implement per-page JS and CSS adjustments using toggles. For example, when I feel like writing some math in a blog, I implemented a "Turn on LaTeX?" toggle that enables KaTeX typesetting on demand, thereby reducing loading made by the user and reducing bandwidth usage. This is also why the main page does not load the Photoswipe 4 library. Grav plugins, on the other hand, enables JS and CSS site-wide.
For the photos, I feel that the current implentation is perfect. Visually, it organizes photos responsively in a masonry-stule format, each image can load into a Photoswipe 4 lightbox, and each image has its own download button. What makes this implementation better than before, was that thumbnail generation and loading was done all by the Flickr API. During load, the browser sends a request to Flickr containing the ID of the album, and receives in JSON a list of photos and their IDs. Using this information I build a URL containing the "small" size of the photo to display in the gallery. When a user enters the lightbox, they get the largest image appropriate for their browser. In addition, the browser makes another API request when the download button is pressed and the user is presented with all the formats possible for download. This was the most elegant and conservative implementation I could achieve for this. There is a security concern, since my Flickr API key is publicly exposed in the JS, but there aren't any malicious users on the internet, right?
On the back end, content is written in Markdown, which I found to be better than WordPress's visual text editor. There are a bunch of other features that Grav has, such as responsive image processing, but I'll leave that up to you to explore.
This is the journey of my personal website up to today. I plan to keep this as it is for awhile, given my current capabilities to develop websites. In the future, I hope to explore different solutions, perhaps a Grav competitor or python-based CMSes like Django.