PWA 中启动过慢或白屏问题的解决方式

随着移动互联网的普及,越来越多的网站选择使用 PWA(Progressive Web App)技术来开发移动端网站,以提升用户体验和流量。然而,有时候我们会遇到 PWA 启动过慢或者白屏等问题。本文将介绍 PWA 启动过慢或白屏问题的解决方式,并提供示例代码。

造成问题的原因

1. JS 资源太大

PWA 运行过程中需要加载很多 JS 资源,如果这些资源过大,就会导致启动时加载缓慢,甚至无法加载完。

2. 等待其他 JS 资源加载完成

有些 JS 资源可能是异步加载的,在这些资源加载完成之前页面会一直处于白屏状态。

3. 渲染太慢

PWA 在加载资源和渲染页面时,尤其是有很多复杂的 CSS 和 JS 动画效果时,可能会出现页面渲染过慢的问题。

解决方案

1. 优化 JS 资源大小

通过优化 JS 代码,减少不必要的文件和库,去掉无用函数,实现代码的精简和压缩,可以有效地减小 JS 资源的大小,提高加载速度。

2. 提高 JS 资源加载速度

PWA 可以使用 ServiceWorker 进行本地缓存,提高 JS 资源的加载速度。通过 ServiceWorker 缓存的方式,在下一次访问时,页面可以直接从缓存中获取资源,避免了网络请求的过程,从而提升了资源加载速度。

const cacheName = 'v1';
const cacheAssets = [
  'index.html',
  'main.css',
  'main.js',
  'service-worker.js',
  'manifest.json',
  'images/icons/icon72x72.png',
  'images/icons/icon96x96.png',
  'images/icons/icon144x144.png'
];

// Call Install Event
self.addEventListener('install', e => {
  console.log('Service Worker: Installed');

  e.waitUntil(
    caches.open(cacheName).then(cache => {
      console.log('Service Worker: Caching Files');
      cache.addAll(cacheAssets);
    }).then(() => self.skipWaiting())
  );
});

// Call Activate Event
self.addEventListener('activate', e => {
  console.log('Service Worker: Activated');
  e.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames.map(cache => {
          if (cache !== cacheName) {
            console.log('Service Worker: Clearing Old Cache');
            return caches.delete(cache);
          }
        })
      )
    })
  );
});

// Call Fetch Event
self.addEventListener('fetch', e => {
  console.log('Service Worker: Fetching');
  e.respondWith(
    caches.match(e.request).then(response => {
      return response || fetch(e.request);
    })
  );
});

3. 减少白屏等待时间

在 PWA 开始加载页面之前,可以显示一个加载动画,提高用户体验和减少用户等待时间。可以在 index.html 文件中添加以下 HTML 代码实现:

<div id="loading-spinner">
  <div class="spinner"></div>
</div>

通过 CSS 样式调整加载动画样式:

#loading-spinner {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background: #f5f5f5;
  z-index: 9999;
}

.spinner {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 3px solid #ccc;
  border-top-color: #333;
  animation: spinner 1s ease infinite;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

@keyframes spinner {
  to { transform: rotate(360deg); }
}

当页面加载完成时,移除加载动画:

window.addEventListener('load', () => {
  const loader = document.getElementById('loading-spinner');
  loader.classList.add('fade-out');

  setTimeout(() => {
    loader.parentNode.removeChild(loader);
  }, 500);
});

4. 延迟加载 JS 资源

可以将页面的关键 JS 资源进行延迟加载,等到页面首屏渲染完成以后再进行加载。可以通过以下代码实现:

<head>
  <title>My PWA</title>
  <link rel="stylesheet" href="main.css">
  <script async defer src="my-script.js"></script>
</head>

其中 async 属性表示该 JS 资源可以异步加载,并且不影响页面的渲染。而 defer 属性表示该 JS 资源会延迟到页面渲染完成后加载,不会影响首屏渲染的速度。

总结

PWA 的启动过慢或者白屏等问题是可以通过一定的优化和改善来解决的。在实现 PWA 的过程中,我们需要根据自己的实际情况和需求,选择合适的解决方案。通过本文的介绍和示例代码,相信读者已经对 PWA 启动过慢或者白屏等问题的解决方式有一定的了解和认识了。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65ae22deadd4f0e0ff7b05ef