Zyro recently implemented the first iteration of a website importer feature that allows users to import their existing sites to Zyro’s website builder.
This is a very exciting time for us because we think that much of our future growth depends on our ability to make the Website Importer great.
However, there are still some issues that we need to iron out first, which is the topic I’ll explore in this article.
The Main Problem
The main problem with the Website Importer is that many imported sites do not look good on the Zyro grid.
This is due to the stretching or overlapping of various components, e.g. images or videos, after the coordinates measured in pixels are converted into grid columns/rows.
Here’s a diagram of a component (blue) placed onto the Zyro website builder grid.
BLUE – The original element position in pixels.
RED – Simple algorithm placement (showing component stretching).
GREEN – Ideal result (the component is no longer stretched though it has been moved slightly).
As you can see, the element size does not stay the same when placed onto Zyro’s grid. And if there are more components, they might overlap or appear out of order.
The issue arises from our placement algorithm implementation that is just too simple – it only places elements in the nearest cells.
We know that we have can do better.
So, if we want to improve, we need answers to the following questions:
- How can aesthetic design choices be evaluated algorithmically?
- How can that algorithm know where to place the components?
Our first attempts involved trying to keep the aspect ratio and the positioning of each element as close to the original as possible. Still, we know that we cannot do that correctly, as it will always have to be translated onto the grid.
There are definitely other metrics that we could use for evaluating the placement of different components.
But how can we figure them out?
As you know, Zyro has a lot of A-game professionals, so we decided to use that unique resource.
During meetings with our UX team, we discussed the problem and took a cross-functional approach to it. We wanted to know if they knew anything about possible design rules or algorithms that we could implement.
Their perspectives were beneficial and brought the AI team a whole host of new ideas and insights to try.
The main thing that stuck with us was this article that explores why some designs look messy and others don’t.
Our main takeaway can be expressed through this image:
Here, the design can become more appealing by extending the component edges and matching them to one another. This is an excellent example of an algorithmic implementation that can significantly simplify the beauty calculation for a particular design.
Still, the question remains:
How can we tie this metric together with the other ones?
And in the case that we discover more key metrics, these too will need to be tied to any strategic implementations.
The first iteration
We came up with the first iteration of Zyro’s Website Importer by introducing Genetic Algorithms (GAs).
Put simply, GAs borrow the main concepts of evolution from biology to produce the best possible output.
Here’s how they work:
- Start with a sample of agents (layouts in our case).
- Evaluate their scores.
- Breed the best-performing ones with the others.
- Introduce mutations and changes.
- Repeat steps 2 through 4 until you reach a satisfactory score or reach a maximum number of cycles.
To implement the metrics or add any new ones, we only need to modify the scoring function, while every other step can be kept the same.
To implement GAs, we first need to have a data structure that would allow us to quickly calculate the score of a specific layout to iterate through different configurations and optimize accordingly.
We chose to convert the layout to a NumPy array, where each component is defined by:
- Pixel coordinates (top-left and bottom-right corner coordinates).
- Grid coordinates (using grid-column and row indexes).
- Grid pixel coordinates (grid columns and rows converted to pixels).
- Aspect ratios (pixel and grid pixel width/height).
We also added a matrix that is the same size of the grid that includes:
- A component area.
- Vertical and horizontal component edges (taking inspiration from the earlier image).
And here’s what the matrix of Zyro current front page looks like:
- Main element area:
- Horizontal edges:
- Vertical edges:
The vertical edge component matrix shows us where gaps between columns are very effectively, and it also matches with the screenshot above.
Even placed without a genetic algorithm, this is the most difficult part of our render preview:
There are still some issues, the most visible one being that the text is all smashed together.
This happens because our builder grid row size is a lot bigger than the small text height on the website, and our simple algorithm just cannot deal with it.
To solve this, we started implementing a custom Genetic Algorithm.
For the first proof of concept iteration, we decided to use a fast and easy scoring system.
This scoring implementation can be summarized as follows:
- Overlapping cells have a penalty of -1.
- The difference between original pixel coordinated and grid pixel coordinates have a penalty of -0.01 per pixel.
- The aspect ratio difference between the original element dimensions and grid pixel dimensions x -1.
- A perfect solution has a score of 0, while the worst case has -∞. The closer the score is to 0, the better the solution.
After implementing this scoring system, we were really excited to see what the result would look like in the worst-case scenario, so we ran our algorithm on the section above.
And here’s what that section looks like after 120 epochs of genetic algorithm evolution (with unoptimized meta parameters):
Less overlapping! That’s great, but what is all of this mess?
Well, we did not implement the extended edge calculations into the score at this proof of concept stage, so all the order and structure went right out the window.
But we have less overlapping.
This part of the project was simply to evaluate if GAs would be able to solve this small overlapping issue before moving further with the project.
While the results are not great, there is clearly a lot of unrealized potential for this kind of task. So, we decided to move forward with a second iteration.
Here are some of the planned metrics:
- Symmetry score
- Matching vertical edges
- Matching horizontal edges
- Relative/absolute placement pixel difference penalty
We can’t wait to share the Website Importer feature improvements with you really soon.