uni-app Web 端优化

核心知识点

1. Web 端性能特点

uni-app Web 端与小程序和 App 相比,具有不同的性能特点:

  • 运行环境:基于浏览器运行,受浏览器性能和兼容性影响
  • 渲染方式:使用 Web 标准的 HTML、CSS、JavaScript 渲染
  • 资源加载:依赖网络加载资源,受网络环境影响较大
  • 响应式设计:需要适配不同屏幕尺寸的设备
  • 浏览器兼容性:需要考虑不同浏览器的兼容性问题

2. Web 端优化策略

有效的 Web 端优化策略包括:

  • 加载优化:减少页面加载时间,提升首屏加载速度
  • 渲染优化:提高页面渲染性能,减少卡顿
  • 资源优化:优化图片、CSS、JavaScript 等资源
  • 网络优化:优化网络请求,减少数据传输时间
  • 响应式优化:优化响应式设计,提升不同设备的用户体验
  • 浏览器兼容性:解决不同浏览器的兼容性问题

3. Web 端性能监控工具

常用的 Web 端性能监控工具:

  • Chrome DevTools:Performance、Network、Memory 等面板
  • Firefox Developer Tools:性能分析工具
  • Safari Developer Tools:性能分析工具
  • 第三方监控平台:如 Google Analytics、百度统计等

实用案例分析

案例:Web 端优化实战

1. 加载优化

优化策略

  • 减少 HTTP 请求:合并文件,使用 CSS Sprites,内联关键 CSS
  • 使用 CDN:使用内容分发网络,加速静态资源加载
  • 启用压缩:启用 Gzip、Brotli 等压缩方式
  • 使用浏览器缓存:合理设置缓存策略
  • 延迟加载:延迟加载非关键资源
  • 预加载:预加载可能需要的资源

实现代码

index.html 中的加载优化

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>uni-app Web 端</title>
  <!-- 1. 内联关键 CSS -->
  <style>
    /* 关键 CSS,如首屏样式 */
    .app-loading {
      display: flex;
      align-items: center;
      justify-content: center;
      height: 100vh;
      background-color: #f5f5f5;
    }
    .app-loading__text {
      font-size: 16px;
      color: #999;
    }
  </style>
  <!-- 2. 预加载字体 -->
  <link rel="preload" href="/static/fonts/iconfont.woff2" as="font" type="font/woff2" crossorigin>
  <!-- 3. 预连接 -->
  <link rel="preconnect" href="https://api.example.com">
  <link rel="preconnect" href="https://cdn.example.com">
</head>
<body>
  <div id="app">
    <div class="app-loading">
      <div class="app-loading__text">加载中...</div>
    </div>
  </div>
  <!-- 4. 延迟加载非关键脚本 -->
  <script defer src="/static/js/vendor.js"></script>
  <script defer src="/static/js/app.js"></script>
</body>
</html>

2. 渲染优化

优化策略

  • 减少 DOM 节点:减少页面 DOM 节点数量,避免深层嵌套
  • 避免重排重绘:减少 DOM 操作,使用 CSS transforms 和 opacity 进行动画
  • 使用 CSS 动画:优先使用 CSS 动画,避免 JavaScript 动画
  • 使用 requestAnimationFrame:使用 requestAnimationFrame 进行动画
  • 避免使用 table 布局:避免使用 table 布局,使用 CSS Grid 或 Flexbox

实现代码

CSS 动画优化

/* 优化前:使用 JavaScript 动画 */
.animate {
  /* JavaScript 控制 */
}

/* 优化后:使用 CSS 动画 */
.animate {
  animation: slideIn 0.3s ease-out forwards;
}

