The website as a signal


We rarely think about our website as a signal, which affects the quality of our design. Every time we add an element to a page, we influence the signal at a particular point in time. Every time we remove from it, we eliminate part of the signal. Imagine a singer recording their latest song in a noisy environment and then selling it. Any listener who perceives the noise would be reluctant to buy another album from the same artist again. After reaching a perceivable threshold, the noise becomes intolerable.

As web designers we are in a good position to deal with the noise. By reducing it, we improve the perception about the signal (see SNR ratio). The intent of our pages becomes more clear and the content more easily understood by our users. To seek complete elimination of the noise would be impractical. In fact, it is already present before our first signal is ever created. If we examine HTML as a signal, we'll see characters like <>/” and others that appear in tags, but have nothing to do with the output on the screen. To say that a website has m*(2*n+5) bytes of HTML noise, where m is the number of tags and n the average length of each (if all are <span>, it would be 4) would be a coarse approximation, but we could eventually neglect the number of tags that appear in the head section and the ones that don't have a closing tag if there are relatively few of them. This also doesn't consider the numerous attributes we could attach to each tag, either for presentational or functional purposes, which are likely to increase this size much more. The factor of 2 in front of the n is to indicate a duplication of the signal (span open-span closed) and the 5 is formed from the two “<”, two “>” and one “/” characters respectively. A page consisting of 2000 <span> tags would have at least 2000*(2*4+5) = 26000bytes = 25.4kB noise within the HTML. This may not seem much, until we consider that the PNG image above is 2.29kB. The people behind HAML recognized the tag duplication and offered a simpler representation for it, allowing everyone to save on typing. But the browser can't understand this language—only the code it generates,—which doesn't remove the redundancy in the signal. Even when we type less, the browser is still capable of interpreting the code slightly differently than we expected, resulting in a different signal. It is always a good idea to check with Ctrl+U.

Noise doesn't exist only in the tags, but also in the content as well. If we repeat the word “web design” 50 times on a the page, would that be considered a signal or noise? This will depend on both search engine algorithms and user perceptions. If we use 10 times &nbsp; (60 bytes) to make enough horizontal space between a pair of words and repeat the same approach many times for other pairs too, we would generate a lot of noise. For a single visible space, we are using six bytes in the background, so the ratio of 6:1 is really big. Yet, sometimes HTML entities can be used instead of a tag or an image (saves an HTTP request), in which case they are good, but this will depend on how we choose to shape the signal in a given context. If we add new lines with <br/>, the ratio will become only marginally better (4-5:1). This is just one reason why I mentioned on the front page that design is also in the invisible.

What about CSS? It is common to see many different selectors to contain the property “position: relative”, “float: left” or “display: block”. We are duplicating these properties, creating the same signal segment at multiple places. We could choose to combine multiple selectors and assign a single property to them, which gives us some flexbility in the way we can mix them at the expense of possibly matching the same elements multiple times, for every property they have (again, duplication). Like HAML, SASS also helps us write less, but also doesn't eliminate duplicates in the final signal. The more powerful ways we have to shape our information, the more redundancy we can expect to create.

Each pixel on the screen has been produced by a signal that the graphics card is sending to the screen. Every image is a signal with red, green and blue components that we could access and manipulate separately (but which can become quite CPU intensive for large images). We choose at any given moment how to paint the small amount of the pixels on the screen. This means that the website shows a signal. When we start scrolling, it can either be continuous (smooth) or discrete (janky). We generally strive for continuous signals. If someone creates a long HTML form and divides it into multiple pages to make it more manageable for the user, they are probably creating a discrete signal, not a continuous one. This allows them to hide which information they require under the mask of a simple username&email form. Once the user fills the two fields, they are asked for 15 more, where there was no previous indication that this would happen. Now the site owner has some information and doesn't need to provide anything for it. This is both discrete and disrespectful, but in my experience, it happens quite often on the web. If the user needs to click multiple times in short bursts, for instance, to move between the various steps in the form, this is both discrete and tiring. Everyone who has tried to download a driver from a hardware provider and had to first choose manufacturer, then OS, then device, then serial number, driver version and so on, can probably confirm this.

An important aspect is to choose the most effective representation for the data, e.g. to encode the signal in the most effective way. For instance, if we intend to output data that has tabular nature, it is probably not a good idea to store it within a hierarchical data structure. We could use a NoSQL database like MongoDB (hierarchical) to extract data into a <table> on the page, but this would be less efficient than using an SQL database that has been made specifically for this purpose. Here it is important to examine how the database is encoding the data internally, to see the quality of the signal. For instance, MongoDB uses a lot of ,” symbols, and a repretitive JSON-like structure is less efficient than the CSV format. In each document the properties are duplicated and it is not possible to list all values after a single property instead. All this (at least on the surface) creates a signal with a lot of redundancy, so we can expect that working with such a signal would be slower compared to one from a relational database. Even if MongoDB can impress with speeds of a couple of milliseconds, we should not forget that this is within the DB management application. When the data reaches the web page the situation might be quite different.

