CHALLENGES FOR FRONT END DEVELOPERS OF LARGE WEB APPLICATIONS Graham - - PowerPoint PPT Presentation

challenges for front end developers of large web
SMART_READER_LITE
LIVE PREVIEW

CHALLENGES FOR FRONT END DEVELOPERS OF LARGE WEB APPLICATIONS Graham - - PowerPoint PPT Presentation

CHALLENGES FOR FRONT END DEVELOPERS OF LARGE WEB APPLICATIONS Graham Hinchly FT Labs Me app.ft.com Some things on the web are hard When you have a large amount of code they get really hard But why is it harder on the web than


slide-1
SLIDE 1

CHALLENGES FOR FRONT END DEVELOPERS OF LARGE WEB APPLICATIONS

Graham Hinchly FT Labs

slide-2
SLIDE 2

Me

slide-3
SLIDE 3

app.ft.com

slide-4
SLIDE 4

Some things on the web are hard

slide-5
SLIDE 5

When you have a large amount of code they get really hard

slide-6
SLIDE 6

But why is it harder on the web than elsewhere?

slide-7
SLIDE 7

Languages lack encapsulation

slide-8
SLIDE 8

Browser rendering model designed for documents

slide-9
SLIDE 9

Built around assumption of always

  • n, stable internet connection

by GraciolliDotCom - https://www.flickr.com/photos/marcelograciolli/2807100863

slide-10
SLIDE 10

How do we deal with this?

slide-11
SLIDE 11

Scream in the street for a bit. YMMV.

by mdanys -https://www.flickr.com/photos/mindaugasdanys/3766009204/

slide-12
SLIDE 12

Offline Modularisation Performance

slide-13
SLIDE 13

Modularisation

Encapsulation, managing dependencies and using components

slide-14
SLIDE 14

Encapsulation is our friend

slide-15
SLIDE 15

CommonJS Spec

  • Declare dependencies

at the top of the file with require

  • Expose public API via

exports

  • Not supported by the

browser

// Declare dependencies var depA = require(“depA”); var depB = require(“./../depB);

  • /**

Module code **/

  • // Export public API

exports.foo = foo;

slide-16
SLIDE 16

Allows you to write JavaScript like this

slide-17
SLIDE 17

But what if I want to use bits

  • f other peoples’ code…
slide-18
SLIDE 18

Cleanly manages your JavaScript dependencies

slide-19
SLIDE 19

npm + browserify

  • Install from npm

registry

  • …or specify git URL
  • Great for breaking up a

monolith

$ npm install fastclick --save

{ "name": "ft-app", "dependencies": { "fastclick": "^1.0.3", [...] } }

package.json someModule.js

var fc = require(“fastclick”); /** Module code **/

slide-20
SLIDE 20

It’s not perfect (yet…)

– Git tags don’t guarantee repeatability

  • Use npm-shrinkwrap

– Registry introduces a single point of failure

  • We use a private lazy cache
slide-21
SLIDE 21

CSS isn’t encapsulated either…

slide-22
SLIDE 22

Leak-proof styling for reusable components

  • Context agnostic
  • Non-semantic naming –

clear that it’s reusable

  • Classes prefixed with

component name

