Skip to content

Instantly share code, notes, and snippets.

@johannlilly
Last active January 26, 2024 10:32
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johannlilly/e162f85240eaa8bf6fe680fe3f703222 to your computer and use it in GitHub Desktop.
Save johannlilly/e162f85240eaa8bf6fe680fe3f703222 to your computer and use it in GitHub Desktop.
The purpose of this document is to articulate considerations, tools, and methodologies for UI architectures with regard to the code, UI design, and project management.

UI Architecture: Tools and Methodologies

The purpose of this document is to articulate considerations, tools, and methodologies for UI architectures with regard to the code, UI design, and project management.

Always be closing shipping

Code

This compendium on UI Architecture is specifically for a React environment, though many principles apply to others. This section describes tools and methodologies for ensuring quality code from local or remote teams.

Prevent errors and ensure code quality

Testing categories

The following testing categories will be considered:

  • Test-driven development (TDD) is an evolutionary approach to development which combines test-first development where you write a test before you write just enough production code to fulfill that test and refactoring.
  • End-to-end testing is a top-down approach where tests are written to determine whether an application has been built appropriately from start to finish. We write end-to-end tests as though we are a user's movement through our application. End-to-end tests are often labeled as integration tests since multiple modules or parts of a software system are often tested together.
  • Unit testing is a confined approach that involves isolating each part of an application and testing it in isolation. Tests are provided a given input and an output is often evaluated to make sure it matches expectations.

Testing, CI/CD tools, and QA/QE

Any font-end testing and CI/CD pipelines should be performed in conjunction with the full-stack of an application and streamlined with DevOps teams. Various tools exist, but consideration should be given to the existing environment and conformed accordingly.

  • Jest: used by Facebook; it integrates beyond UI and may be used with a full-stack CI/CD pipeline
  • Jasmine: describe() {...} it() {...}, etc.
  • AVA: uses JavaScript’s async nature and runs tests concurrently
  • Tape: TypeScript support
  • Mocha & Chai: testing + assertions
  • Puppeteer: built by Chrome’s Development Team, UI testing
  • PhantomJS, ZombieJS
  • Arrange, Act, Assert (a design pattern, not a tool)

A number of CI/CD pipelines integrate with Git. GitLab, for example, integrates well with Jenkins and Jira. Again, consider the workflow used in other parts of the stack. It will likely dictate that of the UI.

QA/QE assets from teams associated with other parts of the stack may be available for use in testing the code.

Write clean code

You're not just coding for today. You are coding for your future self--as well as the next developer who works on your code--for maintainability, reusability, and upgradeability. Pair programming complements this endeavor.

JavaScript comment methodologies

  • RFC 2119: a common vocabulary.
  • JSDoc: A markup language used to annotate JavaScript source code files.
  • Google JavaScript Style Guide: a common set of rules.
  • ESLint: a code linter to enforce valid comments.
  • ESDoc: a plug-in that automatically generates a documentation template as you code.

CSS selector naming conventions

CSS selectors can vary widely from developer to developer. There is no single best practice, but these conventions enforce common patters and formats, which keeps code legible, understandable, and maintainable across people and teams.

  • BEM
  • OOCSS
  • SMACSS
  • Atomic CSS

Writing CSS

Just as test-driven development combines test-first development--where you write a test before you write just enough production code to fulfill that test--CSS should be written in what can be called "responsive-driven development," whereby code for multiple screen sizes and devices is written concurrently.

  • styled-components should be used in general, with SCSS for global styles. I prefer this approach over using Pure CSS, Bulma, Materialize, Tailwind, etc. With styled-components, you write CSS within your JSX. I generally prefer to keep HTML, CSS, and JS as isolated as possible, but that approach isn't as efficient when thinking in terms of components.
  • styled-components has community-organized TypeScript definitions from DefinitelyTyped to allow the library to be used in any TypeScript project.
  • inject themes into styled-components - theming (e.g. dark/light theme).
  • Emotion can be used instead of styled-components and may be better if not using React, but benefits of using Emotion (modularity) will be diminished with the release of styled-components version 5. styled-components continues to be more popular on GitHub and NPM.
  • SCSS over LESS, but pre-processors should be used minimally if most styling is handled with styled-components.

APIs

In whatever way backend developers and database engineers handle their environments, the front end should interface with them in a way that is maintainable and upgradeable without redesigning the entire system. GraphQL is a modern query language that integrates within a React environment and provides a methodologically agnostic bridge between client and server, or between layers of the stack.

Building endpoints to which the front-end can connect not only enables ease of interfacing with existing layers of the tech stack, but enables interoperability with modern cloud technologies. For example, a web application may respond to particular events. Depending on cloud strategy, these events can be configured through functions-as-a-service (FAAS), such as AWS Lambda.

Write code faster

  • Emmet: less keystrokes (supported by Visual Studio Code).
  • a view engine (like PUG or EJS) can be used instead of JSX with React, but I only recommend them with Vue.

The most fundamental unit of work for the developer is writing code. Meetings and other corporate happenings interrupt "fingers on keyboards." Tools like Emmet help make that time more efficient.