The DOM is a binary tree, which is also hierarchical. It may partner well with this database as long as we aren't trying to create deeply nested structures. Even if the DOM isn't the best way to store large amounts of textual data, it allows for fast operations (insertions, replacements, deletes), which would be otherwise much more difficult. This makes pages more interactive and interesting to the user at the expense of having a slightly suboptimal signal (as explained in the paragraph about HTML).

SVG exists from a long time and still seems popular among people, who need scalable graphics in the browser. However, the SVG syntax is very noisy, consisting of non-expressive “magic” numbers only, which makes it hard to understand and debug. Some people said that it is much easier to create the vector graphic in a tool like Illustrator and export it as SVG than to create it from scratch. This indicates a potential problem with the technology. It is often much better to discard a signal that we can't easily understand than to introduce one that could behave as noise. We should realize that anything that is too complicated is probably wrong. Otherwise our websites will grow as much as to become unmanageable.

Signals have frequency and amplitude. The amplitude indicates how strong the signal is at a given point in time and how abruptly it transitions to a later state. This means that we need to consider how smooth we lead the eye from one element/state to another, evaluating position, size, color and shape. How things coexist on the page can be as important as their exact nature. In the case of blinking, we repeatedly and abruptly alternate between the values 0 and 1 (invisible and visible), which is bad. Instead we should have moved from 1 to 0.99 to 0.98 and so on with each value corresponding to a different segment of the signal.

If our page is a signal and the signal is a function, this means that we can combine it with other functions to arrive at new ones. For instance, we can use a template engine to create a template (one function) that we use to populate with data (another function) to receive the final page (resultant function, h(z)= f(x)&middot;g(y)). We can think in terms of a superposition of multiple functions and tweak their individual parameters to see how the whole would behave. This gives us a lot of flexibility to arrive at a signal we want.

A signal is subject to selection. Using JavaScript functions or XPath, we can address only a small portion of the signal and work with it, independently of what is happening with the rest. Another possibility would be to move a sliding window over a function to get only the visible portion of it. But this may not be easily achievable if we don't have prior information of the objects we would like to reference at the boundaries. Working with file pointers directly would require a lot of precision and is rather fragile.

A signal can also be transformed. In the equation h(z) = f(g(y)), f is our transforming function that receives a web page (the function g(y)) as a parameter. Web scraping, where we extract portions of a page and place the data in a new context would be an example of this. The transforming function itself may not work universally with any given page by default, since we may want to extract very specific fragments from individual pages with highly varying structure. Getting all data could lead to space problems and will increase the computational effort needed to analyze it. Again, we should remember that we seek the sparsest possible representation to complete our task. The possibility for transformation means that the information we provide to our users will likely not remain in its original form. That is, we should allow for the signals we produce to be easily transformed by an arbitrary transforming function picked by the user. If you remember XSLT, then you know that it was used to transform XML. Providing a service API publishes our transforming function to everyone who wants to send signals to it and wait for the response. (APIs usually limit the frequency at which this could happen to prevent abuse).

We should always question how things are done currently. For example, if we are trying to implement an idea in 10 steps, having multiple references that say “this is how it's done”, we may be blind for the case in which someone did it in 3 steps by viewing the problem from a very different lens, maybe even reformulating it. Then it would be clear that spending all the time to polish our complex signal lost against a simple approach that provingly works. So, instead of asking ourselves what we can add, we should be asking what we can remove from our signal. And not blindly jump into the complexity someone else invented for us.

I also want to point out that we can't rely on compression to fix the problem with our signal. The reason for this is that “better data beats better algorithms”. Here, I use “better” not in the sense of “more”, but in the sense of “encoded once only”. Compressing a signal without repetitions will be more efficient than compressing a signal with repetions, since the last need to be encoded separately. Although the algorithm will shrink the size of the data, it will still be unable to fix the original problem with it.

If a team of four people works on a single website, then this means that 4 functions are influencing each other at any given point, which may affect the consistency of the signal that is communicated to the user. If he/she perceives the message differently while moving from one page to another, they will ask themselves whether this is still the same site. It may look similar, but it may not feel the same.

There is no reason to be proud of having 50000 lines of CSS on our website. This is a sign of avoiding to treat it as a signal. Over time the redundant components will add up and maintenance will become increasingly harder, converting our “advantage” into disadvantage. If you mess with the signal, it will bend you.