Design for the lower end of the spectrum: Part 3

Ideas for client-side

So how do we address some problems of the web? There are aspects that go beyond PWAs and contribute to the bloat of the web and, I would imagine, the large size of apps.

For each of the problems listed in the Developer Facing Problems there is a solution that will work whether we use a build system or not. I avoided build system-based solutions as I don’t want to give the impression that a build system is required, just the extra effort of running the apps either locally or in the cloud.

Image sizes and download times

A solution for image sizes passes through responsive images (either picture or srcset) and image compression with tools like imagemin.

We don’t need to send the same high DPI retina image to all browser; we can choose what type of image to send and browsers are smart enough to know which one to use for each browser and screen size (if we set them up correctly).

This is what a responsive image looks like:

<img src="small.jpg"
     srcset=" large.jpg 1024w,
              medium.jpg 640w,
              small.jpg 320w"
     alt="A rad wolf">

Both srcset, nd sizes (a related specification) are part of the HTML specification and is supported in all major browsers so there should be no problem in using it across devices. If a browser doesn’t understand the srcset attribute it will just use src like any browser did until we got responsive images… they will get something, not just the optimized version of the image we wanted to give them.

Cloudinary has made available a Responsive Image Generator that allows you to create responsive images and their corresponding CSS styles in the cloud and then download it to use it on your project during development.

Javascript issues

Problems with Javascript size and download time can be solved by bundling content and using tools like Webpack or Rollup to create and bundle, split into smaller pieces, tree shake the result so it’ll only use what is actually needed, and load only assets for a specific page or route (lazy loading).

If we send large bundles down to the users, it’ll take a while to parse the code we send. This will not hurt our high-end devices but it will be much longer for mid and lower-end phones we’re likely to see in rural areas or for people who can’t afford the latest and greatest.

Parse times for a 1MB bundle of JavaScript across desktop & mobile devices of differing classes. From JavaScript Start-up Performance by Addy Osmani.

Mid and Lower level devices in other countries may be different and have different specs, usually less powerful than what we normally see.

Meeting users where they are: using their language

We can also provide content in the users’ target language and take advantage of technologies that have been on the web for a while. Web fonts used responsibly and with proper fallbacks, give you a device independent way to give users content in the language they use every day without major changes to the structure of your CSS.

First declare the language in the root element of your page, usually html:

<!-- provides a default language -->
<html lang="en-US" dir="ltr">

and later in the document, we add content in traditional Chinese, like this:

<!-- Later in the document -->
<p lang="zh-Hans">朋消然,地正成信青約屋角來邊還部下賽清受光可,綠不女外!
權來星加智有花個費主母:機爭理陸行吃洋然答辦清大旅動節活性眼還起就情相蘭要運見……
都靜內率機足轉</p>

We can use the following CSS to indicate what fonts we want to use for each case. We can go further and indicate multiple language fonts for different versions or dialects of the language. In this case, we’ve indicated different fonts for traditional and simplified Chinese characters.

body {
  font-family: "Times New Roman", serif;
}

:lang(zh-Hant) {
  font-family: Kai, KaiTi, serif;
}

:lang(zh-Hans) {
  font-family: DFKai-SB, BiauKai, serif;
}

You can also use attribute selectors that exactly match
the value of a language attribute ([lang = "..."]) or one that only matches the beginning of the value of a language attribute (lang |= "..."]).

<p lang="en-uk">Content written in British English</p>
<p lang="en-au">G'Day Mate</a>
<p lang="es">Buenos días</a>
<p lang="es-cl">Hola</a>
*[lang="en-uk"] {
  color: white;
  background: black
}

*[lang="es-cl"] {
  color: white;
  background: rebeccapurple;
}

*[lang|="es"] {
  text-align: end;
}

Finally, you can always create classes for the languages that you want to use and add them to the elements using that language.

.en-uk {
  color: white;
  background: black
}

.es-cl {
  color: white;
  background: rebeccapurple;
}

.es {
  text-align: end;
}

There’s another aspect of working with non-latin, non-western languages: writing direction.

If you’ve seen Hebrew or Arabic text you’ll notice that is written in the opposite direction than English: right to left, top to bottom.

There are other languages that write top to bottom, and either left to right or right to left.

There is CSS that will make vertical languages is not hard but it’s not something that we’re used to seeing in most western content.

<div class="japanese-vertical">
  <p>こいけそ個課チクテャあえむ派たケトリネちたつよめ'
  ねかへゆと都ヌミニセメ無かカルウャ「ウつ巣根都阿瀬個そ」
  るるうほさフソメふ毛さ名ゃみゃ日シセウヒニウっれ根離名屋エコネヌ。
  こっつろてとねつぬなつさそやほっツカトル夜知め鵜舳屋遊夜鵜区せすの
  ぬ雲るきな屋素夜差っメケセア都毛阿模模派知ンカシけか瀬
  列野毛よいーソコ区屋ろぬゅき</p>
</div>
.japanese-vertical {
  writing-mode: vertical-rl;
}

You can see an example combining Latin and Japanese text in this demo page

Depending on your target audiences and the languages they use, this may be all you need to do. But there are other languages that use different directions and vertical alignments.

The first step, always, is to localize your UI but the localizing the content is not too far away.

Conclusion: Where do we go from here?

Perhaps the hardest part is to move away from a one size fits all model and ask ourselves the question: “Does the web work well for what I’m trying to do?”

Think about it… the web has no app store and no install friction. All that your users need is visit the URL in a browser that supports the PWA technologies, and voila, they are using a PWA and using the technologies without having to do anything else but use their web browser. When they have engaged with the app enough times they can install it to the device (desktop or mobile) without having to follow the app store procedure and update the app with a large download every time the developer makes changes.

Once they are there the APIs that make up a PWA give you features that look like native but work on the browser and make the experience better for all your users, not just those on mobile connections.

And you’re not required to use all the APIs that make a PWA. For example, in my Layout experiments I chose to implement a service worker to make sure that users get a consistent experience after their first visit without using a manifest or any other PWA API or technology.

I’m not saying not to implement native applications but to evaluate your target audience and requirements before deciding if web or native is better for your application and your objectives.

And, whether you decide the web is best for your project or not, you owe it to your users to optimize your content as much as possible.

Links, References, Tools