Upload
klaus-enzenhofer
View
115
Download
0
Embed Size (px)
Citation preview
3 Tips to Deliver Fast Performance Across Mobile WebStefan Baumgartner @ddprrtKlaus Enzenhofer @kenzenhofer
Who we are
4.5 sec 15 sec
Why?
NetworkSame Page
4.5 sec 15 secSanity Check
Browser CheckChrome 49 Chrome Mobile 33
Server SideLocal WLANLocal WLAN
Only difference is Browser & Device
Why did they look at the performance on the mobile device?
Google - Mobile Friendliness Campaign?!
Change in their compensations
plan!
Contract SLA: Average Response Time < 3
sec
User
on Desktop + Mobile
Good idea?!
Let’s talk about response time
NetworkSame Page
4.5 sec 15 secSanity Check
Browser CheckChrome 49 Chrome Mobile 33
Server SideLocal WLANLocal WLAN
4.5 sec 15 sec
UserDeveloper Operator
Let‘s take a look at the timings!Navigation Start: 0 ms
Domain Lookup End: 269 ms
Connect End: 330 ms
Response Start: 517 ms
Response End:518 ms
Dom Loading: 519 ms
Dom Interactive: 519 ms
DomContentLoaded Event End: 520 ms
Dom Complete: 520 ms
Load Event End:522 ms
0.5 sec 0.5 sec
Developer
User Operator
User
DNS Lookup
Initial connection
TTFB
(HTML)Download
Life of an URL request
Starting here, we are able to control …
<script src=“angular.js”> blocking!
<script src=“angular.js”> blocking!<script src=“main.js”> blocking!
<script src=“angular.js”> blocking!<script src=“main.js”> blocking!
start render
<script src=“angular.js”> blocking!<script src=“main.js”> blocking!
start renderresponse time
The impact of a JavaScript error
<script src=“angular.js”> blocking!<script src=“main.js”> blocking!
start render?
Important content first Everthing else is an
enhancement
Single page application frameworks are aware of this trend
- As long as you have valid routes (= URLs), you have the ability to render the state on the server
- The first two requests are the document and the styles of your application
- Then the JS framework kicks in
Server-side rendering for SPA
Brow
ser
App
Serv
ing
asse
tsAP
I Ser
ver
GET /app
JavaScript payload
GET /api/users
JSON payload
GET /api/posts
GET /api/pages
JSON payload
JSON payload
Send index.html
Request JS application
Brow
ser
App
Uni
vers
al re
nder
ing
API S
erve
r
GET /app
JavaScript payload
GET /api/users
JSON payload
GET /api/posts
GET /api/pages
JSON payload
JSON payload
Initial render HTML + CSS
Request JS application
4.5 sec 6 sec
UserDeveloper Operator
Operator
The CDN bill exploded!
285 Resources for an initial Page Load
151 CSS and 121 JavaScript files
~200 Resources had larger Header than Body
User
Mobile Data is expensive
https
://w
hatd
oesm
ysite
cost
.com
http://cdn.shopify.com/s/files/1/1462/9702/articles/26_cangoroo_1024x1024.jpg?v=1473016235
Back Home
Back Home
HTTP Archive – Transfer Size Trend
http://httparchive.org/trends.php
Average Size ~2 500 KB By 1.6 € per 100 KB
40 € to get started!!!!
2. Page weight
There’s lots of ways to reduce the payload
Responsive images
<img src=”screenshot-600.png” srcset="screenshot-200.png 200w, screenshot-400.png 400w, screenshot-600.png 600w, screenshot-800.png 800w, screenshot-1000.png 1000w, screenshot-1200.png 1200w, screenshot-1400.png 1400w, screenshot-1600.png 1600w” sizes="(min-width: 900px) 50vw, 100vw" alt=”Super screenshot of our product.">
<img src=”screenshot-600.png” srcset="screenshot-200.png 200w, screenshot-400.png 400w, screenshot-600.png 600w, screenshot-800.png 800w, screenshot-1000.png 1000w, screenshot-1200.png 1200w, screenshot-1400.png 1400w, screenshot-1600.png 1600w” sizes="(min-width: 900px) 50vw, 100vw" alt=”Super screenshot of our product.">
These sources are available. For each “width unit”there’s a reduced version of our original screenshot
The sizes define which source to choose from. Retina screensare also checked
A low-res fallback image for browsers that don’t know srcset
Reduce styles
Tree shaking
4.5 sec 6 sec
UserDeveloper Operator
3. Now for the returning visitor
Service worker
if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js') .then(function(registration) { // Registration was successful console.log('ServiceWorker registration successful with scope: ', registration.scope); }).catch(function(err) { // registration failed :( console.log('ServiceWorker registration failed: ', err); });}
self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request) .then(function(response) { // Cache hit - return response if (response) { return response; } return fetch(event.request); }) );});
var CACHE_NAME = 'my-site-cache-v1';var urlsToCache = [ '/', '/styles/main.css', '/script/main.js' ]; self.addEventListener('install', function(event) { // Perform install steps event.waitUntil( caches.open(CACHE_NAME) .then(function(cache) { console.log('Opened cache'); return cache.addAll(urlsToCache); }) );});
2 sec 2.5 sec
UserDeveloper Operator
4.5 sec 15 secUserDeveloper Operator
UserDeveloper Operator
How to?
2.5 sec2 sec
4.5 sec 15 secUserDeveloper Operator
UserDeveloper Operator
How to?
2.5 sec2 sec
Happy Developer != Happy User
Your user might travel and mobile data is expensive
The returning user will appriciate your caching strategy
You don‘t know how happy your users are?
https://www.dynatrace.com/trial/
Thank you!Stefan Baumgartner
@ddpprtKlaus Enzenhofer
@kenzenhofer