At the office, I led a major initiative to create a lovely drag-and-drop manager for a toolkit of pre-packaged views of. The views had their own complexities; Splunk search views come with the own controls, and the controls are populated by underlying searches, which may in turn be controlled by other controls. I fumbled around with various design decisions before realizing the obvious. What I just described was a tree. I threw out all my fancy analyzers and weird Backbonification stuff, and wrote a tree handler.
It worked perfectly.
Later, I realized that each view dropped onto the screen could be described using the RDFa trio of typeof/about/property, three rarely used HTML attributes that allow any HTML object to have a rough correspondence a database notion of table/row/column, or the object-oriented notion of class/object/field. Instead of doing all my previous, ridiculously hairy code managing the visual layout, I used the HTML5 drag/drop for positioning, some very small Javascript for grid management, and classic event handling to figure out when new views had been dropped in, moved, or deleted, and I let the existing libraries do all the heavy lifting. Using data attributes to describe the visual state and CURIE for de-obfuscation, I had a nice event-driven system where everything on the page represents every and only those things I cared about.
The lessons learned were fairly straightforward, and classical. The data structures you learned in university are usually Good Enough; don't borrow trouble trying to create a hack for performance reasons. Premature optimization is always the root of evil. Second, always survey the tools available to you before starting to code. You'll be surprise just how little work you actually have to do. Clever is writing a lot of code to do a lot of stuff; smart is figuring out that you don't need a lot of code to do a lot of stuff.
Another lesson learned is that purity matters. In web application design, view every event as a miniature program-- it does two things, it transforms your existing data to create a new structure, and then it illustrates that new structure on the page. Keep those two things as separate as possible, even if you have to go around your framework to do it, and you'll have a much more testable system when you're done.