一、渐进式 Web 应用(PWA)的定义
渐进式 Web 应用(Progressive Web App,PWA)是一种结合传统 Web 技术与现代移动应用特性的技术方案,旨在通过 HTML、CSS 和 JavaScript 构建具备原生应用体验的 Web 应用。其核心特性包括:
- 可安装性:用户可将 PWA 添加到设备主屏幕,像原生应用一样独立运行;
- 渐进增强:根据设备和网络环境逐步提升功能,确保基础功能在所有浏览器中可用;
- 技术融合:依赖 Service Workers、Web App Manifest 等现代 Web API 实现离线访问、推送通知等高级功能。
二、PWA 的核心优势与好处
1. 可靠性
- 离线可用:通过 Service Workers 缓存关键资源,即使无网络连接也能加载内容。
- 快速响应:首次加载后,后续访问速度接近即时,减少用户等待时间。
2. 性能优化
- 资源预缓存:Service Workers 提前加载核心资源,降低网络依赖;
- 智能更新:仅更新变动内容,避免重复下载完整应用。
3. 跨平台兼容性
- 全设备适配:支持桌面、手机、平板等设备,一次开发多端覆盖;
- 响应式设计:自动适配不同屏幕尺寸,提供一致的视觉体验。
4. 用户粘性与推广优势
- 推送通知:通过浏览器向用户发送实时提醒,提升用户活跃度;
- 免安装推广:用户可直接通过 URL 访问,无需应用商店审核;
- SEO 友好:内容可被搜索引擎索引,提高自然流量转化率。
三、为何选择 PWA?
1. 用户体验升级
- 消除原生应用下载门槛,用户点击链接即可使用完整功能;
- 提供类原生应用的交互体验(如全屏模式、主屏图标)。
2. 开发与维护成本降低
- 统一代码库:无需为不同平台单独开发,节省人力与时间;
- 简化更新流程:服务端更新自动同步到客户端,无需用户手动操作7。
3. 适应多样化场景
- 弱网/离线场景:如教育、电商等领域的离线内容访问;
- 轻量化需求:替代低频使用的原生应用,减少设备存储压力。
四、开发
1. 安装PWA
npm i vite-plugin-pwa -D2. vite 配置
import { VitePWA } from 'vite-plugin-pwa'
// https://vite.dev/config/
export default defineConfig({
  plugins: [
    react(),
    VitePWA({
      registerType: 'autoUpdate',
      workbox: {
        globPatterns: ['**/*.{js,css,html}'],
      },
      manifest: {
        name: '源码分享',
        short_name: '源码分享',
        description: '源码分享',
        theme_color: '#000000',
        background_color: '#000000',
        icons: [
          {
            src: 'public/logo.svg',
            sizes: '192x192',
            type: 'image/svg+xml',
          },
          {
            src: 'public/logo.svg',
            sizes: '512x512',
            type: 'image/svg+xml',
          },
        ],
      },
      devOptions: {
        enabled: true,
        type: 'module',
      },
    }),
  ],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
    },
  },
})
配置注意:
- icons 图标的实际大小必须大于 sizes 的设置值。192×192:适配移动端设备主屏幕图标;512×512:用于桌面端安装弹窗及 Splash 屏幕
- icons 推荐使用svg图标
- devOptions 配置本地开发环境。没有设置浏览器不会出现安装应用的入口。
到此依赖、配置都已经全部完成,是不是非常简单。
3. 使用
首页来分析一下具体需要实现的需求,希望做些什么功能。其实上面配置好,个人觉得90%目的已经达到。能够安装应用,生成一个渐进式 Web 应用(PWA),并缓存关键资源。
下面我们来分析一些高级的运用、体验的优化。
如何引导用户安装PWA应用?
- 捕获安装事件
let deferredPrompt = null;
const handleBeforeInstallPrompt = (e) => {
  e.preventDefault();
  deferredPrompt.current = e;
  setIsInstallable(true);
};
window.addEventListener("beforeinstallprompt", handleBeforeInstallPrompt);- 检测已安装状态
const checkDisplayMode = () => {
  const isStandalone = window.matchMedia(
    "(display-mode: standalone)"
  ).matches;
  const isIOS =
    /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
  setIsInstalled(isStandalone || (isIOS && navigator.standalone));
};注意:iOS 不支持 beforeinstallprompt 事件,需通过 navigator.standalone 检测
- 页面引导提交用户安装
最后就是如何更好的引导用户安装,这里不多说了,自由发挥自己的引导方式,做更好的ui效果。
完整源码
import { useEffect, useState, useRef } from 'react';
function App() {
  const [isInstallable, setIsInstallable] = useState(false);
  const [isInstalled, setIsInstalled] = useState(false);
  const deferredPrompt = useRef(null);
  useEffect(() => {
    const handleBeforeInstallPrompt = (e) => {
      e.preventDefault();
      deferredPrompt.current = e;
      setIsInstallable(true);
    };
    window.addEventListener("beforeinstallprompt", handleBeforeInstallPrompt);
    // 当前是否已是pwa离线应用
    const checkDisplayMode = () => {
      const isStandalone = window.matchMedia(
        "(display-mode: standalone)"
      ).matches;
      const isIOS =
        /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
      setIsInstalled(isStandalone || (isIOS && navigator.standalone));
    };
    checkDisplayMode();
    return () => {
      window.removeEventListener(
        "beforeinstallprompt",
        handleBeforeInstallPrompt
      );
    };
  }, []);
  const handleInstall = async () => {
    if (deferredPrompt.current) {
      deferredPrompt.current.prompt();
      const { outcome } = await deferredPrompt.current.userChoice;
      if (outcome === 'accepted') {
        // 同意
        setIsInstallable(false);
        deferredPrompt.current = null;
      } else {
        // 拒绝
        console.log("拒绝");
      }
    }
  };
  return (
    <>
      <div className="container mt-5">
        <button
          className="px-4 py-2 bg-blue-500 text-white rounded-lg 
              transition-colors duration-200 
              hover:bg-blue-600 hover:shadow-md 
              focus:outline-none focus:ring-2 focus:ring-blue-500 
              disabled:bg-blue-300 disabled:text-gray-100 disabled:cursor-not-allowed"
          onClick={handleInstall}
          disabled={!isInstallable}
        >
          {isInstalled ? "已安装" : isInstallable ? "安装" : "已安装"}
        </button>
      </div>
    </>
  );
}
export default App;
最后PWA上线的必须条件:
- 生产环境需部署 SSL 证书
- 响应式设计(确保页面适配不同设备尺寸)
预览

 原文链接:https://code.ifrontend.net/archives/290,转载请注明出处。		    			
		             
	
评论0