SlideShare une entreprise Scribd logo
1  sur  70
Télécharger pour lire hors ligne
Yves Goeleven
Solution Architect & Azure MVP
• Particular Software / NServiceBus
• Side projects
• MessageHandler: Event stream processing & event sourcing framework
• Dish: Static site generator
• ClubManagement.io: Progressive Web Apps for managing sports clubs
• Azure MVP since 2010
• Co-founder & board member @ AZUG.be
• Board member @ Basket Lummen
This means I’m
old & develop
software
Web development
A brief history with major milestones
1993 Today1995
First browser war!
Client side incompatibilities, but
you could standardize on IE
1996 2004
Second browser war!
More browsers,
more incompatibilities
20092007
Third browser war!
Battle against mobile leads to standardization
2012
Revenge of the static website
Why?
3 reasons
• It’s cheap!
• It’s simple!
• Single codebase for any app (PWA)
• Web, desktop & mobile apps!
• Offline
The story of basketlummen.be
The story of basketlummen.be
Cost
Model
Simple
Architecture
Offline App
Increase
compared to
previous hosting
Flat rate
That’s more like
it!
Usage based
More value for less money
New site is a lot bigger than the old one
The story of basketlummen.be
Cost
Model
Simple
Architecture
Offline App
Old site
Architecture
Browser
Server
#@ %!)
New site
JAM Stack
Browser
NOT MY PROBLEM!
The story of basketlummen.be
Cost
Model
Simple
Architecture
Offline App
New fundraising app
Progressive Web App
Browser
NOT MY PROBLEM!
Setting up cheap hosting
Azure
Storage
Azure CDN DNS
Required for
service worker
Setting up cheap hosting
Azure
Storage
Azure CDN DNS
Why CDN?
2 reasons
• FREE SSL for custom domain names!
• Reduce storage transaction costs
• Ensure cache control headers are set on blobs!
Setting up cheap hosting
Azure
Storage
Azure CDN DNS
Managing the site content
Dynamic
content
Static Site
Generation
Local
Experience
Publishing
Process
Dynamic content
The traditional way: render on every request
Browser
Server
#@ %!)
Dynamic content
Not all content is equal
Change rate vs
user expectations
Real Time Delay Stale
No changes Manual publishing Manual publishing Manual publishing
Occasional On every request Automated publishing Manual publishing
Frequent On every request Automated publishing Manual publishing
In a static site context
• On every request: API call with client side rendering
• Manual publishing: Update the site and publish
• Automated publishing: Plug the publishing process into your business
processes
Managing the site content
Dynamic
content
Static Site
Generation
Local
Experience
Publishing
Process
Static site generator
An essential tool in the publishing process
• Renders a website from content files
• Content files in appropriate format
• Text: markdown
• Config: Yaml
• Templates: Handlebars
• A multistep build pipeline (chain of responsibility)
• Read files
• Preprocessing steps
• Rendering
• Postprocessing steps
• Most popular ones: Jekyll, Hexo, Hugo, …
Introducing DISH
Why I built my own static site generator
• A library
• .Net core
• Plug into my business logic
• Full control of the pipeline
• E.g. publish to azure storage static websites
Managing the site content
Dynamic
content
Static Site
Generation
Local
Experience
Publishing
Process
Local Experience
Requires a command line tool
• Write a console app using the library
• Main generation methods
• Run: generates the site
• Serve: generates & hosts the site locally in Kestrel
• Publish: generates & uploads the site to azure storage static websites
Managing the site content
Dynamic
content
Static Site
Generation
Local
Experience
Publishing
Process
Publishing process
End to end process
Sources in
github
Pull
Run site
generation
Publish Purge CDN
Yes, some
parents do
submit PR’s
Dish
Manual or
Microsoft.Azure.
Management.Cdn
Manual or
invocation from
code using
octokit
Building offline apps
Google
workbox
App Shell
pattern
Command
Queue Pattern
Install on
desktop
How it works when offline
Service Worker intercepts and serves from IndexedDB
Browser
Services
X
Service Worker
Background worker for a web pages
• Also runs when browser is closed!
• Available events
• Install: Fired whenever the worker gets installed (happens only once)
• Activate: Fired whenever a loaded page connects to the worker
• Fetch: Fired every time a connected client performs a request
• Message: Communication between frontend thread and background worker
• Sync: Fired after device comes online
• Push: Fired when device receives a push notification
• But you need to write code to handle all those events
self.addEventListener('install', function(event){
// your code here
});
Google workbox
A set of common patterns for Service Worker
• A javascript library on top of indexed DB & cache storage responding to service worker events
• Available modules
• Precaching: preload files on install
• Routing: configure how to handle specific web requests
• Strategies: caching strategies
• Expiration: remove cached entries
• BackgroundSync: resubmit commands after coming online
• …
importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.6.1/workbox-sw.js');
workbox.core.setCacheNameDetails({
prefix: 'clubmgmt-fundraising-checkin-cache’,
suffix: ‘1.0.0.0’
});
Building offline apps
Google
workbox
App Shell
pattern
Command
Queue Pattern
Install on
desktop
App Shell pattern
‘Installation’ of all files of the web app
• Service worker ‘Install’ event
• All essential files for the app will be downloaded and cached
• Route with a ‘Cache-first’ policy: Cache Falling Back to Network
• Files must be versioned
• Revision hashes generated by Dish postprocessing step
• Embed hashes, service worker file must change for changes to take effect
• Your app shell can run offline now, future pages served from cache
workbox.precaching.precacheAndRoute(self.__precacheManifest || []);
self.__precacheManifest = [
{ url:’/index.html', revision: '16a3cdb338289d….74564ccd3db2430bac’ },
{ url:'/css/bootstrap.min.css', revision: '5a3d8c05785485d3….8b5bd7b0f3168fff1bd9a' },
{ url:'/css/console.css', revision: '900797671c753ea9b421….f1db2874f32d6264996801' },
….
]
Building offline apps
Google
workbox
App Shell
pattern
Command
Queue Pattern
Install on
desktop
Command Queue pattern
‘Store and forward’ command requests when offline
• Store ‘POST’, ‘PUT’ & ‘DELETE’ requests on failure to send
const queue = new workbox.backgroundSync.Queue('bg-queue', {
onSync: replayRequests,
maxRetentionTime: 7 * 24 * 60 // Retry for max a week
});
const bgSync = {
fetchDidFail: async ({ request }) => {
await queue.pushRequest({ request });
}
}
workbox.routing.registerRoute(
/.+/api/.+/,
new workbox.strategies.NetworkOnly({
plugins: [bgSync]
}),
'POST'
);
Command Queue pattern
‘Replay’ when back online
async function replayRequests(o){
if(unableToSend()) return;
while (entry = await o.queue.shiftRequest()) {
try {
if(unableToSend()){ // prevents infinite loop if connectivity drops while replaying
await o.queue.unshiftRequest(entry); return;
}
var req = entry.request.clone();
// fix headers with latest tokens
req.headers.set('Authorization', "Bearer " + self.__authContext.accessToken);
req.headers.set('Authority', self.__authContext.authorityToken);
await fetch(req);
} catch (error) {
await o.queue.unshiftRequest(entry);
}}
}
Building offline apps
Google
workbox
App Shell
pattern
Command
Queue Pattern
Install on
desktop
Install on desktop
Progressive Web App behaves like a mobile or desktop app
• Install experience
• Desktop
• Mobile
• Home screen / desktop icon
• Minimal requirements
• Manifest.json file
• HTTPS
• Service Worker
Web App Manifest
Manifest.json
{
"short_name": "Clubmanagement Checkin",
"name": "Clubmanagement Fundraising Checkin",
"description": "An offline tool for handling check-ins at fundraising events",
"lang": "nl-BE",
"icons": [{ "src": "/img/logo_256.png", "type": "image/png", "sizes": "256x256"},
{ "src": "/img/logo_192.png", "type": "image/png", "sizes": "192x192“},
{ "src": "/img/logo_512.png", "type": "image/png", "sizes": "512x512"}],
"start_url": "/dashboard/",
"background_color": "#EEEEEE",
"theme_color": "#00A5D5",
"display": "standalone",
"related_applications": [{
"platform": "web",
"url": "https://fundraising-checkin.clubmanagement.io"
}]
}
Ready for revenge
of the static website ?
Conclusion
Static websites provide a great client development platform
• It’s cheap!
• It’s simple!
• Single codebase for any app (PWA)
• Web, desktop & mobile apps!
• Offline
Q&A

Contenu connexe

Tendances

Put a Button on It: Removing Barriers to Going Fast
Put a Button on It: Removing Barriers to Going FastPut a Button on It: Removing Barriers to Going Fast
Put a Button on It: Removing Barriers to Going Fast
OSCON Byrum
 
Performance and scalability with drupal
Performance and scalability with drupalPerformance and scalability with drupal
Performance and scalability with drupal
Ronan Berder
 
Riding rails for 10 years
Riding rails for 10 yearsRiding rails for 10 years
Riding rails for 10 years
jduff
 

Tendances (20)

Quick and Easy Development with Node.js and Couchbase Server
Quick and Easy Development with Node.js and Couchbase ServerQuick and Easy Development with Node.js and Couchbase Server
Quick and Easy Development with Node.js and Couchbase Server
 
Michael North "Ember.js 2 - Future-friendly ambitious apps, that scale!"
Michael North "Ember.js 2 - Future-friendly ambitious apps, that scale!"Michael North "Ember.js 2 - Future-friendly ambitious apps, that scale!"
Michael North "Ember.js 2 - Future-friendly ambitious apps, that scale!"
 
SOA on Rails
SOA on RailsSOA on Rails
SOA on Rails
 
Drupal, Android and iPhone
Drupal, Android and iPhoneDrupal, Android and iPhone
Drupal, Android and iPhone
 
Adobe AEM for Business Heads
Adobe AEM for Business HeadsAdobe AEM for Business Heads
Adobe AEM for Business Heads
 
In-browser storage and me
In-browser storage and meIn-browser storage and me
In-browser storage and me
 
Using Packer to Migrate XenServer Infrastructure to CloudStack
Using Packer to Migrate XenServer Infrastructure to CloudStackUsing Packer to Migrate XenServer Infrastructure to CloudStack
Using Packer to Migrate XenServer Infrastructure to CloudStack
 
How to make your Webpack builds 10x faster
How to make your Webpack builds 10x fasterHow to make your Webpack builds 10x faster
How to make your Webpack builds 10x faster
 
Tech connect aws
Tech connect  awsTech connect  aws
Tech connect aws
 
Put a Button on It: Removing Barriers to Going Fast
Put a Button on It: Removing Barriers to Going FastPut a Button on It: Removing Barriers to Going Fast
Put a Button on It: Removing Barriers to Going Fast
 
SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS ...
SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS ...SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS ...
SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS ...
 
WordPress and The Command Line
WordPress and The Command LineWordPress and The Command Line
WordPress and The Command Line
 
Performance and scalability with drupal
Performance and scalability with drupalPerformance and scalability with drupal
Performance and scalability with drupal
 
Web optimization with service woker
Web optimization with service wokerWeb optimization with service woker
Web optimization with service woker
 
Aos canadian tour (YOW) @energizedtech - Manage AzureRM with powershell
Aos canadian tour (YOW)  @energizedtech - Manage AzureRM with powershellAos canadian tour (YOW)  @energizedtech - Manage AzureRM with powershell
Aos canadian tour (YOW) @energizedtech - Manage AzureRM with powershell
 
User Transparent Service Migration to the Cloud
User Transparent Service Migration to the CloudUser Transparent Service Migration to the Cloud
User Transparent Service Migration to the Cloud
 
Padrino - the Godfather of Sinatra
Padrino - the Godfather of SinatraPadrino - the Godfather of Sinatra
Padrino - the Godfather of Sinatra
 
Riding rails for 10 years
Riding rails for 10 yearsRiding rails for 10 years
Riding rails for 10 years
 
WebAssembly vs JavaScript: What is faster?
WebAssembly vs JavaScript: What is faster?WebAssembly vs JavaScript: What is faster?
WebAssembly vs JavaScript: What is faster?
 
Frameworks and webcomponents
Frameworks and webcomponentsFrameworks and webcomponents
Frameworks and webcomponents
 

Similaire à Back to the 90s' - Revenge of the static website

Intro to node and mongodb 1
Intro to node and mongodb   1Intro to node and mongodb   1
Intro to node and mongodb 1
Mohammad Qureshi
 

Similaire à Back to the 90s' - Revenge of the static website (20)

[Struyf] Automate Your Tasks With Azure Functions
[Struyf] Automate Your Tasks With Azure Functions[Struyf] Automate Your Tasks With Azure Functions
[Struyf] Automate Your Tasks With Azure Functions
 
DevOps, Continuous Integration and Deployment on AWS: Putting Money Back into...
DevOps, Continuous Integration and Deployment on AWS: Putting Money Back into...DevOps, Continuous Integration and Deployment on AWS: Putting Money Back into...
DevOps, Continuous Integration and Deployment on AWS: Putting Money Back into...
 
Devops continuousintegration and deployment onaws puttingmoneybackintoyourmis...
Devops continuousintegration and deployment onaws puttingmoneybackintoyourmis...Devops continuousintegration and deployment onaws puttingmoneybackintoyourmis...
Devops continuousintegration and deployment onaws puttingmoneybackintoyourmis...
 
Developing High Performance Web Apps - CodeMash 2011
Developing High Performance Web Apps - CodeMash 2011Developing High Performance Web Apps - CodeMash 2011
Developing High Performance Web Apps - CodeMash 2011
 
AWS as platform for scalable applications
AWS as platform for scalable applicationsAWS as platform for scalable applications
AWS as platform for scalable applications
 
Building API in the cloud using Azure Functions
Building API in the cloud using Azure FunctionsBuilding API in the cloud using Azure Functions
Building API in the cloud using Azure Functions
 
SenchaCon 2016: Develop, Test & Deploy with Docker - Jonas Schwabe
SenchaCon 2016: Develop, Test & Deploy with Docker - Jonas Schwabe SenchaCon 2016: Develop, Test & Deploy with Docker - Jonas Schwabe
SenchaCon 2016: Develop, Test & Deploy with Docker - Jonas Schwabe
 
ITB2017 - Keynote
ITB2017 - KeynoteITB2017 - Keynote
ITB2017 - Keynote
 
Building SPA’s (Single Page App) with Backbone.js
Building SPA’s (Single Page App) with Backbone.jsBuilding SPA’s (Single Page App) with Backbone.js
Building SPA’s (Single Page App) with Backbone.js
 
Serverless technologies with Kubernetes
Serverless technologies with KubernetesServerless technologies with Kubernetes
Serverless technologies with Kubernetes
 
Intro to node and mongodb 1
Intro to node and mongodb   1Intro to node and mongodb   1
Intro to node and mongodb 1
 
Azure Functions Real World Examples
Azure Functions Real World Examples Azure Functions Real World Examples
Azure Functions Real World Examples
 
CouchDB for Web Applications - Erlang Factory London 2009
CouchDB for Web Applications - Erlang Factory London 2009CouchDB for Web Applications - Erlang Factory London 2009
CouchDB for Web Applications - Erlang Factory London 2009
 
Groovy & Grails eXchange 2012 vert.x presentation
Groovy & Grails eXchange 2012 vert.x presentationGroovy & Grails eXchange 2012 vert.x presentation
Groovy & Grails eXchange 2012 vert.x presentation
 
Iac d.damyanov 4.pptx
Iac d.damyanov 4.pptxIac d.damyanov 4.pptx
Iac d.damyanov 4.pptx
 
Hosting Ruby Web Apps
Hosting Ruby Web AppsHosting Ruby Web Apps
Hosting Ruby Web Apps
 
SenchaCon 2016: A Look Ahead: Survey Next-Gen Modern Browser APIs - Shikhir S...
SenchaCon 2016: A Look Ahead: Survey Next-Gen Modern Browser APIs - Shikhir S...SenchaCon 2016: A Look Ahead: Survey Next-Gen Modern Browser APIs - Shikhir S...
SenchaCon 2016: A Look Ahead: Survey Next-Gen Modern Browser APIs - Shikhir S...
 
Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...
Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...
Containerisation Hack of a Legacy Software Solution - Alex Carter - CodeMill ...
 
Developing in the Cloud
Developing in the CloudDeveloping in the Cloud
Developing in the Cloud
 
Code First with Serverless Azure Functions
Code First with Serverless Azure FunctionsCode First with Serverless Azure Functions
Code First with Serverless Azure Functions
 

Plus de Yves Goeleven (10)

Azure storage deep dive
Azure storage deep diveAzure storage deep dive
Azure storage deep dive
 
Io t privacy and security considerations
Io t   privacy and security considerationsIo t   privacy and security considerations
Io t privacy and security considerations
 
Connecting your app to the real world
Connecting your app to the real worldConnecting your app to the real world
Connecting your app to the real world
 
Madn - connecting things with people
Madn - connecting things with peopleMadn - connecting things with people
Madn - connecting things with people
 
Message handler customer deck
Message handler customer deckMessage handler customer deck
Message handler customer deck
 
Cloudbrew - Internet Of Things
Cloudbrew - Internet Of ThingsCloudbrew - Internet Of Things
Cloudbrew - Internet Of Things
 
Windows azure storage services
Windows azure storage servicesWindows azure storage services
Windows azure storage services
 
Azug - successfully breeding rabits
Azug - successfully breeding rabitsAzug - successfully breeding rabits
Azug - successfully breeding rabits
 
Eda on the azure services platform
Eda on the azure services platformEda on the azure services platform
Eda on the azure services platform
 
Sql Azure
Sql AzureSql Azure
Sql Azure
 

Dernier

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Dernier (20)

presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 

Back to the 90s' - Revenge of the static website

  • 1.
  • 2. Yves Goeleven Solution Architect & Azure MVP • Particular Software / NServiceBus • Side projects • MessageHandler: Event stream processing & event sourcing framework • Dish: Static site generator • ClubManagement.io: Progressive Web Apps for managing sports clubs • Azure MVP since 2010 • Co-founder & board member @ AZUG.be • Board member @ Basket Lummen This means I’m old & develop software
  • 3.
  • 4. Web development A brief history with major milestones 1993 Today1995 First browser war! Client side incompatibilities, but you could standardize on IE 1996 2004 Second browser war! More browsers, more incompatibilities 20092007 Third browser war! Battle against mobile leads to standardization 2012
  • 5. Revenge of the static website
  • 6. Why? 3 reasons • It’s cheap! • It’s simple! • Single codebase for any app (PWA) • Web, desktop & mobile apps! • Offline
  • 7. The story of basketlummen.be
  • 8.
  • 9.
  • 10.
  • 11.
  • 12. The story of basketlummen.be Cost Model Simple Architecture Offline App
  • 14.
  • 16. More value for less money New site is a lot bigger than the old one
  • 17. The story of basketlummen.be Cost Model Simple Architecture Offline App
  • 20. The story of basketlummen.be Cost Model Simple Architecture Offline App
  • 21.
  • 22.
  • 23.
  • 24.
  • 25. New fundraising app Progressive Web App Browser NOT MY PROBLEM!
  • 26. Setting up cheap hosting Azure Storage Azure CDN DNS
  • 27.
  • 28.
  • 30. Setting up cheap hosting Azure Storage Azure CDN DNS
  • 31. Why CDN? 2 reasons • FREE SSL for custom domain names! • Reduce storage transaction costs • Ensure cache control headers are set on blobs!
  • 32.
  • 33. Setting up cheap hosting Azure Storage Azure CDN DNS
  • 34.
  • 35.
  • 36.
  • 37. Managing the site content Dynamic content Static Site Generation Local Experience Publishing Process
  • 38. Dynamic content The traditional way: render on every request Browser Server #@ %!)
  • 39. Dynamic content Not all content is equal Change rate vs user expectations Real Time Delay Stale No changes Manual publishing Manual publishing Manual publishing Occasional On every request Automated publishing Manual publishing Frequent On every request Automated publishing Manual publishing In a static site context • On every request: API call with client side rendering • Manual publishing: Update the site and publish • Automated publishing: Plug the publishing process into your business processes
  • 40. Managing the site content Dynamic content Static Site Generation Local Experience Publishing Process
  • 41. Static site generator An essential tool in the publishing process • Renders a website from content files • Content files in appropriate format • Text: markdown • Config: Yaml • Templates: Handlebars • A multistep build pipeline (chain of responsibility) • Read files • Preprocessing steps • Rendering • Postprocessing steps • Most popular ones: Jekyll, Hexo, Hugo, …
  • 42. Introducing DISH Why I built my own static site generator • A library • .Net core • Plug into my business logic • Full control of the pipeline • E.g. publish to azure storage static websites
  • 43.
  • 44. Managing the site content Dynamic content Static Site Generation Local Experience Publishing Process
  • 45. Local Experience Requires a command line tool • Write a console app using the library • Main generation methods • Run: generates the site • Serve: generates & hosts the site locally in Kestrel • Publish: generates & uploads the site to azure storage static websites
  • 46.
  • 47. Managing the site content Dynamic content Static Site Generation Local Experience Publishing Process
  • 48. Publishing process End to end process Sources in github Pull Run site generation Publish Purge CDN Yes, some parents do submit PR’s Dish Manual or Microsoft.Azure. Management.Cdn Manual or invocation from code using octokit
  • 49.
  • 50.
  • 51. Building offline apps Google workbox App Shell pattern Command Queue Pattern Install on desktop
  • 52. How it works when offline Service Worker intercepts and serves from IndexedDB Browser Services X
  • 53. Service Worker Background worker for a web pages • Also runs when browser is closed! • Available events • Install: Fired whenever the worker gets installed (happens only once) • Activate: Fired whenever a loaded page connects to the worker • Fetch: Fired every time a connected client performs a request • Message: Communication between frontend thread and background worker • Sync: Fired after device comes online • Push: Fired when device receives a push notification • But you need to write code to handle all those events self.addEventListener('install', function(event){ // your code here });
  • 54. Google workbox A set of common patterns for Service Worker • A javascript library on top of indexed DB & cache storage responding to service worker events • Available modules • Precaching: preload files on install • Routing: configure how to handle specific web requests • Strategies: caching strategies • Expiration: remove cached entries • BackgroundSync: resubmit commands after coming online • … importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.6.1/workbox-sw.js'); workbox.core.setCacheNameDetails({ prefix: 'clubmgmt-fundraising-checkin-cache’, suffix: ‘1.0.0.0’ });
  • 55. Building offline apps Google workbox App Shell pattern Command Queue Pattern Install on desktop
  • 56. App Shell pattern ‘Installation’ of all files of the web app • Service worker ‘Install’ event • All essential files for the app will be downloaded and cached • Route with a ‘Cache-first’ policy: Cache Falling Back to Network • Files must be versioned • Revision hashes generated by Dish postprocessing step • Embed hashes, service worker file must change for changes to take effect • Your app shell can run offline now, future pages served from cache workbox.precaching.precacheAndRoute(self.__precacheManifest || []); self.__precacheManifest = [ { url:’/index.html', revision: '16a3cdb338289d….74564ccd3db2430bac’ }, { url:'/css/bootstrap.min.css', revision: '5a3d8c05785485d3….8b5bd7b0f3168fff1bd9a' }, { url:'/css/console.css', revision: '900797671c753ea9b421….f1db2874f32d6264996801' }, …. ]
  • 57.
  • 58.
  • 59. Building offline apps Google workbox App Shell pattern Command Queue Pattern Install on desktop
  • 60. Command Queue pattern ‘Store and forward’ command requests when offline • Store ‘POST’, ‘PUT’ & ‘DELETE’ requests on failure to send const queue = new workbox.backgroundSync.Queue('bg-queue', { onSync: replayRequests, maxRetentionTime: 7 * 24 * 60 // Retry for max a week }); const bgSync = { fetchDidFail: async ({ request }) => { await queue.pushRequest({ request }); } } workbox.routing.registerRoute( /.+/api/.+/, new workbox.strategies.NetworkOnly({ plugins: [bgSync] }), 'POST' );
  • 61.
  • 62. Command Queue pattern ‘Replay’ when back online async function replayRequests(o){ if(unableToSend()) return; while (entry = await o.queue.shiftRequest()) { try { if(unableToSend()){ // prevents infinite loop if connectivity drops while replaying await o.queue.unshiftRequest(entry); return; } var req = entry.request.clone(); // fix headers with latest tokens req.headers.set('Authorization', "Bearer " + self.__authContext.accessToken); req.headers.set('Authority', self.__authContext.authorityToken); await fetch(req); } catch (error) { await o.queue.unshiftRequest(entry); }} }
  • 63. Building offline apps Google workbox App Shell pattern Command Queue Pattern Install on desktop
  • 64. Install on desktop Progressive Web App behaves like a mobile or desktop app • Install experience • Desktop • Mobile • Home screen / desktop icon • Minimal requirements • Manifest.json file • HTTPS • Service Worker
  • 65.
  • 66.
  • 67. Web App Manifest Manifest.json { "short_name": "Clubmanagement Checkin", "name": "Clubmanagement Fundraising Checkin", "description": "An offline tool for handling check-ins at fundraising events", "lang": "nl-BE", "icons": [{ "src": "/img/logo_256.png", "type": "image/png", "sizes": "256x256"}, { "src": "/img/logo_192.png", "type": "image/png", "sizes": "192x192“}, { "src": "/img/logo_512.png", "type": "image/png", "sizes": "512x512"}], "start_url": "/dashboard/", "background_color": "#EEEEEE", "theme_color": "#00A5D5", "display": "standalone", "related_applications": [{ "platform": "web", "url": "https://fundraising-checkin.clubmanagement.io" }] }
  • 68. Ready for revenge of the static website ?
  • 69. Conclusion Static websites provide a great client development platform • It’s cheap! • It’s simple! • Single codebase for any app (PWA) • Web, desktop & mobile apps! • Offline
  • 70. Q&A