• Skip to main content
  • Skip to footer

InRhythm

Your partners in accelerated digital transformation

  • Who We Are
  • Our Work
  • Practices & Products
  • Learning & Growth
  • Culture & Careers
  • Blog
  • Contact Us

engineering

Mar 26 2019

Structuring and Serving PWAs with the PRPL Pattern


It’s been over 10 years since the release of the first model of the iPhone. Back then, most people had primitive mobile devices, limited mostly to making calls and receiving brief text messages. Anything close to decent was considered a pleasant user experience when it came to mobile. Nobody was concerned about the status quo, because nobody was using unstable mobile devices on a daily basis to browse through sites, make purchases, etc. (at least, not yet).

Over the years, however, a powerful shift has moved users’ primary point of entry from desktop machines with fast, reliable network connections to relatively underpowered mobile devices with connections that are often slow or flaky. Unfortunately, Google reports state 53% of users abandon sites that take longer than 3 seconds to load; the average load time takes up to 19 seconds on a 3G connection and 14 seconds on a 4G connection. Now you might ask yourself: right, but how does that happen?  Why does the page load take 19 seconds? I wrote some CSS, it is responsive, it should work! Here’s the problem: the UI looks like it works, but it doesn’t work in the real world. If you think about your mobile users, a good amount of them are still using median devices—the ones they receive for free with a new mobile plan, with just 1GB of RAM. They are a little (or even a lot) better than years ago, but still slow and suffering from poor connectivity.

There’s clearly a significant gap between today’s consumer expectations, the capabilities of their devices, and the mobile behavior of most sites. The patterns we have developed for building feature-rich web apps are just not sufficient for a mobile device user anymore. In order to create the best experience, the PRPL pattern can be key to improved mobile website development and user experience.

PWAs to the Rescue

When trying to ensure that a web app is suitable for a mobile device, most organizations develop responsive apps. It could appear as a great solution to our previously mentioned problem: the pages automatically respond to the screen size, UX stays consistent across all platforms, and we only have one code base for both mobile and desktop platforms. Unfortunately, this solution comes with some limitations. Responsive Web Design has clear network dependency; as soon as the connection is lost, your page is gone. If your connection is slow, you will automatically see layout and UI glitches.

Responsive Web Design is a fast and simple solution—it doesn’t solve all problems, but it does solve some of them, and quickly. It works best, however, when it naturally moves on to Progressive Web App. While PWAs are quite new and emerging, this architecture allows your app to inherit all main behaviors of RWD such as push notifications or GPS awareness, but also offers some advanced features. Not only is the app visible immediately after entering the page, but it also works better on a slow internet connection. What’s more, thanks to clever caching methods, your content can be visible and flawless even if you are not connected to the internet.

One of the ways to achieve that improved behavior lays in a pattern for structuring and serving Progressive Web Apps with emphasis on the performance of app delivery and launch. It’s known as the PRPL pattern: push, render, pre-cache, and lazy-load. It is not a specific technology or tools, but more of a mindset and a long-term plan for improving the performance of mobile web. The specific implementation of each of the steps is out of the scope of this article, but feel free to do additional research for more information.

Page Loading Process  

What does it take to load a page, from the moment you first open that page to the moment it’s fully loaded and you can interact with it? When you try to open a site on a mobile device, an initial request is sent to a remote server somewhere far away. After some time, the server brings the response, usually in the form of an HTML document. After that, your browser runs through the HTML file to check what other resources are needed; for each additional resource, your browser needs to make a separate call to the server in order to get that resource. You’ve probably noticed: that’s a lot of calls. How do we optimize that performance?

Push Critical Resources

Not every file in your application has the same level of importance. Browsers know this, and using their own heuristic they are able to decide which files they should be fetching first. It’s useful to also tell the browser which files are more important to us. There are multiple ways of preloading critical resources faster. Some of them include rel=”preload” and rel=”prefetch”, however you may also want to explore webpack options. It may be useful to keep in mind that prefetch is better for getting ready the resources needed for different navigation routes.  In general, both of these methods allow you to mask the initial latency by preparing the resources that are important but usually take some time to load. This way your browser reads through HTML and instantly warms up the connection with the source, so by the time the browser got to the last line of the HTML file, the resource is ready to be rendered.

Render the Initial Route as soon as Possible

Providing basic user experience as soon as possible is critical when it comes to convincing users that the site they entered is worth staying on. How does it feel when you open a site that starts loading, and the only thing you see for the next 15 seconds is a blank screen? I always ask myself: is it loading? Is my connection not working? Maybe it’s my phone that is not working? Downloading and processing external stylesheets is probably blocking the content from being rendered until the whole process has finished. That creates an opportunity for improvement.

