進歩的なWebアプリの理解:モバイル・エクスペリエンスを提供する



何がPWAですか?

A PWA (Progressive Web Application) is a type of app software delivered through the web. PWAs are built using common technologies such as HTML, CSS and JavaScript. They can be installed and function on any platform which uses a W3C compliant web browser on either desktop or mobile devices.
It is important to note that the browser will allow your web application to become a PWA only over a secure connection (using SSL encryption technology) or on localhost.



誰がpisをインストールできますか?
Pwasのサポートは、主にモバイルブラウザに焦点を当てているが、いくつかのデスクトップブラウザーのための限られたサポートもあります.

Support as of August 2021:

Mobile:

Nearly every mobile browser supports PWAs, with the exception of KaiOS

Desktop:

Chrome 39 & UP
Edge 79 & UP
IOS Safari/Chrome 11.3 & UP - Partial Support
Firefox - Deprecated as of January 2021



スクリーンショットcaniuse.com

なぜ、私はpisを開発しなければなりませんか?

Purpose:

PWAs allow us to offer web applications that can be installed onto any device and act indistinguishably from a native app.
By meeting certain criteria, your website or web application can easily be turned into a PWA as well.

Required Technologies:

  • HTML
  • CSS
  • JavaScript
  • NodeJS (optional package that we will be using here)

Benefits:

  • Application Store Registration
  • Offline Fallbacks
  • Network or Cache First Resource Fetching
  • Push Notifications
  • Background Sync
  • And More


それは多くの開始を取得しません!

ファイル構造
    -root/
      -index.html
      -manifest.json
      -service-worker.js
      -logo.[png, jpg, etc...]

インデックス.HTML
開発は、基本的なHTML 5のボイラーで始まることができます.

HTML 5ボイラープレート
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>TechSnack Simple PWA</title>
      </head>
      <body>
        <h1>Hello World!</h1>
      </body>
    <html>

マニフェスト.JSON
ユーザーのデバイスは、我々のWebアプリケーションで何をすべきかを知るためには、いくつかの詳細を提供する必要があります.これらの詳細はかなり自明です.

We will leave the icons array empty for now. More on this shortly.


    {
      "name": "TechSnack Simple PWA",
      "short_name": "TechSnack",
      "start_url": "/?home=true",
      "icons": [],
      "theme_color": "#000000",
      "background_color": "#FFFFFF",
      "display": "fullscreen",
      "orientation": "portrait"
    }

With this information the user's device can:

  • Install our application
  • Apply a custom icon for launching the app
  • Display a custom splash screen on launch
  • Allow customization of the application window and behaviour
  • Mimic native application behaviour
  • Allow access to native features such as GPS and push notifications
  • Register our application with popular app stores


リンクマニフェスト.JSON
使用するlink 接続するタグmanifest.json 我々のアプリに
    <head>

      ...

      <link rel="manifest" href="manifest.json">
    </head>

