Coder Social home page Coder Social logo

googlechromelabs / application-shell Goto Github PK

View Code? Open in Web Editor NEW
1.2K 1.2K 156.0 435 KB

Service Worker Application Shell Architecture

Home Page: https://app-shell.appspot.com/

License: Apache License 2.0

JavaScript 69.19% HTML 7.46% CSS 23.35%

application-shell's People

Contributors

addyosmani avatar albertorestifo avatar andreasonny83 avatar angelogulina avatar dandv avatar jeffposnick avatar michaseel avatar raiseandfall avatar suryagaddipati avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

application-shell's Issues

Move app.js to top level?

Two things:

  1. Get gulp dev to start nodemon app.js
    2.) Move app.js to root (This way any file changes in the directory will restart the server, rather than in just the server).

Because we inline CSS, a css change should restart the server.

Add comments clarifying what files do

There is a lot of stuff going on in this repo. I think it would be really helpful to have at least a few sentences at the start of files such as Dockerfile, app.yaml and gulpfile.js (and probably many other files) to clarify what they do.

I think that would really help people trying to orient their way around this and work out what to modify / rip out for their own variation.

Add support for sw-precache to the build

Unless there's a good reason not to. If there is a good reason not to, I'd like to try to address it in the library.

As it stands, the SW implementation will end up trying to re-fetch all the static resources each time the version is bumped, and there's no cache-busting URL parameter to protect against stale resources being returned from the HTTP cache during the install phase.

Depending on what the HTTP cache expiration is for the static resources, you'll either end up making unnecessary network requests (if your cache expiration is very short) or risk serving stale content from your service worker's fetch handler (if your cache expiration is longer).

sw-precache will version each resource automatically and only re-fetch those that change, appending a cache-busting URL parameter.

gulp fails

