H5移动端游戏项目

245 阅读11分钟

一、性能优化板块

当前跑分

indexfcplcp入口文件源大小总分
11.27.81.6mb48
21.58.41.6mb51
31.68.11.6mb50
  • fcp,衡量的是从用户首次导航到相应网页到该网页的任何部分呈现在屏幕上所用的时间。
  • lcp,从用户开始加载网页到最大的图片文本块在视口中呈现之间的时间。
  • 入口文件源大小,webpack打包后的入口文件大小
  • 总分,lighthouse的总跑分数据。

优化过程

fcp

html添加一个loading图

lcp

image.png

  • csr项目fcp时间长痛点的原因,我们是入口文件加载渲染完成后再通过js动态添加img,导致我们的资源加载延迟特别长,官方建议:为了消除不必要的资源加载延迟,您的 LCP 资源必须可从 HTML 源代码中发现
优化思路
  • 简单粗暴版

在项目的html文件里面添加一个loading图片,让loading图成为我们的fcp资源,待我们的root元素加载完成后,再隐藏这个loading图片。

  • 高级版本

写死fcp图片资源的cdn路径,然后在html的添加如下link链接,关键是preload

<link rel="preload" fetchpriority="high" as="image" href="/path/to/hero-image.webp" type="image/webp">
  • 最优版本

采用SSG,参考资料,时间20240402,正在学习中。

入口文件源大小

通过webpack的webpack-bundle-analyzer进行分析。

  • 入口文件不加载三方sdk
  • 异步加载sdk与路由页面
  • 组件里面的非关键子组件进行懒加载

第一版优化后的跑分

优化的部分

  • 添加loading
  • 三方sdkmoment改为非入口文件引入
indexfcplcp入口文件源大小总分
11.813.41.3mb53
21.6131.3mb55
31.3131.3mb50

二、google的SEO

搜索引擎优化 (SEO) 旨在帮助搜索引擎了解您的内容,并通过搜索引擎帮助用户找到您的网站并决定是否应访问您的网站。Google 不会通过收取费用来提高网站抓取频率或网站排名。

0、 google搜索的工作原理

总结:

  • 首先抓取:使用googlebot抓取网页,可配置robots.txt禁止某些页面被抓取,在抓取过程中会渲染执行js,这意味着客户端渲染的网站也能被正确抓取到。
  • 其次索引编制:也就是理解网页的内容,如:title元素 以及 alt属性。将数据存储到goolge索引数据库中。
  • 最后呈现搜索结果:当用户输入查询时,浏览器会在goolge索引数据库中搜索匹配的网页。

1、查看目标网址是否已编入索引(是否能在google搜索中找到)

在google搜索中输入此内容 site:wikipedia.org 会返回如下结果,则是成功。

image.png

如果没有考虑是否是以下问题:

  • Googlebot被屏蔽
  • 网页状态码不是200
  • 网页没有包含可编入索引的内容
  • 刚刚推出新的网站,Google 还没来得及抓取

可编入索引的内容

2、如何查看目标网址在google搜索中的整体数据情况

image.png 需要你的根目录配置google专属html文件进行校验,校验通过后会进入此网站。

image.png

image.png

image.png

3、抓取和编入索引

官方说明 介绍了如何控制 Google 对您内容的查找和解析以使其显示在 Google 搜索和其他 Google 产品和服务中,以及如何阻止 Google 抓取您网站上的特定内容。注意:只有页面被编入索引,才能在google搜索中展示出来