ノードパッケージ( 1 -オプション)
  • pwa-asset-generator
  • As previously mentioned, the user's device will apply the custom icon for us. For it to do that we will need to supply at least one image for the device to reference.



    どのような複数の画面のサイズや解像度は?
    今日は世界中で使用される無数の異なるモバイルデバイスがあります.視覚的な資産の表示を最適化するために、各々の装置は、ある次元のロゴを好む.

    PHAアセットジェネレーター
    以下のMIMEタイプの少なくとも一つのイメージファイルが必要になります.
  • PNG
  • JPEG・JPG
  • SVG
  • Webp
  • Install

       $ npm install --global pwa-asset-generator
    

    パッケージを実行したいのですがwebroot ディレクトリ.
    以下のスニペットは私たちの目的のために行います.

    npx pwa-asset-generator [path/to/logo] [path/to/output/dir] -i [path/to/index.html] -m [path/to/manifest.json] -f
    The -f flag generates favicon image/meta tag

    Execution - From webroot directory

       $ npx pwa-asset-generator logo.jpg logos -i index.html -m manifest.json -f
    


    It is worth noting that if you execute pwa-asset-generator without using the -i, -m and -f flags the results will be output to your console instead.

    Copy and paste the results into the icons array within manifest.json



    Copy and paste the output into the head tag of index.html




    新しいicons/ ディレクトリ

    Contains all of the generated images.




    更新index.html我々index.html ファイルは次のようになります.
        <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta name="theme-color" content="#000000">
        <link rel="apple-touch-icon" href="icons/apple-icon-180.png">
    
        <meta name="apple-mobile-web-app-capable" content="yes">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-2048-2732.jpg" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-2732-2048.jpg" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-1668-2388.jpg" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-2388-1668.jpg" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-1536-2048.jpg" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-2048-1536.jpg" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-1668-2224.jpg" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-2224-1668.jpg" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-1620-2160.jpg" media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-2160-1620.jpg" media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-1284-2778.jpg" media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-2778-1284.jpg" media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-1170-2532.jpg" media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-2532-1170.jpg" media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-1125-2436.jpg" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-2436-1125.jpg" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-1242-2688.jpg" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-2688-1242.jpg" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-828-1792.jpg" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-1792-828.jpg" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-1242-2208.jpg" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-2208-1242.jpg" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-750-1334.jpg" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-1334-750.jpg" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-640-1136.jpg" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
        <link rel="apple-touch-startup-image" href="icons/apple-splash-1136-640.jpg" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
    
        <title>TechSnack | Simple PWA</title>
        <link id="favicon" rel="sortcut icon" href="favicon.ico" type="image/x-icon">
        <link rel="manifest" href="manifest.json">
      </head>
      <body>
        <h1>Hello World!</h1>
      </body>
    </html>
    

    ファイナルmanifest.json我々manifest.json ファイルは次のようになります.
        {
          "name": "TechSnack Simple PWA",
          "short_name": "TechSnack",
          "start_url": "/?home=true",
          "icons": [
            {
              "src": "icons/manifest-icon-192.png",
              "sizes": "192x192",
              "type": "image/png",
              "purpose": "maskable any"
            },
            {
              "src": "icons/manifest-icon-512.png",
              "sizes": "512x512",
              "type": "image/png",
              "purpose": "maskable any"
            }
          ],
          "theme_color": "#000000",
          "background_color": "#FFFFFF",
          "display": "fullscreen",
          "orientation": "portrait"
        }
    

    サービスワーカー
    我々のPWAが前に言及したすべての空想をすることができる前に、我々はサービスワーカーを最初につくらなければなりません.

    A service worker is a listener script the browser runs in the background. The service worker runs separately from the webpage allowing for the implementation of features that do not require interaction or calls from the webpage or user.
    Service Workers may support features such as periodic sync or geofencing in the future.
    NOTE: Although service workers are a JavaScript file, there are additional limitations imposed when coding. You may not have access to the DOM through a service worker.



    サービス労働者のライフサイクル

    There are multiple functions/features that you would normally have to build out around A Service Workers Lifecycle.
    We will be using an API called workbox to avoid worrying about configuring what is under the hood.


    workbox API
    我々のサービスワーカーのために、我々は呼ばれるAPIの使用を使用するつもりですworkbox . このAPIは、独自に記述するために複数の記事を必要とする機能で焼かれています.
    場合は、nitty grittyに掘ることに興味がある場合は約約読むことができますA Service Workers Lifecycle .

    ImportScript

    Inside of service-worker.js we will import the workbox API

       importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.0.2/workbox-sw.js');
    


    路線登録
    サービスワーカーは、ページからネットワーク要求を傍受できます.ページに対応する可能性がありますcached content or generated content
    スクリーンショットGoogle Dev

    Note: (From Above)

    The method is GET by default.
    To change this it must be specified.

    The order of route registration is important when multiple workers are available to handle a request.
    Whichever worker has been created first will take priority in handling a given request.


    service-worker.js次のコードを追加できますservice-worker.js :
    
        ...
    
        workbox.routing.registerRoute(
          ({request}) => request.destination === 'image',
          new workbox.strategies.CacheFirst() //to search cache first
          //new workbox.strategies.NetworkFirst() //to search server first
    );
    

    That's it! The above code will:

    • RegisterRoute with workbox
    • Intercept all 'image' files at the page's request

    ここで我々はstrategies . 我々のページにサービスを提供したいですかCacheFirst or NetworkFirst ? これは、我々が興味を持っている特定のリソースかどうかによって決定しますstatic or dynamic .
  • 一般的であればstatic ページに我々のユーザーの土地に我々はそれらからサービスを提供したいと思いますcache .
  • しかし、もしあればdynamically generated 何らかの種類でback-end それから、私たちはそのファイルをnetwork .

  • ファイナルservice-worker.js
    
        importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.0.2/workbox-sw.js');
    
        workbox.routing.registerRoute(
          ({request}) => request.destination === 'image',
          new workbox.strategies.CacheFirst() //to search cache first
          //new workbox.strategies.NetworkFirst() //to search server first
    );
    

    リンクservice-worker.js現在、我々はサービスワーカーを置いて、イメージファイルの要求を妨害していますindex.html
        <body>
    
          ...
    
          <script>
            if('serviceWorker' in navigator){
            navigator.serviceWorker.register('/service-worker.js');
          }
          </script>
        </body>
    
    そのシンプルなサービスワーカーを登録する!

    すべてをまとめる
    我々は最終的に我々のPWAプロジェクトの最終的なコードベースを見ることができます.

    ファイル構造:

    index.html
        <!DOCTYPE html>
        <html lang="en">
          <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <meta name="theme-color" content="#000000">
            <link rel="apple-touch-icon" href="icons/apple-icon-180.png">
    
            <meta name="apple-mobile-web-app-capable" content="yes">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-2048-2732.jpg" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-2732-2048.jpg" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-1668-2388.jpg" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-2388-1668.jpg" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-1536-2048.jpg" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-2048-1536.jpg" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-1668-2224.jpg" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-2224-1668.jpg" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-1620-2160.jpg" media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-2160-1620.jpg" media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-1284-2778.jpg" media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-2778-1284.jpg" media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-1170-2532.jpg" media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-2532-1170.jpg" media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-1125-2436.jpg" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-2436-1125.jpg" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-1242-2688.jpg" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-2688-1242.jpg" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-828-1792.jpg" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-1792-828.jpg" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-1242-2208.jpg" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-2208-1242.jpg" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-750-1334.jpg" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-1334-750.jpg" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-640-1136.jpg" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
            <link rel="apple-touch-startup-image" href="icons/apple-splash-1136-640.jpg" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)">
    
            <title>TechSnack | Simple PWA</title>
            <link id="favicon" rel="sortcut icon" href="favicon.ico" type="image/x-icon">
            <link rel="manifest" href="manifest.json">
          </head>
          <body>
            <h1>Hello World!</h1>
    
            <script>
              if('serviceWorker' in navigator){
                navigator.serviceWorker.register('/service-worker.js');
              }
            </script>
          </body>
        </html>
    
    manifest.json
        {
          "name": "TechSnack Simple PWA",
          "short_name": "TechSnack",
          "start_url": "/?home=true",
          "icons": [
            {
              "src": "icons/manifest-icon-192.png",
              "sizes": "192x192",
              "type": "image/png",
              "purpose": "maskable any"
            },
            {
              "src": "icons/manifest-icon-512.png",
              "sizes": "512x512",
              "type": "image/png",
              "purpose": "maskable any"
            }
          ],
          "theme_color": "#000000",
          "background_color": "#FFFFFF",
          "display": "fullscreen",
          "orientation": "portrait"
        }
    
    service-worker.js
        importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.0.2/workbox-sw.js');
    
        workbox.routing.registerRoute(
          ({request}) => request.destination === 'image',
          new workbox.strategies.CacheFirst() //to search cache first
        );
    

    当社のページ
    ブラウザでページを見ることができます.

    For localhost run npx serve in the webroot directory.
    Then you can visit your securely served remote ip or domain
    Please keep in mind the browser support for your device



    There is a new icon in our address bar!

    The browser requires a user action to install the PWA
    The User can click this icon to see the prompt

    Now you can click on the icon installed on the device's homepage



    PWA開発の要約
    あなたはそれがネイティブアプリと同じ機能を模倣することができますWebアプリケーションを作成するのは簡単です超簡単に見ることができます.将来の記事では、我々は現在、我々は現在、この強力な技術にアクセスできるようになる各機能をご利用いただけます.

    ヘルプテクニーク簡潔なコンテンツを書く:
    私たちに以下の記事についてのあなたの考えでコメントを残してください.かどうかを気に入ったか、記事を嫌い、すべてのフィードバックをどのようにより良いあなたのニーズ、目標や願望を満たしてコンテンツを作成する方法を知るのに役立ちます.
    あなたの社会的なプラットホームに関する記事を共有することは、大きな助けでもあります!
    会話に参加するr/TechSnack