JS 앱이 온라인/오프라인인지 또는 느린 연결인지 감지하는 간단한 방법(+ 경고, + 느린 인터넷 에뮬레이션)

이 기사에서는 다음 3가지를 다룰 것입니다.
  • JS 응용 프로그램(SPA, PWA, Electron 또는 일반 JS일 수 있음)이 다시 온라인 상태가 될 때 연결 문제(느림, 오프라인)를 감지하는 방법 및 페이지 없이 데이터를 다시 다운로드하는 방법 새로 고침(온라인 상태에서 완료할 시간이 충분하지 않은 경우).
  • 그림을 다운로드하고 표시하는 간단한 JS 응용 프로그램을 만듭니다. 여기에서 이전 단계의 모든 경우를 다룹니다.
  • Chrome에서 인터넷 연결을 제한하는 방법을 배우고 우리가 만든 응용 프로그램을 테스트합니다.



  • 1 단계.



    애플리케이션이 오프라인 상태인지 또는 다시 온라인 상태인지 감지하는 것은 매우 간단합니다.

    window.addEventListener("offline", () => {
      console.log("I am offline.");
    });
    
    window.addEventListener("online", () => {
      console.log("I am back online.");
    });
    

    예를 들어 Google 드라이브에 파일을 업로드하기 위해 인터넷 연결이 필요한 Chrome 확장 프로그램을 빌드하는 경우 다음을 활용할 수 있습니다.

    if (!navigator.onLine) {
      return false;
    }
    
    // Upload the file...
    

    응용 프로그램이 너무 오래 로드되는지 감지하려면 타이머를 만들고 시간을 지정하여 수행할 수 있습니다. 그 후에는 아직 로드되지 않은 경우 연결이 느리다고 가정합니다. 애플리케이션이 로드된 후 타이머를 재설정합니다. 다음은 예제 코드입니다.

    // Our simple App
    const App = async (onstart, onload) => {
      onstart();
    
      // Loading...
    
      // The application is now loaded
      onload();
    }
    
    let isSlow;
    let loaded;
    
    App(
      () => {
        isSlow = setTimeout(() => {
          console.log("Thing are getting slow...");
        }, 10000); // 10 seconds
      },
      () => {
        clearTimeout(isSlow);
        loaded = true;
        console.log("Loaded.");
    });
    

    애플리케이션이 너무 오래 로드되는지 여부를 결정하는 논리는 앱에 따라 다릅니다.

    이제 다음 단계로 진행할 수 있습니다.

    2 단계.



    이제 https://picsum.photos에서 임의의 사진을 로드하는 간단한 앱을 만들 것입니다. 인터넷 연결이 느려지거나 오프라인이 되거나 다시 온라인이 되면 다음과 같은 특정 메시지가 표시됩니다.







    앱은 다음과 같이 표시됩니다.



    메시지는 필요할 때 상단 중앙에 표시됩니다. 이미지 로딩을 시각적으로 더 좋게 만들기 위해 펄스 효과가 있습니다.
    index.html를 생성하여 시작하겠습니다.

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>App</title>
      <link rel="stylesheet" href="app.css">
    </head>
    <body>
      <div id="slow" class="message">Slow Internet Connection.</div>
      <div id="offline" class="message">No Internet Connection.</div>
      <div id="online" class="message">Back Online.</div>
    
      <div id="app"></div>
    
      <script src="app.js"></script>
    </body>
    </html>
    

    계속 생성하여 app.css:

    body {
      margin: 0;
      padding: 4em;
      font-family: Arial, Helvetica, sans-serif;
    }
    
    @keyframes pulse {
      0% { background-color: #f1f1f1; }
      100% { background-color: silver; }
    }
    
    img {
      width: 640px;
      height: 480px;
    }
    
    img.loading {
      animation: pulse 1s ease-out alternate infinite;
    }
    
    .message {
      position: fixed;
      left: 50%;
      top: 0;
      font-size: 2em;
      font-weight: bold;
      padding: 1.5em;
      transform: translate(-50%, -100%);
      transition: transform .25s;
    }
    
    #slow {
      background: #FF9800;
      color: white;
    }
    
    #offline {
      background: #E91E63;
      color: white;
    }
    
    #online {
      background: #4CAF50;
      color: white;
    }
    
    body.slow #slow,
    body.offline #offline,
    body.online #online {
      transform: translate(-50%, 0);
    }
    

    메시지(또는 경고)는 각각 다른 색상을 가지며 필요하지 않을 때는 화면에서 사라집니다. 필요한 경우 메시지가 상단 중앙에서 슬라이드됩니다.

    마지막으로 app.js를 만듭니다.

    // Simple App that loads a picture.
    const App = (onstart, onload) => {
      onstart();
    
      const h1 = document.createElement("h1");
      h1.innerText = "App";
    
      const img = document.createElement("img");
      img.src = "https://picsum.photos/640/480";
      img.className = "loading";
      img.onload = () => {
        img.className = "";
        onload();
      };
    
      const app = document.getElementById("app");
      app.innerHTML = "";
      app.append(h1);
      app.append(img);
    }
    
    let isSlow;
    let loaded;
    
    const loadApp = () => {
      App(
        () => {
          loaded = false;
          isSlow = setTimeout(() => {
            // Show "Slow Internet Connection." message.
            document.body.className = "slow";
            console.debug("slow");
          }, 1500); // Intentionally a low number for testing. Try some different values here, or play with different Internet Throttling setting.
        },
        () => {
          loaded = true;
          clearTimeout(isSlow);
          setTimeout(() => { document.body.className = ""; }, 1000); // Hide message after 1s.
          console.debug("loaded");
      });
    };
    
    
    // We are "offline".
    window.addEventListener("offline", () => {
      // Show "No Internet Connection." message.
      document.body.className = "offline";
    });
    
    
    // When we back "online".
    window.addEventListener("online", () => {
      // Show "Back online" message.
      document.body.className = "online";
      console.debug("online");
    
      // Hide message after 1s.
      setTimeout(() => { document.body.className = ""; }, 1000);
    
      // There was not enough time to load the App. Do it again.
      if (!loaded) {
        console.debug("Reconnecting...");
        loadApp();
      }
    });
    
    
    window.addEventListener("DOMContentLoaded", loadApp);
    

    이 간단한 앱은 사진을 로드하고 표시합니다. 그림이 로드되는 동안 펄스 효과를 표시하기 위해 .loading 클래스가 추가됩니다. 이미지가 로드된 후 .loading 클래스가 제거되고 타이머가 중지됩니다. 로딩이 지정된 것보다 오래 걸리면 Slow Internet Connection. 메시지가 표시됩니다.

    인터넷이 꺼져 있으면 No Internet Connection. 메시지가 표시되고 다시 온라인 상태가 되면 Back Online. 메시지가 표시됩니다.

    오프라인 상태가 되기 전에 사진이 로드되지 않은 경우 다시 온라인 상태가 되면 사진이 로드됩니다.

    3단계.



    다양한 네트워크 조건에서 앱을 테스트할 시간입니다. Chrome -> DevTools -> Network를 열고 Throttling 섹션을 찾은 다음 Add...를 클릭합니다.





    아래와 같이 2개의 새 제한 프로필을 정의합니다.



    우리가 표시하려는 임의의 사진은 크기가 20KB에서 80KB까지 다양할 수 있습니다. 즉, 매우 느린 프로필에서는 로드하는 데 약 5초가 걸리고 엄청나게 느린 프로필에서는 약 30초가 걸립니다. 우리는 기본적으로 좋은 테스트를 위해 콘텐츠의 크기에 따라 속도를 조정합니다.

    이제 DevTools가 열린 상태에서index.html를 열고(조절이 적용되도록) 다른 초기 조절 설정(온라인, 오프라인, 매우 느림 또는 엄청나게 느림)으로 페이지를 계속 새로 고치고 페이지가 로드되는 동안 프로필을 변경해 보십시오(에서 오프라인에서 온라인으로, 매우 느린 속도에서 오프라인에서 온라인으로 등).

    다음과 같이 보일 수 있습니다.



    그게 다야. 나는 당신이 기사를 즐기고 재미 있었기를 바랍니다!

    그리고. 읽어 주셔서 감사합니다! 🙂

    좋은 웹페이지 즐겨찾기