Write documentation

  • ESDoc generates documentation as you code, so long as you are writing comments properly
  • Write The Docs publishes best practices when writing documentation.

App development

When developing in a React environment, TypeScript is preferred. In today's app environment, UI development bleeds into the front-end and even replaces previous middleware and back-end responsibilities. Relevant tools for building these modern apps include:

  • TypeScript + Next.js + Redux + RxJS
  • server-side rendering is important for web crawlers to access the entire site, therefore, for SEO
  • code-splitting using React's import(), which is supported by Next. React documentation recommends this, but lazy loading via webpack is better supported with React Native. React.lazy and Suspense are not yet available for server-side rendering. React documentation recommends Loadable Components.

Static vs. dynamic

Statically-typed languages have less bugs. A research paper from University College London showed that using a typed language results in 15% less bugs in your code. source

Statically-typed languages prevent errors. A study from Penn State showed that products with TDD applied had between 40% and 90% decrease in pre-release bug density. source

TypeScript vs. PropTypes

TypeScript is more powerful because:

  • You don’t need to run your application to know if you have type errors. TypeScript is parsed by your code editor so you can see the errors as you make them.
  • You can only use prop-types with components. In your application, you will probably have functions and classes that are not using React. It is important to be able to provide types for them, as well.
  • TypeScript gives you more options to define the types and then it allows you to use this type information in many different ways.
  • TypeScript has interfaces and declarations.

App architecture beyond UI

  • Functional Requirements
  • Programming languages, their features, readability, and interoperation
  • Code reuse across platforms (server vs web vs mobile)
  • Early error detection (compile-time vs runtime error detection, breadth of validation)
  • Availability and cost of hiring the right talent; learning curve for new hires
  • Readability and refactorability of code.
  • Approach to code composition, embracing the change
  • Datastore and general approach to data modeling
  • Application-specific data model, and the blast radius from changing it
  • Performance and latency in all tiers and platforms
  • Scalability and redundancy
  • Portability, transferability, and operation across platforms
  • Spiky traffic patterns, autoscaling, capacity planning, time to first byte (TTFB)
  • Error recovery
  • Logging, telemetry, and other instrumentation
  • Reducing complexity
  • User interfaces and their maintainability. External APIs
  • User identity and security
  • Hardware and human costs of the infrastructure and its maintenance
  • Enabling multiple concurrent development workstreams
  • Enabling testability
  • Fast-tracking development by adopting third-party frameworks and methodologies (e.g. TOGAF)

Performance testing

  • Google PageSpeed Insights, in conjunction with properly understanding how Chrome DevTools work.

App monitoring

In a world where cloud-native full-stack reactive web applications are the norm, each major cloud provider has their own set of tools for monitoring an app, as well as a suite automatic actions that can be performed according to predefined triggers. Whether scaling vertically or horizontally, your application can adapt. Amazon has resources like CloudWatch, CloudWatch Alarm, and EC2 CloudWatch; while Microsoft has Azure App Service, Application Insights, Azure Monitor, and Log Analytics. But these are tools more aligned with DevOps teams. If an app goes down, it impacts UX/UI. But a broken UX/UI won't likely compromise the underlying infrastructure, therefore, it calls for additional monitoring.

The monitoring in which we are interested can be referred to as UI or GUI testing. Besides the manual testing of QA/QE resources, the following tests can be performed:

  • capture and replay testing
  • model-based testing
  • accessability testing

The following tools can accomplish this testing:

  • Waitir
  • Sahi
  • Sikilu
  • AutoIT
  • TestComplete

UI

Designing a UI

  • InVision for creating pseudocode and autogenerated click-to-copy CSS
  • Storybook.js for developing UI components in isolation
  • axure for prototyping
  • PSD file with grid lines (e.g. Bootstrap); perhaps the most basic option and relatively inefficient

Multi-billion dollar organizations perform research on user interfaces and publish their findings. These documents can be referenced to offload internal research:

UX/UI tools, testing, and analytics

All-in-one tools exist, such as:

  • UsabilityTools
  • userzoom

A/B testing

This is relevant when presenting designs to stakeholders and/or testing the efficacy of the UX/UI. A/B testing can be costly to perform for most organizations, with regular global UI updates beings unrealistic. It is important for the Art Director and/or UI designers to be well-researched on the latest design patterns and A/B testing results. Minor UI variations (color palette swaps, element arrangement) can quickly be rendered within that context and presented to stakeholders while still giving engendering the sense of ownership over the resulting product.

If performing A/B testing, notable tools include:

  • VWO
  • Optimizely

An organization requiring highly-specific (proprietary) UIs may necessitate more robust A/B testing, as the relevant testing data results may not exist or be available. This should be evaluated according to the scope of the project.

"A/B testing is not a way to increase conversion. A/B testing is a way to test your hypotheses. And nothing else. You have various hypotheses and it is A/B testing, that allows you to confirm whether your hypotheses will work out well or not. That’s all. It will never solve all the problems of your business. It can only help to make the right decisions, as each of your hypotheses will be confirmed by data."

Analytics & heatmaps

  • Google Analytics
  • luckyoarange
  • mixpanel
  • hotjar
  • crazyegg