@keyframes slideIn {
  from {
    transform: translateX(-100%);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

/* 使用 will-change 提示浏览器 */
.animate {
  will-change: transform, opacity;
}

使用 requestAnimationFrame

// 优化前:使用 setTimeout 进行动画
function animate(element, start, end, duration) {
  let startTime = null;
  function step(timestamp) {
    if (!startTime) startTime = timestamp;
    const progress = Math.min((timestamp - startTime) / duration, 1);
    const value = start + (end - start) * progress;
    element.style.left = value + 'px';
    if (progress < 1) {
      setTimeout(step, 16); // 约 60fps
    }
  }
  setTimeout(step, 16);
}

// 优化后:使用 requestAnimationFrame 进行动画
function animate(element, start, end, duration) {
  let startTime = null;
  function step(timestamp) {
    if (!startTime) startTime = timestamp;
    const progress = Math.min((timestamp - startTime) / duration, 1);
    const value = start + (end - start) * progress;
    element.style.left = value + 'px';
    if (progress < 1) {
      requestAnimationFrame(step);
    }
  }
  requestAnimationFrame(step);
}

3. 资源优化

优化策略

  • 图片优化:使用适当尺寸的图片,支持 WebP 格式,使用图片懒加载
  • CSS 优化:减少 CSS 文件大小,使用 CSS 预处理器,避免 CSS 冗余
  • JavaScript 优化:减少 JavaScript 文件大小,使用模块化,避免 JavaScript 冗余
  • 字体优化:使用字体子集,减少字体文件大小,使用字体图标
  • 资源压缩:压缩 CSS、JavaScript、HTML 文件

实现代码

图片懒加载

// 图片懒加载实现
function lazyLoadImages() {
  const images = document.querySelectorAll('img[data-src]');
  
  const imageObserver = new IntersectionObserver((entries, observer) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        const image = entry.target;
        image.src = image.dataset.src;
        image.removeAttribute('data-src');
        imageObserver.unobserve(image);
      }
    });
  });
  
  images.forEach(image => {
    imageObserver.observe(image);
  });
}

// 页面加载完成后执行
window.addEventListener('load', lazyLoadImages);

CSS 优化

/* 优化前:冗余的 CSS */
.header {
  width: 100%;
  height: 60px;
  background-color: #fff;
  border-bottom: 1px solid #eee;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
}

.header .logo {
  font-size: 20px;
  font-weight: bold;
  color: #007AFF;
}

.header .nav {
  display: flex;
  gap: 20px;
}

/* 优化后:使用 CSS 变量和简写 */
:root {
  --primary-color: #007AFF;
  --border-color: #eee;
  --padding: 0 20px;
}

.header {
  width: 100%;
  height: 60px;
  background: #fff;
  border-bottom: 1px solid var(--border-color);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--padding);
}

.header .logo {
  font: bold 20px/1 sans-serif;
  color: var(--primary-color);
}

.header .nav {
  display: flex;
  gap: 20px;
}

4. 网络优化

优化策略

  • HTTP/2:使用 HTTP/2,提高传输效率
  • HTTPS:使用 HTTPS,提高安全性和性能
  • CDN:使用 CDN 加速静态资源
  • 缓存策略:合理设置缓存策略,减少重复请求
  • 请求合并:合并多个请求,减少网络请求次数
  • 数据压缩:启用 Gzip、Brotli 等压缩方式

实现代码

缓存策略配置 (nginx.conf):

# 静态资源缓存配置
location ~* \.(js|css|png|jpg|jpeg|gif|webp|svg|ico)$ {
  expires 7d;
  add_header Cache-Control "public, max-age=604800";
  access_log off;
}

# HTML 文件缓存配置
location ~* \.html$ {
  expires 0;
  add_header Cache-Control "no-cache, no-store, must-revalidate";
  add_header Pragma "no-cache";
  add_header Expires "0";
}

使用 HTTP/2

# HTTP/2 配置
server {
  listen 443 ssl http2;
  server_name example.com;
  
  # SSL 配置
  ssl_certificate /path/to/cert.pem;
  ssl_certificate_key /path/to/key.pem;
  
  # 其他配置...
}

5. 响应式优化

优化策略

  • 使用媒体查询:使用媒体查询适配不同屏幕尺寸
  • 弹性布局:使用 Flexbox 和 CSS Grid 进行弹性布局
  • 相对单位:使用相对单位(如 rem、em、vw、vh),避免使用固定单位
  • 图片响应式:使用响应式图片,适配不同屏幕尺寸
  • 移动端优先:采用移动端优先的设计策略

实现代码

响应式布局

/* 移动端优先 */
.container {
  width: 100%;
  padding: 0 15px;
}

/* 平板 */
@media (min-width: 768px) {
  .container {
    width: 750px;
    margin: 0 auto;
  }
}

/* 桌面 */
@media (min-width: 992px) {
  .container {
    width: 970px;
  }
}

/* 大屏桌面 */
@media (min-width: 1200px) {
  .container {
    width: 1170px;
  }
}

/* 弹性布局 */
.grid {
  display: flex;
  flex-wrap: wrap;
  margin: 0 -15px;
}

.grid-item {
  flex: 0 0 100%;
  padding: 0 15px;
  margin-bottom: 30px;
}