There are some parts of an application that can be pushed earlier to provide some basic user experience and assure the user of the loading progress. One method is to extract styles responsible for minimum initial rendering and inlining them in the HTML document. You can either implement that solution yourself or use already existing packages such as critical package. This way the browser would be able to render the styles right away.  Another approach to improve first paint is to server-side render the initial HTML of your page. This displays content immediately to the user while scripts are still being fetched, parsed, and executed. However, this can increase the payload of the HTML file significantly, which can harm the time it takes for your application to become interactive and thereby respond to user input. There is no single correct solution to reduce the initial load of your application, and you should only consider inlining styles and server-side rendering if the benefits outweigh the tradeoffs for your application.

Pre-cache Remaining Routes

As you probably already noticed, minimizing server-side trips can be crucial in the process of shortening page load time. Here’s where the service worker really shines. Using a service worker cache allows you to store the resources that make up the shell. On repeat visits, your browser can fetch assets directly from the cache rather than the server. This way your user will not only be able to use your application offline, but also enjoy a much faster page load. You can either create the service worker file and write the logic yourself, or use libraries such as Workbox that can make this process easier.

Lazy-Load

We’ve arrived at the moment when all of our assets are finally delivered by the server at the speed of light, but the initial paint is still slow; what’s taking so long? Almost always the most expensive asset happens to be a JavaScript bundle. From the moment it gets loaded to the moment the UI gets fully interactive, your browser goes through a few phases: it has to download the files, parse through them, compile, and finally execute. In simple terms, after your browser’s received all the resources, it now has to compute what all the files combined together look like, and how they work together. The bigger the bundle you ship, the longer it will take for the browser to parse through it and put it together.

What does it really mean for the user? Shipping a large bundle of JavaScript can significantly delay how your user will be able to interact with UI components. That means your user will be tapping on the UI without anything meaningful happening. The previously mentioned phases don’t take a lot of time on a desktop machine, but on a median mobile device, it can take forever. So how do we manage to quickly load the rest of the code necessary for the application to run? Should we just load the entire code all at once?

Instead of providing users with all of the code that makes up the entire application as soon as they land on a site you could split the code based on used routes, otherwise known as code splitting. The idea behind it is to give the user small chunks of the code that takes the currently used route. As the user navigates through the site, the browser makes additional requests for more of the fragments of code that haven’t been cached yet, and creates required views, known as lazy loading. This is another feature that you could implement yourself, but it may be worth it to use existing packages and plugins instead, such as an aggressive splitting webpack plugin.

Summary

Nowadays, through improvements in Internet browsers, the expectations toward mobile websites are set very high. The purpose of the first websites over 20 years ago was simply to share information; these days the Internet provides everything from grocery shopping, maps, real estate, social networks, chatting, tickets…everything. If you are hoping for maximum engagement from your customers, improving their mobile experience by delivering content fast and reliably may be the way to go.

 

InRhythms engineers leverage their passions to provide the best user experience for large-scale enterprises leading their fields. Subscribe below for the latest in thought leadership, or reach out to see what our rapid development strategies can do for your latest project.

Written by InRhythm · Categorized: InRhythm News, Learning and Development, Web Engineering · Tagged: best practices, development, engineering, progressive web apps, pwa, service worker, software engineering

Jul 11 2016

Code Challenge Accepted (And Answered)

One of engineers challenged our entire team with the following task:

 

Code challenge (in js, obvi).
Write a one-liner that outputs (int) 10 using only the following symbols: “+”, “[” and “]”
Oh, and you have to explain your answer.
Extra credit: Same restrictions, output (string) 20.

Now if you want to play around a little bit and try and figure out the answer – feel free! Make sure to drop your answer or logic in the comments below. Let us know if you want to see more challenges on the blog as well.

 

But for those of you who want to dive right into it – here is our answer explained!

 

What happens when we perform a math operation on an empty array?

 

+[] // 0

Int 0. Int-eresting, it looks like javascript automatically type casts our array into an int.

 

Now, using some basic cs principles we can have some fun. Let’s try outputting int 1. We know that we can get 0 from +[] so let’s try to increment it

 

++[] // Invalid left-hand side expression

Well… that sucks. However, we’ve got another trick up our sleeve. We can shove our outputted 0 into an array, access index[0] and then increment that.

 

Huh?

Just watch, you’ll get it.

 

[+[]]
That’s our array[0], now let’s get to that precious 0 it’s keeping safe for us.

 