.apple {} .apple_headline { font-size: 40px; } .apple_subhead { font-size: 20px; } .apple_body { font-size: 14px; column-count: 2; color: #333 }

  • <div class=“apple”>

<h2 class=“apple_headline”>… <h3 class=“apple_subhead”>… <div class=“apple_body”>… </div>

Code example from smashingmagazine.com/ 2013/05/23/building-the-new-financial-times- web-app-a-case-study/

slide-23
SLIDE 23

Works for one app – what about sharing components across an entire organisation?

slide-24
SLIDE 24
  • rigami.ft.com
slide-25
SLIDE 25

The future – fully encapsulated web components?

slide-26
SLIDE 26

Performance

Maintaining smooth animations and a responsive UI

slide-27
SLIDE 27

Long running processes block user interactions

Perils of a single thread

slide-28
SLIDE 28

Missed frames make animations, scrolling and swiping feel “janky”

Synchronous tasks also block screen updates

Perils of a single thread

slide-29
SLIDE 29

6 frames per second Great for animated gifs Rubbish for your app

slide-30
SLIDE 30

Consistent frame rate

We want something that’s silky smooth, so we aim for 60 frames per second. This gives us just 16.6ms between frames

slide-31
SLIDE 31

What happens on this thread?

JavaScript execution Style recalculation Layout Paint

slide-32
SLIDE 32

JavaScript execution

JavaScript execution is rarely the bottleneck

slide-33
SLIDE 33

Style recalculation Layout Paint

Which means we need to understand the other

  • perations taking place (sorry!)
slide-34
SLIDE 34

Layout

Working out what goes where on the screen

Style recalculation

Working out what things should look like from CSS & DOM

Paint

Putting the pixels onto the screen*

* Technically this is the browser painting to a bitmap and then uploading to the GPU rather than putting pixels directly on the screen

slide-35
SLIDE 35

Use animation effects which avoid relayout/paint

  • transforms:

– translate – scale – rotation

  • pacity
  • These use the GPU, which is
  • ptimised for just such a task

// Position/margin slow style.top = x; style.marginLeft = x;

  • // translate & translate3d fast

style[transform] = “translate(“ + x + “px,“ + x + “px)”;

  • /** may need to use “translateZ

hack” to manually force layer creation **/ style[transform] = “translateZ(0)”

slide-36
SLIDE 36

If you can’t eliminate, reduce time spent doing these tasks

slide-37
SLIDE 37

Time for some detective work…

by minifig - https://www.flickr.com/photos/minifig/3174009125

slide-38
SLIDE 38

Timeline – shows us time spent in JS execution, layout and paint

From: http://www.html5rocks.com/en/tutorials/speed/high-performance-animations/

slide-39
SLIDE 39

Timeline “frames view” shows amount of work required to render each frame

Taller bars = slower We want all our frames below the 60 FPS line

slide-40
SLIDE 40

Let’s see how much time the entire page would take to paint…

slide-41
SLIDE 41

Keep your painting simple…

  • Hide elements to see what impact they

make on page paint time

  • Common suspects: lots of box-shadow

and border-radius

by Colin Tsoi -https://www.flickr.com/photos/cokedragon/9047633335/

slide-42
SLIDE 42

Reducing relayout

Writing to the DOM invalidates previous calculations Reading a geometric value from the DOM once it has been invalidated forces a relayout

slide-43
SLIDE 43

Reducing relayout

Doing this repeatedly prevents the browser from being able to render a frame, resulting in dropped frames

slide-44
SLIDE 44

Batch DOM read/writes

Instead we can queue these reads and writes together, and execute them once per frame

slide-45
SLIDE 45

This can be hard to do manually, especially with lots of components, but we can manage it with a library:

wilsonpage/fastdom

slide-46
SLIDE 46

Putting it all together: Swiping on app.ft.com

ftlabs/ftscroller

slide-47
SLIDE 47

More

  • Videos
  • Debugging CSS & Render Performance

– https://developers.google.com/events/io/sessions/ 324511365

  • Lots of good tutorials/blogs
  • html5rocks.com/en/features/performance
  • jankfree.org/
  • Paul Lewis: aerotwist.com/
slide-48
SLIDE 48

Offline

Client-side storage options and their limitations

slide-49
SLIDE 49

Cookies LocalStorage (fast, but synchronous) AppCache (flawed, but usable) IndexedDB (async, but tricky to use)

Client Side Storage Options

slide-50
SLIDE 50

Cookies LocalStorage AppCache IndexedDB

AppCache

  • Well intentioned, but flawed
  • However, it is usable

– We use it for bare minimum: bootstrap code, fonts, splash screen images

slide-51
SLIDE 51

Cookies LocalStorage AppCache IndexedDB

LocalStorage

  • Simple API
  • Fast…?
slide-52
SLIDE 52

Cookies LocalStorage AppCache IndexedDB

Faster than cache…

http://www.mobify.com/blog/smartphone-localstorage-outperforms-browser-cache/

slide-53
SLIDE 53

Cookies LocalStorage AppCache IndexedDB

LocalStorage

  • But:

– Limited storage – Synchronous

  • File I/O for persistence means it can

have variable performance – Odd behaviour in Safari private browsing – We use a lightweight wrapper called Superstore by Matt Andrews

matthew-andrews/superstore

slide-54
SLIDE 54

Cookies LocalStorage AppCache IndexedDB

IndexedDB

  • Async key value object store

– We use this for articles and images

  • Not supported everywhere - use polyfill [1] to

support (long deprecated) WebSQL

  • Managing versions and migrations can be

awkward

  • Documentation is variable

[1] http://nparashuram.com/IndexedDBShim/ or https://github.com/mozilla/localForage

slide-55
SLIDE 55

Future: ServiceWorker

  • Sits in the middle of browser and network
  • Lots of good things:

– Extensible w/ low level, granular control – “Cache API” for storage – Async

  • But:

– No access to localStorage – HTTPS only

slide-56
SLIDE 56

More

  • Tutorial: Building an offline web app

labs.ft.com/2012/08/basic-offline-html5-web-app/

  • Storage quotas:

html5rocks.com/en/tutorials/offline/quota-research

  • Maximising storage by using UTF-8 instead of UTF-16:

labs.ft.com/2012/06/text-re-encoding-for-optimising-storage- capacity-in-the-browser/

  • Using ServiceWorker today:

jakearchibald.com/2014/using-serviceworker-today/

slide-57
SLIDE 57

Summary

slide-58
SLIDE 58

A quick recap….

  • Modularisation

– npm + browserify works well for managing client side JS dependencies – Prefixed class names for CSS component elements

  • Performance

– Good tools, profile your own use case. Look out for relayout and paint as bottlenecks – batch DOM read/writes and stick to known fast animations

  • Offline

– Hard with limited options, prefer async IndexedDB, look out for ServiceWorker

slide-59
SLIDE 59

Thanks!

grahamhinchly graham.hinchly@ft.com labs.ft.com/jobs ftlabs | financial-times