Appearance
Web App Checklist: Frontend
A concise guide to frontend performance, accessibility, i18n, and SEO.
Performance
Measuring Performance
The currently popular metrics are:
- First Contentful Paint (FCP) - time took to render the first image or text on the initial viewport
- Largest Contentful Paint (LCP) - time took to render the largest image or text on the initial viewport
- Cumulative Layout Shift (CLS) - how much things moved around while the page loads
- Interaction to Next Paint (INP) - time took to render some feedback after user interaction
Some less popular metrics:
- First Paint (FP) - time took to render the first pixel to screen
- First Input Delay (FID) - time took from user's first interaction to render any UI feedback
Use Lighthouse and Performance to inspect page load performance on any website.
Use the Performance APIs to collect performance in production.
Improving Performance
Use a CDN, enable caching
For loading any resources, use Resource Hints:
For images:
- Specify height and width to prevent layout shifts
- Use the webp image format
- lazy load them
- Consider using the
<picture>
element to load different images base on screen size
For JavaScripts:
- Mark scripts as async or defer
- Inspect bundle sizes: ESBuild, Webpack, Vite
- Remove dependencies that are not actually used
- Reduce bundle size by minifying and tree-shaking
- Split bundles and only serve the ones the page need: ESBuild, Webpack, Vite
- Minify and compress the CSS
- Rely on inheritance instead of universal selectors (i.e.
body *
). This also makes overriding style easier
- Instead of linking from a font CDN (i.e. google fonts), consider downloading it and serving it from your own infra (i.e. your own CDN). This ensures you always load the same font, and reduces unnecessary DNS time
- Only load the glyphs that are actually used. This can be particularly consequential for CJK characters
For animations:
- Use the animation panel to inspect
- Animate the transform property instead of "top"/"left"/etc for absolute positioned element to allow GPU hardware acceleration
Additional considerations:
- the speed on the "first load with empty cache" might be significantly different from subsequent visits/navigations
- the speed on mobile might be significantly different from desktop due to reduced internet speed and processing power
- consider using server side rendering
Accessibility (a11y)
Usability predicates accessibility - if the user experience doesn't work well for the average user, it’s unlikely to work well for those with accessibility needs. So:
- Just have a good functioning website, that includes
- Working functionalities that match user expectations
- clear & simple language
- no broken links
- clear navigation logic
- show loading states
- show form errors, etc
- Have a viewport meta tag so that it can be rendered properly on mobile
- Support dark mode, respect
prefers-color-theme
, avoid flash of incorrect theme - Choose a default font size that works for the audience and the use cases. And test the app with modified font size (Ctrl/Cmd +/-)
- Content should have enough contrast
- Tap targets are large enough
- Don't use click here
- Working functionalities that match user expectations
Now comes to addressing accessible needs, ordered by increasing complexity.
- Speech - provide ability to type for voice features. For example: Type to Siri, TTY.
- Auditory - provide subtitles and visual cues. For example: subtitled tiktoks
- Cognitive & neurological
- Respect
prefers-reduced-motion
- Limited blinking or flashing to reduce distractions and photosensitivity induced seizures
- Speed control and pause-resume for audio/video playbacks
- Give enough or allow user to get additional time. For example, to
- stay authenticated
- complete a long form
- read any toast popups
- Respect
And to address additional visual and physical accessibility needs, the page should be:
Keyboard accessible - all element must satisfy all or none of the following
- is mouse clickable - has
onclick
handler - is keyboard focusable - has
onkeydown
handler, addtabindex=0
if needed - is visually different when is focused - has
:focus
or:focus-visible
style - has interactive semantics - prefer
<button>
over<div>
; or addingrole="button"
when constrained
- is mouse clickable - has
Screen reader friendly
- Have a document structure that makes sense
- Use semantic elements like
header, footer, nav, section, h1, p
overdiv
,span
- Have a
lang
attribute on thehtml
- Add alt text to all images
- A skip to content button that's hidden until focused by keyboard
- Use ARIA labels when necessary and only when necessary
- You can inspect the accessibility tree in chrome
Internationalization/Localization (i18n/l10n)
Localization vs Internationalization
Localization: adapting software to a specific culture Internationalization: designing software so that it can be easily localized
Get user's preferred language via navigator.language
and a list of all accepted language via navigator.languages
. And backend can use the Accept-Language
header.
The global object Intl
provides many functions for generating localized text.
There are many more things to localize that browsers don't yet have support for.
Furthermore, webpage should handle different text direction, or ideally, design for bidirectionality (RTL layout) (Material v3 version).
Search Engine Optimization (SEO)
Be crawlable
- Have a
robots.txt
- Use meta tags for additional control
- Request a crawl or recrawl from Google
- Sign up for google search console
- For larger sites, add
sitemap.xml
Additionally:
- Each page must have a meaningful
<title>
- Add the meta description
Many points from the a11y section still apply here.
- Use semantic html tags
- No broken links
- Don't use click here
And also from the performance section:
- Each page should load fast (low FCP, LCP)
- Make sure it load fast on mobile too
Be shareable
- Providing additional information to enrich the preview cards in social & messaging apps
- Have Open Graph (
og:title
,og:description
,og:image
) meta tags - Test how it looks on all the social & messaging apps
- Check for platform-specific tags as needed