[+[]][0]
Bingo, but we can do better. We know +[] is zero, so we can access the 0 index using +[] instead

 

[+[]][+[]]
Bang, we’ve got our 0 again. But we’ve already had a 0, what’s the difference? I’ll tell you. Nothing… except that this 0 won’t throw an invalid left handed expression error when we try to increment it.

 

++[+[]][+[]]
And there’s our int 1.

 

Let’s try and get a string 20. Seems pretty easy. We can take our newly created int 1 and increment that to a 2 then just add a string 0. But how do we get a string 0. Simple. We just add two arrays together. That makes sense, right?

 

[]+[] // empty string

Now, what happens when you add a string and an int? It gets cast as a string.

 

[++[[++[+[]][+[]]+[]]][+[]]]+[+[]] === "20" // true
Have fun wrapping your head around that one.

 

barney-more-challenges

Written by inrhythmAdmin · Categorized: Software Engineering · Tagged: challenge, code, development, engineering, growth, JavaScript, puzzle, software

Jul 13 2015

Who runs the world? Code, Code: What Development Can Teach Us About Creativity and Being Prepared for the Future

I recently read a LinkedIn post by Dan Robinson on the negative effects of social media and sharing designs and it has caused me to wonder if designers can learn more from developers than the value of coding as a skill. Maybe us designers can learn a little something about what it means to have a strong community to draw inspiration from. In his post, Robinson explores issues of self esteem and what inspiration, if any, designers can and should take from others. He highlights a common concern that we may be ‘comparing ourselves to death’ not only as individual human beings with social media and how we compare to others, but also as UX and visual designers because of constant exposure to what others are doing. Harold Bloom was an early analyst of the role of influence and peers on creativity, including his 1973 work called ‘The Anxiety of Influence’, and how the issues of feeling confident in designs will always plague designers, who often are self reflexive in their outlook to begin with.

Being a designer isn’t just about finding solutions – it’s about critiquing a state to improve it for the future, and as a result, criticism is often the default for many of us. Social media, and communities of practice, have value in learning the craft of design, and designer communities like Behance andDribbble help as a place to explore and share concepts and drafts. But, there is a downside to all of this sharing – Dribbble’s concept of a ‘shot’ often leads to designs which only look beautiful in a small, 400×300 pixels canvas. Good designers can become wracked with self consciousness if their design doesn’t look anywhere near as perfect as a final product on Dribbble. Ironically enough, the less glamorous design could be the right solution for a client and their customers even if it doesn’t win any design awards for Best Use of Flat Design on Buttons, or get voted up as noteworthy.  When we do see the perfect final version, we don’t get a feel for all the struggles which occurred behind the scenes. We don’t see the designs which were thrown out, and more disturbingly, few requirements or constraints (business or technical) are stated in a case study that accompanies that final image. Often there’s no case study at all – just an image, and people may see these final designs as solutions worth emulating. When designing more complex, enterprise transactional applications, is a simple, elegant, stylized shot found on Dribbble really the best source of inspiration? Should redesigns that focus on polish and the continual sharing of final products really be leading designers to late night bouts of existential anxiety?