/* 平板:2 列 */
@media (min-width: 768px) {
  .grid-item {
    flex: 0 0 50%;
  }
}

/* 桌面:3 列 */
@media (min-width: 992px) {
  .grid-item {
    flex: 0 0 33.333%;
  }
}

/* 大屏桌面:4 列 */
@media (min-width: 1200px) {
  .grid-item {
    flex: 0 0 25%;
  }
}

响应式图片

<!-- 响应式图片 -->
<picture>
  <!-- 大屏 -->
  <source media="(min-width: 1200px)" srcset="image-large.webp" type="image/webp">
  <source media="(min-width: 1200px)" srcset="image-large.jpg">
  <!-- 桌面 -->
  <source media="(min-width: 992px)" srcset="image-medium.webp" type="image/webp">
  <source media="(min-width: 992px)" srcset="image-medium.jpg">
  <!-- 平板和移动端 -->
  <source srcset="image-small.webp" type="image/webp">
  <img src="image-small.jpg" alt="响应式图片" class="responsive-image">
</picture>

<style>
.responsive-image {
  max-width: 100%;
  height: auto;
}
</style>

6. 浏览器兼容性

优化策略

  • 使用 Babel:使用 Babel 转译 ES6+ 代码,提高兼容性
  • 使用 Polyfill:使用 Polyfill 填充浏览器缺失的功能
  • CSS 前缀:使用 Autoprefixer 自动添加 CSS 前缀
  • 特性检测:使用特性检测,避免使用不支持的特性
  • 优雅降级:对于不支持的特性,提供降级方案

实现代码

Babel 配置 (babel.config.js):

module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        targets: {
          browsers: [
            '> 1%',
            'last 2 versions',
            'not dead'
          ]
        },
        useBuiltIns: 'usage',
        corejs: 3
      }
    ]
  ]
};

特性检测

// 特性检测
function checkFeatureSupport() {
  // 检测 localStorage
  const hasLocalStorage = typeof Storage !== 'undefined' && typeof localStorage !== 'undefined';
  
  // 检测 Promise
  const hasPromise = typeof Promise !== 'undefined';
  
  // 检测 fetch
  const hasFetch = typeof fetch !== 'undefined';
  
  return {
    hasLocalStorage,
    hasPromise,
    hasFetch
  };
}

// 使用特性检测结果
const features = checkFeatureSupport();

if (features.hasFetch) {
  // 使用 fetch
  fetch('https://api.example.com/data')
    .then(response => response.json())
    .then(data => console.log(data));
} else {
  // 使用 XMLHttpRequest 作为降级方案
  const xhr = new XMLHttpRequest();
  xhr.open('GET', 'https://api.example.com/data');
  xhr.onload = function() {
    if (xhr.status >= 200 && xhr.status < 300) {
      const data = JSON.parse(xhr.responseText);
      console.log(data);
    }
  };
  xhr.send();
}

学习目标

通过本章节的学习,你应该能够:

  1. 理解 Web 端性能特点:掌握 uni-app Web 端的性能特点和运行机制
  2. 掌握 Web 端优化策略:能够从加载、渲染、资源、网络、响应式等方面优化 Web 端性能
  3. 使用 Web 端性能监控工具:能够使用浏览器开发者工具分析性能问题
  4. 实现 Web 端优化:能够根据项目特点,实施有效的 Web 端优化方案
  5. 解决浏览器兼容性问题:能够解决不同浏览器的兼容性问题

总结

uni-app Web 端优化是一个综合性的工作,需要从多个方面入手,结合 Web 端的特点实施针对性的优化策略。通过合理的优化,可以显著提升 Web 端应用的用户体验,提高用户留存率。

在实际项目中,我们需要注意以下几点:

  1. 性能分析:使用浏览器开发者工具,定期分析 Web 端性能
  2. 优化优先级:根据用户体验影响程度,确定优化优先级
  3. 持续优化:建立性能优化的持续迭代机制
  4. 测试验证:优化后进行充分测试,确保优化效果
  5. 浏览器兼容性:关注不同浏览器的兼容性问题,提供降级方案
  6. 用户反馈:关注用户反馈,及时解决性能问题

通过本章节的学习和实践,你应该能够熟练掌握 uni-app Web 端优化的方法和技巧,为用户提供更加流畅、快速的 Web 端应用体验。

« 上一篇 uni-app App 性能优化 下一篇 » uni-app 多端样式统一