steve@steve-FX6800-09h:~/javascript/service_worker/ver1/application-shell$ gulp
/home/steve/javascript/service_worker/ver1/application-shell/gulp-tasks/service-worker.js:57
  .catch(() => {
          ^
SyntaxError: Unexpected token )
    at exports.runInThisContext (vm.js:73:16)
    at Module._compile (module.js:443:25)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at requireDir (/home/steve/javascript/service_worker/ver1/application-shell/node_modules/require-dir/index.js:116:33)
    at Object.<anonymous> (/home/steve/javascript/service_worker/ver1/application-shell/gulpfile.js:40:23)
    at Module._compile (module.js:460:26)
steve@steve-FX6800-09h:~/javascript/service_worker/ver1/application-shell$ gulp dev
/home/steve/javascript/service_worker/ver1/application-shell/gulp-tasks/service-worker.js:57
  .catch(() => {
          ^
SyntaxError: Unexpected token )
    at exports.runInThisContext (vm.js:73:16)
    at Module._compile (module.js:443:25)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at requireDir (/home/steve/javascript/service_worker/ver1/application-shell/node_modules/require-dir/index.js:116:33)
    at Object.<anonymous> (/home/steve/javascript/service_worker/ver1/application-shell/gulpfile.js:40:23)
    at Module._compile (module.js:460:26)

I'm sure I'm making a mistake on my end, but I'm a js neophyte and the build process/ecosystem can be overwhelming. I thought you guys might appreciate being made aware of this error as I followed -- as far as I can tell -- the exact instruction from the Readme. That and node told me to tell you lel

npm ERR! Linux 3.13.0-63-generic
npm ERR! argv "/home/steve/.nvm/versions/node/v0.12.7/bin/node" "/home/steve/.nvm/versions/node/v0.12.7/bin/npm" "install"
npm ERR! node v0.12.7
npm ERR! npm  v2.11.3
npm ERR! code ELIFECYCLE
npm ERR! [email protected] postinstall: `gulp`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] postinstall script 'gulp'.
npm ERR! This is most likely a problem with the app-shell package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     gulp
npm ERR! You can get their info via:
npm ERR!     npm owner ls app-shell
npm ERR! There is likely additional logging output above.

Drawer doesn't display on Safari 8/iOS

This makes testing the other views quite difficult there. Verified it works fine on desktop Safari 9.0. Going to update my iOS devices to iOS9 and check with Safari 9.0 in case the situation is better there.

App-shell architecture in different JS frameworks

  • React - @jeffposnick is taking a look at this. Will either turn his iFixit app in an updated standalone or ship an app like an RSS/News reader or something using the YouTube API. I'm also talking to the React community about examples.
  • Angular 2 - Coordinating with the Angular Mobile team on a new GitHub issues app using their version of the app-shell architecture and Angular Universal. I'll be working with them weekly on getting the patterns here down right from a perf perspective.
  • Ember - I'm going to work on this. Coordinating with Tom Dale and some Ember community folks on current status of FastBoot. I think showing fast SSR for the shell + some notion of hydration + SW caching should be feasible.
  • Polymer - Working with the Polymer team directly on a few different efforts around this for I/O.

TODO List

TODOs

List of things we've discussed that need doing on app-shell

  • Use MDL.
  • Move over voice memos to use this.
  • . . . .

error MSB6006: "CL.exe" exited with code -1073741515.

While installing application-shell, I am getting following error:

C:\Users\cl\Documents\programs\reactjs\application-shell\application-shell\node_modules\sse4_crc32>if not defined npm_config_node_gyp (node "C:\Users\cl\Documents\softwares\node-v8.1.2-win-x64
\node_modules\npm\bin\node-gyp-bin\\..\..\node_modules\node-gyp\bin\node-gyp.js" rebuild )  else (node "" rebuild )
Building the projects in this solution one at a time. To enable parallel build, please add the "/m" switch.
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.CppCommon.targets(356,5): error MSB6006: "CL.exe" exited with code -1073741515. [C:\Users\cl\Documents\programs\reactjs\applic
ation-shell\application-shell\node_modules\sse4_crc32\build\crc32c_sse42.vcxproj]
gyp ERR! build error
gyp ERR! stack Error: `C:\Program Files (x86)\MSBuild\14.0\bin\msbuild.exe` failed with exit code: 1
gyp ERR! stack     at ChildProcess.onExit (C:\Users\cl\Documents\softwares\node-v8.1.2-win-x64\node_modules\npm\node_modules\node-gyp\lib\build.js:285:23)
gyp ERR! stack     at emitTwo (events.js:125:13)
gyp ERR! stack     at ChildProcess.emit (events.js:213:7)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:197:12)
gyp ERR! System Windows_NT 10.0.14393
gyp ERR! command "C:\\Users\\cl\\Documents\\softwares\\node-v8.1.2-win-x64\\node.exe" "C:\\Users\\cl\\Documents\\softwares\\node-v8.1.2-win-x64\\node_modules\\npm\\node_modules\\node-gyp\\bin\
\node-gyp.js" "rebuild"
gyp ERR! cwd C:\Users\cl\Documents\programs\reactjs\application-shell\application-shell\node_modules\sse4_crc32
gyp ERR! node -v v8.1.2
gyp ERR! node-gyp -v v3.6.0
gyp ERR! not ok

Please help !

Incognito tabs not maintaining breakpoints

Quite sorry if this is the wrong place for this, not sure where to report this as a Chrome dev tools bug.

For incognito tabs, breakpoints are not saved when you close and reopen them. Incognito mode is quite helpful for developers as it saves us having to clear cookies after each look at the page, but the fact that it removes break points anytime you close the tab is a major impediment.

This may be by design, in which case I would like to hear the argument for this "feature." Thank you!

Didn't found index.html

Why isn't there any index.html page huh?
I don't have any experience with terminal and doesn't like it.
Can I use this template/Shell without node.js/nom?
Can I host it, without terminal?
I found screenshot of this web app, from a website. And being interested on it. Please help, I really need this shell. And I cannot use terminal.

Switch to SPA/XHR'd in model for non-SW experience

Atm, we revert to full static page reloads for browsers without Service Worker support. We can probably switch to a more SPA-like model without too much difficulty. We're otherwise opting for simplicity with the current approach with a focus on fast initial paint.

syntax error with 'gulp clean' - clone and install

--updated --
workaround
commit/0eb960cff1c7fee021f9c67b9a484248accf51ae works fine . this module's syntax OK

application-shell$ gulp --version
[11:27:13] CLI version 3.9.1
[11:27:13] Local version 3.9.1

rob@ application-shell$ gulp clean
/home/rob/tmp/application-shell/gulp-tasks/service-worker.js:57
.catch(() => {
^
SyntaxError: Unexpected token )
at exports.runInThisContext (vm.js:73:16)
at Module._compile (module.js:443:25)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at requireDir (/home/rob/tmp/application-shell/node_modules/require-dir/index.js:116:33)
at Object. (/home/rob/tmp/application-shell/gulpfile.js:40:23)
at Module._compile (module.js:460:26)

--- i have no idea why it does not like that syntax ..

My app shell disappears and reappears on page reload, why?

I'm using SW precache v2 in my React App and webpack. However, I am not getting the same results. My app works offline but on page reload(offline or online) everything from the DOM disappears and gets fetched again, the results do come from the service worker: (see photo below). In contrast, this app shell demo, react-hn app, and thesession.org app dont even make a request on page reload. What I'm I missing?
app_network_frames-timeline

Multiple server impls may be needed

Mainly PHP. My assumption (and I think it'd be good to have data around this) is that many people are on shared architectures where PHP is the predominant env.

Service Workers behaviour could be confusing

Since we don't declare to the dev that they are running a SW they might think something is broken.

Suggestions:

  1. A traffic light overlay that tells a developer that they're serving from SW or not
  2. Changed content from initial load ("this is done over network; future loads will be from SW" vs "I'm coming from the SW, you will need to Cmd+Shift+R to load over the network")

Find a better way to manage inline vs remote CSS

Possible Options:

1.) Don't - just inline CSS
2.) Enforce some kind of naming convention
- Default file is index_inline.scss and index_remote.scss if they exists
- for a url, use the name after the origin. For example: localhost:9000/home would look for home_inline.scss and home_remote.scss
3.) Make some better helper methods to wrap request and response parameters (these would take in the response, a css name and view. Ensure safe defaults.

@addyosmani - thoughts? Other options?

Removing the cache

Sorry, real newbie question.

I cloned the 1.x version of this project to have a look. All went fine. Of course, the application shell is cached in Chrome. So now any other project using localhost:8080 is diverted to the application shell. Perhaps I'm missing something simple, but I'd like to remove the cached shell, but don't know how and don't see an obvious reference to that action in the READ.ME. Could I trouble you for some help?

Apologies for what I'm guessing is a real naive question ...

SyntaxError: Unexpected token ) running Gulp

