Application Shell Architecture
A modern web application architecture leveraging Service Worker to offline cache your application ‘shell’ and populate the content using JS. This means you can get pixels on the screen without the network, even if the content eventually comes from the network - a great performance win. In browsers without SW, we gracefully degrade to server-side rendering (e.g iOS). Demo.
Full details of the architecture can be found in Instant Loading Web Apps With An Application Shell Architecture and Instant Loading with Service Workers.
- Time to first paint is extremely fast
- Content is rendered. App shell can be a placeholder.
- User can scroll, but doesn’t necessarily need to be able to navigate or deeply interact.
- First pageload < 1000ms
- App shell is progressively enhanced in.
- User can now navigate within the app.
- Second pageload
- Shell is loaded from SW cache
- Content loads off the network
Install dependencies using npm:
$ npm install -g gulp nodemon && npm install
Development Build with Watch
$ gulp dev
Once you’ve got a production build or development build of gulp done, start the server with:
$ nodemon app.js
Alternatively, you can just run
npm run monitor. The application shell should now be available on port
We’ve deployed the project to Node.js on Google Cloud. To do the same, follow the steps in their Node.js deployment getting started guide and after running
npm install run
gcloud preview app deploy app.yaml --promote. If everything works correctly, you should have the project deployed to your custom AppSpot endpoint.
Tips for your application shell
A static webapp that always displays the same content may not be what your users expect - it may well be quite dynamic. This means the app may need to fetch data specific to the user’s current needs so this data can come from the network / a server-side API but we logically separate this work for our app from the application shell. When it comes to offline support, structuring your app so that there’s a clear distinction between the page shell and the dynamic or state-specific resources will come in very handy.
There are no hard and fast rules with this architecture, but there are a few gotchas you should be aware of.
Why is there a noscript tag for CSS files?
The reason we have a
Because this project is aimed at progressively enhancing, this is a simple way to work without JS and then progressively enhance, adding in support for a faster load time by asynchronously loading extra styles.
Why care about noscript in an architecture depending on fetch support?
Copyright 2015 Google, Inc.
Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Please note: this is not a Google product