总结:

  • 链接,仅当链接是包含 href 属性的 <a> HTML 元素(也称为“锚标记元素”)时,Google 才能自动抓取该该网站的其他链接。(官方推荐举例
  • js,spa页面的话,不用使用hash路由方式,使用history方式,同时页面的跳转使用a标签,而不是js代码这种伪方式。
  • 站点地图,告诉搜索引擎您希望让哪些网址显示在搜索结果中。
    1. 创建站点地图
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://www.example.com/foo.html</loc>
    <lastmod>2022-06-04</lastmod>
  </url>
</urlset>

image.png

    1. 验证,google搜索输入site: example.com/test
  • 请求google重新抓取您的网址
  • robots.txt,控制抓取工具可以访问您网站上的哪些文件,此文件主要用于避免您的网站收到过多请求;它并不是一种阻止 Google 抓取某个网页的机制。若想阻止 Google 访问某个网页,请使用 noindex 禁止将其编入索引,或使用密码保护该网页。
  • AMP,一种让你的网站能够在google浏览器快速渲染出来的技术,也有助于seo排名.
  • js,google能理解spa页面,但是其他搜索引擎就不一定了,所以还是建议用ssr渲染或者pre渲染。对于spa页面,确保使用的路由跳转是History api且是通过a标签跳转而不是js代码。对于图片,推荐用延迟加载策略,从而减少带宽。
  • 网页和内容元数据,告知开发者head里面的元素只有哪些标签,以及告诉开发者使用meta元素的作用.

4、搜索结果呈现

介绍了如何更改您的网站在 Google 搜索及其他 Google 产品和服务中的显示效果。

核心关键点就是通过结构化数据功能(application/ld+json) 完成。

各种结构化数据功能

5、SEO

官方说明 搜索引擎优化,使您的内容易于搜索,且排名靠前。

总结:

  • 相关页面需要被编入索引。
  • 站内优化:描述网页元素的字词,每个页面都有title与meta description,关键图片有文字描述、alt描述,每个页面的title、description meta、h标签都很重要,其内容要与网站有很大的关联性。注意 google 搜索不会留意keywords meta这个关键字,官方对于keywords 说明,关于关键字查找详细指导
  • 技术优化:站点地图,白屏优化,多语言,二级域名或者目录标明语言类型,如en.example.com | es.example.com | test.example.com/en | test.example.com/es ,同时设置link中的alternate。(官方说明)
  • 结构化数据,控制网页在搜索引擎的搜索列表中展示效果。(官方说明
  • google的广告系统,实际上广告会显示与搜索关键匹配的字段,且有广告标签,并且不会罗列在排名列表里面,而是在其他醒目位置展示。 image.png

6、业务运用

我的项目是纯csr项目,现在是针对seo做的优化策略。

  1. 将页面从原来是的hash的路由切换成history路由,这是seo的要求。
  2. 页面路由跳转用的库是react-router-dom,将一级页面的跳转从js控制跳转改成用Link组件(a标签)跳转,google SEO是根据a标签的href来进行其他链接搜索的。
  3. 图片添加loading标识。
  4. 添加站点地图。

遇到的问题

提交的站点地图确实是xml,但是google后台检测老是显示说是html。

问题情况(解决):

1.2024-07-22 官方后台提问 2.2024-07-25 解决,重新提交并重命名

通过google索引展示的链接,点击进去之后会带上参数?

问题情况(待解决):

1.2024-07-22 重新抓取请求,编入索引。

csr动态修改一级页面的标题,但是在google 索引里面并没有变化

问题情况(待解决):

1.2024-07-22 将页面改成ssg,需要迁移框架了,将webpack5切到next.jx.

三、移动端适配pc端

1、单位用rem,动态修改html的fontSize

import React, {
    useEffect,
} from "react";
// 动态计算rem
export default () => {
    useEffect(() => {
        const changeSize = () => {
            const innerWidth = window.innerWidth;
            const minimum = 1534; // pc最低宽度要求
            const isPcWidth = 450; // 是否转为pc的阈值判断
            const desginW = 1920; // 设计稿宽度

            let pcWidth = innerWidth < minimum ? minimum : innerWidth;
            if (innerWidth < minimum) {
                pcWidth = minimum;
            } else if (innerWidth > 1920) {
                pcWidth = 1920;
            } else {
                pcWidth = innerWidth;
            }
            console.log("pcWidth", pcWidth);
            const rem = pcWidth / desginW;

            document.documentElement.style.fontSize = `${rem}px`;
        };
        window.addEventListener("resize", changeSize, false);
        changeSize();
        return () => {
            window.removeEventListener("resize", changeSize, false);
        };
    }, []);
}

2、设置高度等比于宽度的3/4

面试官:CSS如何实现固定宽高比?

四、PWA的使用

juejin.cn/post/737652…

五、ios描述文件安装(web clip)

作用:通过安装ios描述文件,让你的h5网站以快捷方式存留在苹果用户桌面上,类似app,很鸡肋。

需要两个文件mobileconfigmobileprovision

mobileconfig这个描述文件存储了网站的url、icon、app名称,可以在apple store上安装Apple configurator,通过它来生成mobileconfig文件。

image.png

image.png

image.png

image.png

image.png

签名的话需要开发者账号或者进行ssl证书签名,否则签署身份就是无。

mobileprovision这个描述文件的作用就是辅助用户直接跳转到描述文件的安装页面。这个文件的生成需要ios开发者账号,需要花钱的一年99刀,但是我们可以去网上扒拉一个白嫖。

html安装代码:

 <a className={cs.hasDownload} href="/web1.mobileprovision" download='mobileprovision'>mobileprovision</a>
 <a className={cs.download} href='/Pooke.mobileconfig' download='mobileconfig' >mobileconfig</a>

五、google登录

juejin.cn/post/727812…

六、firebase

创建fireabase项目

image.png

给其他用户分配权限

image.png

创建项目中的应用

image.png

image.png

1、引入事件分析(埋点)

引入sdk,打开firebase管理后台,进行如下操作,并把sdk引入。

image.png

整体测试代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <p>设置用户id:</p>
  <button onclick="handleSetUserId('10086')">10086</button>
  <button onclick="handleSetUserId('10010')">10010</button>
  <button onclick="handleSetUserId('888')">888</button>
  <p>设置用户属性</p>
  <button onclick="handleSetUserProterty({zone: '广东省'})">广东省</button>
  <button onclick="handleSetUserProterty({zone: '福建省'})">福建省</button>
  <p>设置买上衣事件</p>
  <button onclick="handleBuyCloth({type: '短袖T恤', price: 100, unit: '元'})">短袖T恤 100元</button>
  <button onclick="handleBuyCloth({type: '纯棉外套', price: 200, unit: '元'})">纯棉外套 200元</button>
  <p>设置买裤子事件</p>
  <button onclick="handleBuyPath({type: '短裤', price: 110, unit: '元'})">短裤 110元</button>
  <button onclick="handleBuyPath({type: '长裤', price: 150, unit: '元'})">长裤 150元</button>


</body>
<script type="module">
  // Import the functions you need from the SDKs you need
  import { initializeApp } from "https://www.gstatic.com/firebasejs/10.12.3/firebase-app.js"
  import { getAnalytics, logEvent, setUserProperties, setUserId } from "https://www.gstatic.com/firebasejs/10.12.3/firebase-analytics.js"
  // TODO: Add SDKs for Firebase products that you want to use
  // https://firebase.google.com/docs/web/setup#available-libraries

  // Your web app's Firebase configuration
  // For Firebase JS SDK v7.20.0 and later, measurementId is optional
  const firebaseConfig = {
    apiKey: "AIzaSyBFbCvxMeaNghjN7XYlamdJOf8ONS5OED0",
    authDomain: "test-7f75e.firebaseapp.com",
    projectId: "test-7f75e",
    storageBucket: "test-7f75e.appspot.com",
    messagingSenderId: "352314329264",
    appId: "1:352314329264:web:97b63a90deb53946751375",
    measurementId: "G-3NKG441EVK"
  }

  // Initialize Firebase
  const app = initializeApp(firebaseConfig)
  window.analytics = getAnalytics(app)
  window.logEvent = logEvent
  window.setUserProperties = setUserProperties
  window.setUserId = setUserId
</script>
<script>

  var handleSetUserId = (data) => {
    console.log('用户Id:', data)
    setUserId(analytics, data)
  }
  var handleSetUserProterty = (data) => {
    console.log('用户属性:', data)
    setUserProperties(analytics, data)
  }
  var handleBuyCloth = (data) => {
    let eid = '买衣服'
    console.log('事件上报:', eid, 'data', data)
    logEvent(analytics, eid, data)
  }
  var handleBuyPath = (data) => {
    let eid = '买裤子'
    console.log('事件上报:', eid, 'data', data)
    logEvent(analytics, eid, data)
  }
</script>

</html>

注意:自定义事件,它的事件参数要在后台进行配置,可以设置维度或指标。纬度与指标不能同时指向相同的事件参数的key

image.png

image.png

纬度:当事件参数的key作为维度时,它的value要设置成字符串。

指标:当事件参数的key作为指标时,它的value要设置成数字类型。图标分析时会累计计算这个值

每个自定义事件,都要配置自定义维度与指标。

2、 建立图标分析

根据事件分析各种情况。 image.png

image.png

2.1 自由形式

2.2 用户分层图标

使用场景:

  • 分析单个用户的事件情况 image.png

image.png

3、 遇到的问题

3.1 firebase是如何区分用户总数的?

image.png

解答:是根据api setUserId做区分的,如果没有设置此api,则sdk会自动调用,并设置一个随机数值。

3.1 为什么我设置了自定义事件以及自定义参数key,但是后台并没有展示这个值的key?

例如

    logEvent(analytics, '买衣服', {
      type: '短袖T恤'
    })

image.png 原因:多等几天,google的数据分析会有好多天的延迟,等个四五天即可。

image.png 为什么会有个(not set)? 我猜测是google那边还没有分类完成,先用(not set)代替,再多等等。

其他零零碎碎的总结

1、多语言的问题

  • 以英文的字段作为key
"key1":"value1"

这么做的好处1,是没有匹配到多语言的时候可以走默认英文,2是方便自己用node写一个脚本工具