Remote user feedback

Automated and manual tools exist and can be utilized according to the priority and scope of the project.

  • Storybook.js enables React UI testing
  • userlytics is an example of a company that enables UI research by gathering feedback from testers
  • Smartbear is an example of a service that provides automated UI tests

Avoid user drop-off

User playback videos

  • fullstory
  • uxCam
  • inspectlet

Surveys

  • Qualaroo
  • SatisMeter
  • Wootric
  • usabilla

QA/QE

QA/QE assets from teams associated with other parts of the stack may be available for use in testing the UX/UI.

UI Frameworks

  • styled-components is top choice. It integrates well with React, especially for theming, and supports React Native. It has a responsive grid built in and works with multiple grid frameworks.
  • Bootstrap 4: I prefer to only use Bootstrap's grid system and avoid having to bundle jQuery; import components written in vanilla JavaScript or TypeScript to do what you would otherwise do with Bootstrap's components. I don't recommend variations of Bootstrap that are written in vanilla JavaScript because of uncertain community support. Bootstrap isn't going anywhere. At a minimum, I like to use Bootstrap's breakpoints, modified for iPads and rare screen sizes, i.e.:
    • ss: max-width:320px (optional, only for small fixes for compatibility with iPhone 4S and below)
    • xs: max-width:575px (small phones)
    • sm: min-width:576px and max-width:767px (large phones)
    • md: min-width:768px and max-width:1023px (iPad mini, tablets in portrait)
    • lg: min-width:1024px and max-width:1199px (iPad in portrait)
    • xl: min-width:1200px (desktop)
    • xx: min-width:1920px (optional, only for customized full-screen or ultrawide experiences)
  • Dead Simple Grid, Skeleton, and Base are alternatives to Bootstrap's grid, but developers may be more accustom to Bootstrap's grid syntax.
  • Bulma is simple. It is a framework based on Flexbox and built with Sass.

A framework should be chosen by considering community support, success of integration into a project, and the skills of the development team. Bulma may be incredible, but if developers are only familiar with Bootstrap and there are little comparative technological advantages either way, I'd recommend Bootstrap.

Graphics, icons, and assets

  • styled-icons are included with styled-components.
  • popular icon packs like Font Awesome and Material Design are supported by styled-components.
  • React works nicely for dynamic SVG files through injecting data, but outsourcing this to popular libraries is useful, e.g. Neo4j, D3.js, Chart.js
  • Canvas is a simple alternative for data visualization and animation, and natively supports text wrapping.
  • Mermaid.js can be used alongside markdown documentation. Creating documentation (in addition to auto-generated documentation with ESDoc) using markdown syntax is highly flexible for use with GitHub, GitLab, etc.

CDN

According to the organization's cloud strategy, assets can be configured for hosting via CDN (e.g. AWS Cloudfront). Attention will need to be paid to CORS.

Project management

There's more to UI Architecture than lines of code and colors.

Additional cost considerations

Microservices are important, as are other innovations within the software development community (e.g. FAAS). But they can become buzz words and supersede sound business decisions. Questions that should be considered include:

  • Will your infrastructure require a human to manage?
  • Will you need a fully staffed DevOps/SRE team to support your operations?
  • How much will it cost to run the system at full scale?
  • Can you reduce costs while you are running the POC for the first few months before you get funded?
  • How costly will it be to handle the occasional traffic spikes?
  • How well will your system protect the customer’s data?
  • How can you best support the future development and testing efforts?
  • What is the cost of maintaining your systems’ regulatory compliance?

Don't repeat yourself

Duplicative effort and blocked effort can be avoided with sound tools and methodologies. The coding principle of don't repeat yourself (DRY) applies not only to one developer's code, but the efforts of the team. This calls for a single source of truth (SSoT) that is easily accessible and up-to-date. Adequate consideration should be had about migrating to new tools and methodologies.

Code review

Pair programming is "an agile software development technique in which two programmers work together at one workstation. One, the driver, writes code while the other, the navigator, reviews each line. The roles switch frequently as the pair takes turns focusing on the strategic and tactical aspects of their work. Studies have shown that while engineering pairs spend 15% more time to build the same software than individuals, their output has 15% fewer defects." While this has implications for code quality, it also augments the technical maturity of the development team, growing juniors to mids and mids to seniors.

Performance management

A balance must exist between leaving developers to write code and directing their activity. I prioritize "finger on keyboards" and try to restrict meetings to a 15 minute daily standup. Using a tool like 15Five is an efficient and unobtrusive tool for gathering progress updates from remote teams.

Always be shipping... code to market.

@lcr0815
Copy link

lcr0815 commented Jul 19, 2020

great piece, you may want to include react-material ui which is based on bootstrap but it's great for react. I like it quite a lot alhtough I've used for bulma and the style-components and emotion components but once you get a taste of material-UI you tend to not go back... anywho: just my take....

also you need to define some of the issues: like what is CLEAN-CODE what do you have to do put thru the dishwasher, what is DRY, this may need examples.

with react you also have discuss the functional javascript principles which are awesome time savers and a CLEAN-CODE & DRY foundation.

'noff for now....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment