web performance

in action

Agenda

  • measure
  • progressive render
  • load what you really need
  • adopt service workers
  • next

Measure

- You can’t optimize what you can’t measure

how to measure?

- timing

Performance API

Navigation Timing API

Resource Timing API(part I)


// return Array<PerformanceResourceTiming>
window.performance.getEntriesByType('resource');

interface  PerformanceResourceTiming {
 "name":"http://htmljs.b0.upaiyun.com//css/bootstrap.css?dddddddd",
 "entryType":"resource","
 startTime":3103.7999999825843,
 "duration":1137.4000000068918,
 "initiatorType":"link",
 "nextHopProtocol":"http/1.1",
 "workerStart":0,
 "redirectStart":0,
 "redirectEnd":0,
 "fetchStart":3103.7999999825843,
 "domainLookupStart":0,
 "domainLookupEnd":0,
 "connectStart":0,
 "connectEnd":0,
 "secureConnectionStart":0,
 "requestStart":0,
 "responseStart":0,
 "responseEnd":4241.199999989476,
 "transferSize":0,
 "encodedBodySize":0,
 "decodedBodySize":0,
 "serverTiming":[]
}

Resource Timing API(part II)

User Timing API

User Timing API provides a way that you can insert API calls at different parts of your Javascript and then extract detailed timing data that can be used to help you optimize.
see more at https://www.html5rocks.com/en/tutorials/webperformance/usertiming/

and more:

  • First Paint Time(FPT)
  • First Meaningful Paint(FMP)
  • Time to Interactive(TTI)
  • Above-the-fold time (AFT)
    ...

Auditing with Lighthouse

measure 

to find the bottleneck

Progressive Render

Progressive render

lazyload + fetch with priority + component based

Simple Example

adding some transitions may more friendly for users

lazyload + fetch with priority

The less importance resources should not block the key resources.

And I'm not going to dive into it ~

Component Based

<div
    class="loading-wrapper"
    style={{
      width,
      height
    }}
      >
    {isloading
      ? placeholder || <DefaultPlaceholder />
      : this.props.children}
</div>
 <Loading
  width={400}
  height={200}
  isloading={isloading}
  delay={100}
 >
  {content}
</Loading>

source code of loading

usage of loading

load what you really need

1. lazy load
2. cache

3. polyfill

1. lazy-load which needed in future

  • split app into chunks
  • avoid offscreen block
  • load images in need

split into chunks

Route-based JavaScript chunking

page-a.js

page-b.js

...
page-a.js

page-a.css

...

OR

load images in need

ignore images which outside of viewport

progressively load images scan-by-scan

Analyzing room for improvement with Webpack Bundle Analyzer

2. using cache appropriately

Using Central Store

reliable

Redux

Using Cache

may be unreliable

service worker

  • Caching assets with Service Worker
  • v8 code caching

remove useless polyfill

eg: Use babel-preset-env to only transpile what target browsers need

{
  "presets": [
    ["env", {
      "targets": {
        "browsers": ["last 2 versions"]
      }
    }]
  ]
}

.babelrc

Next

Chrome Dev Tool

1. network(find and optimize critical path)

2. memory leak

3. render(especially for animation)

Made with Slides.com