Wednesday 7 December 2016

React-ing to the need for a modern MapGuide viewer (Part 7): Laying out the blueprints

With the latest release of mapguide-react-layout out of the way, it's time to continue the journey of porting across the remaining fusion templates across.

One of the "problems" we have right now with this new viewer is that although we have got most of the foundational stuff right, the UI lacks stylistic cohesion. This is due to the viewer being a mish-mash of various react components, each with their own unique styling quirks. I really wanted a react-based UI toolkit that had a good enough baseline set of widgets/components with a unified look for building desktop-centric web applications (with an option to go mobile down the road).

Most of these UI toolkits however, take the reverse direction. They are mobile/tablet first, trying to emulate Material Design, iOS or Bootstrap and when trying to adapt such toolkits for a desktop-centric web application design, just look horribly out of place. Most of the UI toolkits that would've passed my desired criteria (like kendo, ExtJS, jQuery UI, etc) suffered from being imperative JavaScript APIs (meaning it would be a painstaking effort to interop with React and/or TypeScript), or some had incompatible/undesirable licenses to boot.

Well, I think my wish for such a toolkit has now been fulfilled, and its name is Blueprint.

What sold me on this particular UI toolkit was:
  • It is React-based
  • It has a good wide range of components that covers most of what I need to port across the remaining Fusion templates
  • It comes with a diverse set of icon fonts
  • It has a friendly license (BSD)
  • It is written in TypeScript and the library comes bundled with TypeScript definitions
  • It looks good!
With so many good selling points, I've decided to adopt Blueprint as the UI foundation for all my viewer templates. This means.

We have better looking modal dialogs (as seen in our updated Aqua template)



We have better styled UI for certain tools

 

And we have key components needed to start bringing across the other remaining Fusion templates, like the TurquoiseYellow template.

Compare the original Fusion template



With our blueprint-powered version


Looks good enough doesn't it?

Now there is one executive decision I'm making with the Fusion templates I'm porting over. The overview map will always be present as a toggle-able button on the main map viewer component and not outside of the map viewport.

Part of the problem is having the OpenLayers OverviewMap control render its content outside of the map viewport doesn't really play nice with React component updates in my attempts thus far, so I've taken the creative decision to not bother trying to get everything 1:1 when porting these templates over. As long as the main elements and styles are there, it's good enough for me.

Now sadly, despite having made several existing libraries and React components redundant (and they have been removed as a result), taking on Blueprint has added a lot of extra weight to our final bundle

Fortunately, this is still significantly under the current Fusion production bundle size, and as we are still in the process of reaching functional parity with our existing AJAX/Fusion viewers, bundle optimization is not a priority at the moment. When that time comes, we can look at things like custom OpenLayers build profiles and moving to Webpack 2 for its tree shaking feature, which should make some in-roads in cutting down our production bundle size to more acceptable levels.

3 comments:

Nimro Cnaan said...

Nimce Work

mapNinja said...

Looks good - does this mean that for every fusion template the embedded code in the viewer will grow a lot?
I never understood why there was so much duplication for Fusion when shared code and a dynamic CSS loader should have been sufficient and provided flexibility for third-party template styles as well.

Jackie Ng said...

To answer your question: No.

The bundle size is primarily a function of the libraries we're using (and hoping to use in the future) and sadly there is no "pay for only what you use" model with all these libraries. You use only one feature of a library and your final bundle still wears the size cost of the whole library.

As it stands right now, the bundle size will most likely plateau out. The choice of external libraries is mostly settled now, so I don't foresee any further dramatic increases in bundle size.

Based on webpack bundle analysis, "our" code (which includes Fusion templates) only represents 15% of this bundle size. Most of the weight is in the libraries we're using.