Got this running gulp:

macedo@macedo-Z97-D3H:~/w/application-shell$ gulp
/home/macedo/w/application-shell/gulp-tasks/service-worker.js:56
  .catch(() => {
          ^
SyntaxError: Unexpected token )
    at exports.runInThisContext (vm.js:73:16)
    at Module._compile (module.js:443:25)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at requireDir (/home/macedo/w/application-shell/node_modules/require-dir/index.js:116:33)
    at Object.<anonymous> (/home/macedo/w/application-shell/gulpfile.js:23:23)
    at Module._compile (module.js:460:26)


serviceWorker.js:97 Error during service worker registration: DOMException: Failed to register a ServiceWorker for scope ('https://localhost:8000/chat/') with script ('https://localhost:8000/chat/service-worker.js'): An unknown error occurred when fetching the script.

Hello,

We are deploying react application generated using crate-react-app to Apache Tomcat-8.
We have homepage: "/chat" in package.json
we generate a chat.war file and deploy to Tomcat, When we access app, now we are getting an error to register service worker with the below error.

Navigated to https://localhost:8000/chat/
An unknown error occurred when fetching the script.
serviceWorker.js:97 Error during service worker registration: DOMException: Failed to register a ServiceWorker for scope ('https://localhost:8000/chat/') with script ('https://localhost:8000/chat/service-worker.js'): An unknown error occurred when fetching the script.

image

Can someone help me with this why this is failing.

Thanks,

Raghu.

Use a different port for dev/prod environments

As of #63 there's a different service worker generated based on whether you're in the 'dev' or 'prod' environments. When working on similar setups, I've found it useful to use a different port number for your server depending on the environment as well. That way your 'dev' SW registration will remain separate from your 'prod' SW registration, and you won't keep triggering the SW update flow every time you switch from 'dev' to 'prod'.

Server Rendering with asp.net core

Hi, first of all, sorry because this is not an issue but a question.

I have an angular 2 web application with its application shell, push notifications, offline access, etc and everything works like a charm

Now I am trying to render it using angular universal and asp.net core but I don't know how to get the web app working offline.

I build my service worker with sw-precache and I tried with "dynamicUrlToDependencies", which works partially.

Could you please give me any guidance or resources?

Thank you.

Docs: How should you handle `<title>` for SEO?

Answer from Jake:

in the last I've populated <title> using a best guess from the url, then use js to set it properly later

Answer from me:

I think we've previously done not too different (default to site-wide <title>, later switch when can)

We verified this morning that presence of <title> in <head> followed by <title> later in <body> is not a workaround folks can rely on. That only works if there's no <title> defined in <head> previously. I think the idea of a best guess or default set using JS later is prolly a good answer.

Touch navigation does not work

I believe I know the answer why:
This is part the code for nav in the master:

   this.rootElement = document.querySelector('.js-side-nav');
    this.sideNavContent = this.rootElement
      .querySelector('.js-side-nav-content');
    this.sideNavBody = this.rootElement.querySelector('.side-nav__body');
    this.rootElement.addEventListener('click', () => {
      this.close();
    });

    this.sideNavContent.addEventListener('click', (e) => {
      e.stopPropagation();
    });

    this.hasUnprefixedTransform = 'transform' in document.documentElement.style;
    if (this.hasUnprefixedTransform) {
      // Touch slop is a variable that is defined to suggest anything larger
      // than this value was an intended gesture by the user.
      // 8  is a value from Android platform.
      // 3 was added as a factor made up from what felt right.
      var TOUCH_SLOP = 8 * window.devicePixelRatio * 3;

      var touchStartX;
      var sideNavTransform;

      var onSideNavTouchStart = (e) => {
        e.preventDefault();
        touchStartX = e.touches[0].pageX;
      };

      var onSideNavTouchMove = (e) => {
        e.preventDefault();

        var newTouchX = e.touches[0].pageX;
        sideNavTransform = Math.min(0, newTouchX - touchStartX);

        this.sideNavContent.style.transform =
          'translateX(' + sideNavTransform + 'px)';
      };

      var onSideNavTouchEnd = (e) => {
        if (sideNavTransform < -TOUCH_SLOP) {
          this.close();
          return;
        }

        this.open();
      };
      this.sideNavContent.addEventListener('touchstart', onSideNavTouchStart);
      this.sideNavContent.addEventListener('touchmove', onSideNavTouchMove);
      this.sideNavContent.addEventListener('touchend', onSideNavTouchEnd);

However this code from current demo, although obscured slightly, does not look similar but shortened, optimized and fixed the bug in master:

               this.rootElement = document.querySelector(".js-side-nav"),
                this.sideNavContent = this.rootElement.querySelector(".js-side-nav-content");
                var n, r, i = function(e) {
                    n = e.touches[0].pageX
                }, a = function(e) {
                    var o = e.touches[0].pageX;
                    r = Math.min(0, o - n),
                    0 > r && e.preventDefault(),
                    t.sideNavContent.style.transform = "translateX(" + r + "px)"
                }, s = function(e) {
                    -1 > r && t.closeSideNav()
                };
                this.rootElement.addEventListener("click", function() {
                    t.close()
                }),
                this.sideNavContent.addEventListener("click", function(e) {
                    e.stopPropagation()
                }),
                this.sideNavContent.addEventListener("touchstart", i),
                this.sideNavContent.addEventListener("touchmove", a),
                this.sideNavContent.addEventListener("touchend", s)

If I spent the time to decode it and refactor the code and then do a pull request, seems not as efficient as someone who already seems to have a fix to push theirs to master?

For giggles I have the compiled version of the master code that also looks different from what is running on the demo:

              this.rootElement = document.querySelector(".js-side-nav"),
                this.sideNavContent = this.rootElement.querySelector(".js-side-nav-content"),
                this.sideNavBody = this.rootElement.querySelector(".side-nav__body"),
                this.rootElement.addEventListener("click", function() {
                    t.close()
                }),
                this.sideNavContent.addEventListener("click", function(e) {
                    e.stopPropagation()
                }),
                this.hasUnprefixedTransform = "transform"in document.documentElement.style,
                this.hasUnprefixedTransform) {
                    var n, i, r = 8 * window.devicePixelRatio * 3, s = function(e) {
                        e.preventDefault(),
                        n = e.touches[0].pageX
                    }, a = function(e) {
                        e.preventDefault();
                        var o = e.touches[0].pageX;
                        i = Math.min(0, o - n),
                        t.sideNavContent.style.transform = "translateX(" + i + "px)"
                    }, u = function(e) {
                        return i < -r ? void t.close() : void t.open()
                    };
                    this.sideNavContent.addEventListener("touchstart", s),
                    this.sideNavContent.addEventListener("touchmove", a),
                    this.sideNavContent.addEventListener("touchend", u)

Please and thank you for fixing and looking at this :)

Cross-browser testing ๐Ÿ”ง

@gauntface I've seen a little flakiness when testing the latest build locally and was wondering if you could find it in your :heart to do a little cross-browser testing on your end in case it's just me.

  • Verify a fresh clone + install works in Chrome stable + canary (first view, repeat view, navigating to different pages)
  • Verify this works in Firefox stable (without any SW flags on)
  • Test if this works in Firefox nightly with SW on
  • Test in Safari and if possible Edge

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.