How do other creative professions in technology – particularly, developers – deal with anxiety from creativity and comparing their work to others? What can designers learn from developers on how to feel confident with the sharing of their work? From the outside, developer communities appear to be less anxious and ultimately better prepared for the changes of being a professional knowledge worker due to a number of key practices about creativity which have developed as accepted standards. It’s not that designers and other professions don’t have the equivalent practices, but there may be a focus more on processes and practices in the building, and comfort in the ‘draft’ state rather than a focus on a final, finished, polished product. Some of the best developer practices when it comes to creativity include (in no particular order):

  • Pair programming as a practice: A core part of Agile development is developers pairing together to solve a problem. It’s not always a more experienced dev with a beginner – there’s an active sense of people who can be equally experienced working together through the best way to code. You can have two developers well versed in Ruby, who differ in how they construct code. There are often multiple ways to frame any solution, with no clear obvious direction. With pairing, you work through the options, put together multiple minds and find that best solution as you evaluate the options in real time. I’ve paired with designers before, and there is an active movement towards Pair Design as an initiative, but as a rule, it’s rare as an established, encouraged practice. There’s no reason why it should be, especially if multiple designers are working at the same company to help achieve consistent brand standards across products with multiple UIs. Smart companies have an active internal designer community, but in the education of designers, we rarely talk about pairing with individual designers as a practice – it’s usually one designer, and one product. Having an extra mind and set of eyes can help you see things that were missed the first time. I’ve worked with developers who sit with each other – different pairs on different days, and it’s what works for many of them.  Contrast that with the cliche of the Genius Designer silently sitting in the corner working away in his black beret. Perhaps pair designing might bring some of those solitary folks out of their shell and they will recognize the value of learning by collaboration. Maybe this will diminish the Genius Designer myth, too.
  • Communities of practice expressed in products, not just discussion: Developers have code repositories where hacking, experimentation and continual iteration are welcomed in addition to the usual forums for communication. Their tools are built out, languages created, and snippets shared on GitHub or other sites where the purpose is about sharing as much as an active finished product. Granted, it’s easier to share a code snippet than the outputs of a design especially concerning NDAs, and again, designers actively work to share their equivalent tool libraries, templates and pattern language libraries. With developers there’s a narrative that is unconsciously spoken – if you don’t like something and want to fix it, then just fork it, and make it your own. Customize it, hack it, tweak it, build it. We’re starting to see that with designers and developers building third party tools to work with Sketch and other applications, effectively building an ecosystem around the act of creating.  The sheer volume of activity on Github alone indicates that developers have beat designers to the punch, embracing the ‘building is part of being a community’ mission. Creativity for developers is building – constantly, and encouraging others to build off what they’ve done. Any hackathon is an expression of creativity and it can be astounding to watch that creativity happen. When we say ‘creative’, how often do we default to a painting, novel or dance performance? Perhaps we can see hackathons as another kind of performance where the code and collaboration are a dance that can be just as beautiful to watch.
  • Constant evolution of languages: This is a touchy subject, as the amount of coding languages and frameworks is exploding, and at a certain point there may be too many of them for any one developer to keep up with. Still, the amount of active development of new languages demonstrates how developers are constantly pushing the boundaries of what they can do with code, and exploring new ways to do it. Everything we once could do in Flash and Flex is now being replicated with CSS3. Our languages will continue to multiply as our interactive experiences online evolve, and as the devices and ways to experience a product continue to proliferate. As a career in development, it can be exhausting to constantly learn new languages, but as a form of art and creation, it shows people creating. Photoshop was a standard for so many years, and designers are only now in the last couple of years successfully evolving their languages and tools to meet the needs of these more complex and sophisticated products.  In creating new languages, the practice is less about comparing yourself to others’ output than creating something new for the sake of trying to solve a problem.
  • A commitment to continuous learning: As more languages, tools, and standards evolve in how we build products, the only constant in responding to change is adaptation and a commitment to learning. Continuous integration isn’t just about checking in your code – it’s about how we learn and keep learning, keeping our eyes open for what to learn, building upon your existing knowledge and seeing where the past and present apply to the future. Everyone – designers, developers, product, sales and more – has to commit to constant openness to learning and evolving one’s skills. But with development, that learning is embraced at a hyper accelerated rate. You may not need to be an expert in everything, but you need to have an awareness of what matters in technology, and for some concepts, at least a recognition that you have a gap which learning can address, and if you need to know about something quickly, the best source of learning is to start mastering it. Thanks to the always-in-flux nature of Web and development languages and practices, you always have to be actively learning – and there’s a potential for developers to be doing so online quickly.  It’s no surprise that there are more varied ways of learning development and computer science outside of traditional education – the rise of online education points to evolving how we learn, and that evolution speaks to how development addresses creativity, too. No surprise – the rise of the Maker movement has a strong tech focus at its core, and the message of the movement is a positive one. Anyone can be a Maker no matter their education or skills, as long as they’re willing to try creating.

No matter what the medium, creative people will always be strivers, dreamers, the people who crave more, who ask why – and often why not. No matter what the medium (paper and pen, keyboard, paintbrush, or whatever comes next in the future) striving is one of the passions which drives us to improve our craft and seek out new ways to design or develop the products and services that change lives.  The trick for creativity is to remember it’s not a race to compete with the Jones’s and the Dribbbles – it’s to start embracing your inner creative spirit and hacking for the sake of hacking.

Written by inrhythmAdmin · Categorized: Design UX/UI, Software Engineering · Tagged: community, education, engineering, language, pair programming, ux

  • « Go to Previous Page
  • Go to page 1
  • Go to page 2

Footer

Interested in learning more?
Connect with Us
InRhythm

140 Broadway
Suite 2270
New York, NY 10005

1 800 683 7813
get@inrhythm.com

Copyright © 2022 · InRhythm on Genesis Framework · WordPress · Log in

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Cookie settingsACCEPT
Privacy & Cookies Policy

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these cookies, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may have an effect on your browsing experience.
Necessary
Always Enabled
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Non-necessary
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.
SAVE & ACCEPT