react with_如何在React with Google Analytics中设置性能和用户跟踪

react with

Keeping track of your users and your app performance is a very crucial part of modern web development. You may have seen reports of companies increasing revenues by simply decreasing the load time of their app by a few hundred milliseconds.

跟踪用户和应用程序性能是现代Web开发中非常重要的部分。 您可能已经看到有关公司通过简单地将其应用程序的加载时间减少几百毫秒来增加收入的报告。

Keeping track of your user behavior is also crucial. This will allow you to modify and build your app according to your users' preferred way of interacting with your app, resulting in happier users and more traffic to your site.  

跟踪用户行为也至关重要。 这将使您能够根据用户与应用程序进行交互的首选方式来修改和构建应用程序,从而带来更快乐的用户和更多的网站访问量。

Here is the completed project:

这是完成的项目:

https://github.com/iqbal125/react-hooks-google-analytics

https://github.com/iqbal125/react-hooks-google-analytics

In this guide I'll give you a complete foundational guide to tracking both performance and user behavior. By the end of the tutorial you will have everything you need to build complex user and performance tracking setups.

在本指南中,我将为您提供跟踪性能和用户行为的完整基础指南。 在本教程结束时,您将拥有构建复杂的用户和性能跟踪设置所需的一切。

Follow Me on Twitter for more tutorials in the future: https://twitter.com/iqbal125sf

在Twitter上关注我,以获取将来的更多教程: https//twitter.com/iqbal125sf

目录 (Table of Contents)

  1. Intro

    介绍
  2. Google Analytics

    谷歌分析
  3. Tracking Pages Views

    跟踪页面浏览量
  4. Tracking Load Performance

    跟踪负载性能
  5. Tracking Rendering Performance

    跟踪渲染效果
  6. Tracking Paint

    跟踪漆
  7. Tracking Scroll

    跟踪滚动
  8. Tracking Events

    追踪事件
  9. Quick Performance Tips and Heuristics

    快速性能提示和启发式

介绍 (Intro)

I will show you the performance metrics for the development build of react to keep this tutorial concise. But in a real world situation do not test the dev version, because it contains a lot of error handling code and lack of optimizations that will give you highly skewed results.

为了使本教程简洁,我将向您展示react开发的性能指标。 但是在现实世界中,不要测试开发版本,因为它包含很多错误处理代码,并且缺乏优化功能,这些优化功能会给您带来严重偏差的结果。

For this reason it is better to test on the build production version to establish some baseline metrics.

因此,最好在构建生产版本上进行测试以建立一些基线指标。

Also, for the sake of brevity I will just refer to Google Analytics as GA.

另外,为简洁起见,我将Google Analytics(分析)简称为GA。

GA also doesn't work with local host. To get a simulation of what you might be sending to GA without actually sending it and messing up your analytics, you can just substitute a console.log wherever you plan on putting your GA hit.

GA也不适用于本地主机。 要模拟您可能要发送给GA的内容而又不实际发送并弄乱您的分析结果,您可以在计划将GA投放到任何地方的地方,都可以用console.log代替。

ReactGA  is the global function and is known as the command queue because it does not execute commands immediately but adds commands to a queue and then sends them asynchronously. This does not tie up the main thread and does not lead to your tracking code harming your app performance.

ReactGA是全局函数,被称为命令队列,因为它不会立即执行命令,而是将命令添加到队列中,然后异步发送。 这不会占用主线程,也不会导致跟踪代码损害应用程序性能。

A hit is when a GA tracker sends data to Google Analytics.

命中率是指Google Analytics(分析)跟踪器将数据发送到Google Analytics(分析)。

We will mainly be focusing on the React code in this tutorial, there are far better other tutorials to learn how to use GA.  

在本教程中,我们将主要关注React代码,还有其他更好的教程来学习如何使用GA。

There are 3 main functions we will use when sending hits to GA. You should know there are more but we will just focus on these 3 for the purposes of this tutorial.

向GA发送匹配数据时,我们将使用3个主要功能。 您应该知道还有更多,但是出于本教程的目的,我们将只关注这3个。

GAReact.pageview(): will pass in a string that contains the route.

GAReact.pageview() :将传入包含路线的字符串。

GAReact.timing(): Will take an object as a parameter. Will contain information related to our performance metrics which we will see below. The fields will be category, variable, value and label. Notice that only the value property will be coming from our app the rest of the properties are user defined.

GAReact.timing() :将一个对象作为参数。 将包含与我们的绩效指标有关的信息,我们将在下面看到。 这些字段将是categoryvariablevaluelabel 。 请注意,只有value属性将来自我们的应用程序,其余属性是用户定义的。

GAReact.event(): Will take an object as a parameter. Will contain data about events that take place in the app (form submit, button click, etc.)  Will have fields of category, action, label and value. Note that only the value is going to come from the app, the rest of the properties are user defined.

GAReact.event() :将一个对象作为参数。 将包含有关应用程序中发生的事件的数据(表单提交,按钮单击等)。将具有categoryactionlabelvalue 。 请注意,只有该值将来自应用程序,其余属性是用户定义的。

Synthetic testing vs RUMYou might be wondering why go through all this trouble of setting up Performance Observer metrics if you can just use a tool like Lighthouse or Webpage speed test and get these metrics by just entering in the url.

综合测试与RUM的比较如果您仅使用Lighthouse或Webpage速度测试之类的工具并仅通过输入URL即可获得这些指标,那么您可能想知道为什么要经历所有麻烦来设置Performance Observer指标。

Tools like those are important but they are what’s known as synthetic testing since the test will be done on your device and the test will not actually reflect what your users are experiencing. You can throttle the CPU or network when making these tests but they are still simulations.

诸如此类的工具很重要,但它们被称为综合测试,因为该测试将在您的设备上完成,并且该测试实际上不会反映用户的体验。 进行这些测试时,可以限制CPU或网络,但它们仍是模拟。

Using GA with Performance Observer metrics will give us real numbers from our actual end users, devices and networks. This is known as RUM or Real User Monitoring.

将GA与Performance Observer指标结合使用,将为我们提供来自实际最终用户,设备和网络的真实数字。 这称为RUM或真实用户监视。

Synthetic testing tools. Simply enter the URL of your app to run the synthetic tests.

综合测试工具。 只需输入应用程序的URL即可运行综合测试。

谷歌分析
(Google Analytics)

SetupIf you already have Google Analytics setup on your app, feel free to skip this section there is nothing new here.

设置如果您已经在应用程序上设置了Google Analytics(分析),请随时跳过此部分,这里没有新内容。

To setup GA go on the dashboard and click on the admin tab on the side drawer. Then click add property. Fill out the required info.

要设置GA,请在信息中心上,然后点击侧面抽屉上的管理标签。 然后单击添加属性。 填写必填信息。

If you are reading this tutorial I'm going to assume your smart enough to setup Google Analytics with just those 3 lines of instruction. If not, here is a handy guide by Google.

如果您正在阅读本教程,那么我将假设您足够聪明,只需使用这3条指令即可设置Google Analytics(分析)。 如果没有,这是Google的便捷指南。

https://support.google.com/analytics/answer/1042508?hl=en

https://support.google.com/analytics/answer/1042508?hl=zh_CN

After you're done setting up, you will get a tracking id at the top, which we will use in our React App.

设置完成后,您将在顶部获得一个跟踪ID,我们将在我们的React App中使用该ID。

Setup in reactWe dont have to re-invent the wheel here, we can use a helper library made by the Mozilla Foundation to help us with the React setup.

React中进行设置我们不必在这里重新发明轮子,我们可以使用Mozilla Foundation提供的帮助程序库来帮助我们进行React设置。

To install the library simply run

要安装该库,只需运行

npm install react-ga

npm install react-ga

Then just import the ReactGA object where ever you want to use it

然后只需将ReactGA对象导入到您想使用它的任何地方

import ReactGA from 'react-ga';

You will also need to initialize it in the root component with the tracking id from google analytics.  

您还需要使用Google Analytics(分析)中的跟踪ID在根组件中对其进行初始化。

...
ReactGA.initialize('UA-00000-1');
...

ObserversReactGA cant do anything besides send data to the Google Analytics website. To actually get performance metrics to send, we will use the Performance Observer browser API. This Performance Observer API has nothing to do with GA or even React, it is a browser API that is available in most modern browsers

观察者 ReactGA除了将数据发送到Google Analytics(分析)网站之外,无能为力。 要实际获取要发送的性能指标,我们将使用Performance Observer浏览器API。 此Performance Observer API与GA甚至React都不相关,它是大多数现代浏览器中都可用的浏览器API

How the PerformanceObserver and related APIs work exactly is a fairly big topic and is far out of the scope of this tutorial. See the Further Reading section for more info and links to tutorials.

PerformanceObserver和相关API的确切工作方式是一个相当大的主题,并且超出了本教程的范围。 有关更多信息和教程链接,请参见进一步阅读部分。

The basic idea of how they work is they "observe" something and then send that data asynchronously at the time of the browsers choosing. This keeps the main thread free for critical app functionality and related tasks, therefore tracking events does not affect your app performance.

他们如何工作的基本思想是,他们“观察”某些东西,然后在浏览器选择时异步发送该数据。 这使主线程可以自由处理关键的应用程序功能和相关任务,因此跟踪事件不会影响您的应用程序性能。

Before observers you would have to add an event listener and fire it synchronously every time something happened, this resulted  in noticeable performance issues if too many events were being fired at once. So this is the problem observers are looking to solve.

在观察者之前,您必须添加一个事件侦听器,并在每次发生任何事情时同步触发它,如果一次触发太多事件,则会导致明显的性能问题。 这就是观察者想要解决的问题。

跟踪页面浏览量
(Track Page Views)

Tracking page views in a single page app like react may seem like it would be complicated but its relatively simple thanks to react-router and history libraries.

在单个页面应用程序(例如react)中跟踪页面浏览量似乎很复杂,但是由于react-router和历史记录库的存在,它相对简单。

history.listen((location) => {
    ReactGA.set({ page: location.pathname });
    ReactGA.pageview(location.pathname)
  }
);

history.listen() allows you to fire a callback on route changes which in our case happens to be the GA hit. The route is contained in the pathname property of location.  But there are a couple of things to note such as:

history.listen()允许您对路线更改触发回调,在我们的案例中,路线更改恰好是GA命中。 路线包含在locationpathname属性中。 但是有几件事要注意,例如:

Handling the intial loadHistory is listening for page changes but it doesn’t cause a hit on the initial page load.

处理初始加载历史记录正在侦听页面更改,但不会对初始页面加载造成影响。

There are a few ways to handle the initial load. I found a simple way to do it that I think requires the least amount of code and complexity and it is just to have an initial load variable and save it to the global state. In the home page just use a conditional to check if it is false then set it to true after the hit.

有几种方法可以处理初始负载。 我找到了一种简单的方法,我认为它需要最少的代码和复杂性,并且只是拥有一个初始加载变量并将其保存到全局状态。 在主页中,只需使用条件检查它是否为false,然后在命中后将其设置为true。

Context variable in the parent component

父组件中的上下文变量

... 

const [initialLoad, setInitialLoad] = useState(false)

...
      <Context.Provider
            //Initial Load
            initialLoadProp: initialLoad,
            setInitialLoadProp: () => setInitialLoad(true),
       >
      </Context.Provider>

Then the useEffect() in the home child component

然后在家庭子组件中使用useEffect()

...   
useEffect(() => {
    if(!context.initialLoadProp) {
      ReactGA.pageview(props.location.pathname);  
      context.setInitialLoadProp(true)
    }
  }, [])
...

There are other implementations and discussions you can find here:

您还可以在这里找到其他实现和讨论:

https://github.com/react-ga/react-ga/wiki/React-Router-v4-withTracker

https://github.com/react-ga/react-ga/wiki/React-Router-v4-withTracker

Tracking pages with User idsAnother thing you might want to know is how many users are visiting their private profile pages. Just using the pageviews would give you a unique url for every hit and will not work.

使用用户ID跟踪页面您可能想知道的另一件事是,有多少用户正在访问其个人资料页面。 仅使用综合浏览量会为您的每次匹配提供唯一的网址,并且将无法正常工作。

Say you have the following URLs with user ids:

假设您有以下带有用户ID的URL:

user/4543456/messagesuser/4543456/accountuser/3543564/messagesuser/3543564/replytomessageuser/3543564/account

用户/ 4543456 / messagesuser / 4543456 / accountuser / 3543564 / messagesuser / 3543564 / replytomessageuser / 3543564 / account

These will all give you a unique page hit. A simple fix is to just check with a conditional and then remove the unique id. You can also use a conditional to make sure you dont send these pages to google analytics.

这些都将为您带来独特的网页匹配。 一个简单的解决方法是只检查条件,然后删除唯一的ID。 您还可以使用条件来确保您不将这些页面发送给Google Analytics(分析)。

...

 history.listen((location) => {
   if(location.pathname.includes('/user')) {
     let rootURL = location.pathname.split('/')[1]
     let userPage = location.pathname.split('/')[3]

     let pageHit = `/${rootURL}/${userPage}`
     ReactGA.pageview(pageHit)
   } else {
     ReactGA.set({ page: location.pathname });
     ReactGA.pageview(location.pathname)
   }
});

...

We are simply just parsing out the user id and then concatenating the route again before sending the hit.

我们只是解析用户ID,然后在发送匹配之前再次连接路由。

This would probably not be true for forum posts since having a unique URL for each post would be correct, since you would like to know how many people visited each post.

对于论坛帖子,可能并非如此,因为每个帖子都有唯一的URL是正确的,因为您想知道有多少人访问了每个帖子。

跟踪负载性能 (Tracking Load Performance)

Getting the load performance is relatively easy. All the load performance data is under the navigation entry which is part of the navigation timing API.

获得负载性能相对容易。 所有负载性能数据均在navigation条目下,该条目是导航计时API的一部分

The Performance Observer Can be setup like so in the root parent component.

可以像这样在根父组件中设置性能观察器。

const callback = list => {
    list.getEntries().forEach(entry => {
      ReactGA.timing({
        category: "Load Performace",
        variable: "Some metric",  
	value: "Value of Metric"
      })
  })
}

var observer = new PerformanceObserver(callback);
observer.observe({entryTypes: ['navigation'] })

First we define a function to be called for each entry. Then we pass this callback into our PerformanceObserver and finally we call the .observe() method on our observer and pass in navigation as an entryType.  

首先,我们定义一个为每个条目调用的函数。 然后,我们将此回调传递到PerformanceObserver ,最后在观察者上调用.observe()方法,并将navigation作为entryType传递。

This will give you the following entry:

这将为您提供以下条目:

This is a very large amount of information but really we need only 3 properties to track the main load performance:

这是大量信息,但实际上我们只需要3个属性即可跟踪主要负载性能:

requestStart: when the browser issues a request to get the webpage from the server

requestStart :当浏览器发出从服务器获取网页的请求时

responsesStart: when the first byte of the website arrives

responsesStart :网站的第一个字节到达时

responseEnd: When the last byte of the website arrives

responseEnd :网站的最后一个字节到达时

There are a few things that happen before the requestStart such as DNS lookup and the TLS handshake. Use this data and see if you can combine it with other properties to make new metrics.

在requestStart之前发生了一些事情,例如DNS查找和TLS握手。 使用此数据,查看是否可以将其与其他属性结合使用以制定新指标。

With the above three properties we can create 3 important metrics. Simply substitute in the variable and value properties for the respective metric.

通过以上三个属性,我们可以创建3个重要指标。 只需用相应属性的variablevalue属性替代即可。

const callback = list => {
    list.getEntries().forEach(entry => {
      ReactGA.timing({
        category: "Load Performace",
        variable: 'Server Latency',
        value: entry.responseStart - entry.requestStart 
      })
  })
}

Server latency:entry.responseStart - entry.requestStart

服务器延迟: entry.responseStart - entry.requestStart

Download time:entry.responseEnd - entry.responseStart

下载时间: entry.responseEnd - entry.responseStart

Total app load time:entry.responseEnd - entry.requestStart

应用程序总加载时间: entry.responseEnd - entry.requestStart

Time to InteractiveThis metric is essentially how long it takes for a user to be able to interact with your site.

互动时间该指标本质上是用户能够与您的网站进行交互所花费的时间。

Until a native TTI metric is available through the browser api we can use this handy polyfill npm module for now. This module is created by Google.

在通过浏览器api获得本机TTI指标之前,我们现在可以使用此便捷的polyfill npm模块。 此模块由Google创建。

npm install tti-polyfill

npm install tti-polyfill

Then we can use the polyfill like so.

然后我们可以像这样使用polyfill。

... 

import ttiPolyfill from 'tti-polyfill';


ttiPolyfill.getFirstConsistentlyInteractive().then((tti) => {
  ReactGA.timing({
    category: "Load Performace",
    variable: 'Time to Interactive',
    value: tti 
  })
});

...

We are simply sending a hit inside of our function with a chained .then() statement since we will retrieve this metric asynchronously.

我们只是通过链接的.then()语句在函数内部发送.then()因为我们将异步检索此指标。

跟踪渲染效果 (Tracking Rendering Performance)

Now we can discuss Rendering Performance, which is how long it takes for React to construct the tree of DOM nodes. We can track rendering performance with the mark and measure entries.

现在我们可以讨论渲染性能,这是React构造DOM节点树所花费的时间。 我们可以使用markmeasure条目来跟踪渲染性能。

mark is used to "mark" a point in time you want to keep track of. Just pass in a string as the name of the mark on the exact line you want mark for tracking.

mark用于“标记”您要跟踪的时间点。 只需在要跟踪标记的确切行上传递一个字符串作为标记名称即可。

performance.mark("name of mark")

measure is the difference between the 2 marks. Just set the name of the measure and pass in start and end marks, which will give you the difference between the marks in milliseconds.

measure是两个标记之间的差。 只需设置小节的名称并传递开始和结束标记,这将为您提供标记之间的差(以毫秒为单位)。

performance.measure.("name of mark", startingMark, EndingMark)

Thankfully React comes pre-bundled with these marks and measures, which saves us from having to open up the React Source and having to write them ourselves. Simply pass in mark and measure for the entry types and you're done.

幸运的是,React预先捆绑了这些标记和措施,这使我们不必打开React Source并自己编写它们。 只需传递markmeasure条目类型,即可完成。

...

var observer = new PerformanceObserver(callback);
observer.observe({entryTypes: ['mark', 'measure'] })

...

This will give you the time it takes for root parent component and all child components to render in milliseconds. You will get entries that look something like this:

这将为您提供根父级组件和所有子级组件渲染所需的时间(以毫秒为单位)。 您将获得类似于以下内容的条目:

You will also get the time it takes for the lifecycle methods to execute. There is a wealth of information here, simply pick what you want to track and send it to GA by checking for the name in a conditional statement.

您还将获得执行生命周期方法所需的时间。 这里有很多信息,只需通过检查条件语句中的名称来选择要跟踪的内容并将其发送给GA。

...
const callback = list => {
    list.getEntries().forEach(entry => {
      if(entry.name.includes('App') ) {
        ReactGA.timing({
          category: "App Render Performace",
          variable: entry.name,
          value: entry.duration
        })
      }
  })
}
...

跟踪油漆性能 (Tracking Paint Performance)

Now we can track paint which is when the pixels are drawn (or "painted") to the screen after the DOM tree is rendered.  

现在我们可以跟踪绘制,即绘制DOM树后将像素绘制(或“绘制”)到屏幕上的时间。

Tracking paint performance comprises 3 metrics: First Paint, First Contentful Paint and First Meaningful paint.

跟踪绘画效果包括3个指标:“第一绘画”,“第一内容绘画”和“第一有意义绘画”。

First Paint: First time anything besides a blank white page is present.

初次涂漆 :第一次出现空白页之外的任何东西。

First Contentful Paint: When the first DOM element is present. Text, image etc.

First Contentful Paint:存在第一个DOM元素时。 文字,图片等

First Paint and First Contentful Paint will be given automatically by the API. Simply do the following:

API将自动提供First Paint和First Contentful Paint。 只需执行以下操作:

...

const callback = list => {
    list.getEntries().forEach(entry => {
       ReactGA.timing({
          category: "Paint",
          variable: entry.name,
          value: entry.startTime
     })
  })
}

var observer = new PerformanceObserver(callback);
observer.observe({entryTypes: ['paint'] })

The entries will look like this

条目将如下所示

It is entirely possible that both these metrics are exactly the same, down to the millisecond. Even if they are not the same there can be an irrelevant difference between them. For this reason another more flexible metric is used, called:

这两个指标完全可能完全相同,直到毫秒。 即使它们不相同,它们之间也可能没有关系。 因此,使用了另一个更灵活的指标,称为:

First Meaningful Paint: When something “meaningful” is painted to the screen. “meaningful” is kept intentionally vague, allowing the developer to decide themselves what they want to test for.  

第一个有意义的绘画 :当“有意义”的东西绘制到屏幕上时。 “有意义的”会故意模糊不清,使开发人员可以自行决定要测试的内容。

According to Google, the First Paint and First Contentful paint answer the question of “Is it happening” and First Meaningful Paint answers “Is it useful”. “Is it useable” is answered by Time to Interactive.

根据Google的说法,First Paint和First Contentful绘画回答了“它正在发生”的问题,First Meanfulful Paint回答了“有用吗”。 《互动时间》回答“是否有用”。

A common way to use First Meaningful paint is to test for the hero element. Which is the main element on the page.

使用“第一有意义”绘画的一种常见方法是测试英雄元素。 这是页面上的主要元素。

An example for youtube would be the video player. Suggested videos and comments would all then be non hero secondary elements. Tracking when the video player has finished painting would be the First Meaningful Paint in this case.

youtube的一个示例是视频播放器。 建议的视频和评论将全部成为非英雄的次要元素。 在这种情况下,跟踪视频播放器完成绘画的时间将是“第一笔有意义的绘画”。

A common hero element on the homepage is a background image near the header that gives the value proposition or theme of the website. Knowing this, we can use the resource timing api to measure when our image has finished loading and make this our First Meaningful paint metric.

主页上常见的英雄元素是标题附近的背景图片,该图片提供了网站的价值主张或主题。 知道了这一点,我们可以使用资源计时api来衡量图像何时完成加载,并将其作为“第一有意义绘画”度量标准。

If your hero element is an image then you can simply look at the resource timing API and then look at responseEnd property and use that as your FMP.

如果英雄元素是图像,则只需查看资源计时API,然后查看responseEnd属性并将其用作FMP。

...
const callback = list => {
    list.getEntries().forEach(entry => {
        ReactGA.timing({
          category: "First Meaningful Paint",
          variable: entry.name,
          value: entry.responseEnd
        })
  })
}

var observer = new PerformanceObserver(callback);
observer.observe({entryTypes: ['resource'] })
...

Entire resource timing response.

整个资源计时响应。

Since the loaded image doesn't technically mean its painted you can also try to set the marks manually.

由于加载的图像从技术上讲并不意味着已绘制,因此您也可以尝试手动设置标记。

//jsx 

{performance.mark('start') 
<img />
{performance.mark('end')
{performance.measure('diff', 'start', 'end')

Again there is a lot of flexibility in this metric, really consider your use case and what your trying to measure.

同样,此度量标准具有很大的灵活性,请真正考虑您的用例以及您要测量的内容。

跟踪滚动 (Track Scroll)

Tracking the scroll position of your user is a fairly important part of analytics. You can for example see how many users scrolled past a certain image or section of text. Having this information you can then tweak your content and increase your conversion.

跟踪用户的滚动位置是分析中相当重要的一部分。 例如,您可以查看有多少用户滚动过某个图像或一段文字。 有了这些信息,您就可以调整内容并提高转换率。

You would have seen older implementations use getBoundingClientRect() but this would tie up the main thread and therefore tracking the scroll would actually decrease performance. You can execute the scroll events asynchronously with IntersectionObserver.  

您将看到较早的实现使用getBoundingClientRect(),但这会占用主线程,因此跟踪滚动实际上会降低性能。 您可以使用IntersectionObserver异步执行滚动事件。

The IntersectionObserver is different than the PerformanceObserver we have been working with in the last sections.

IntersectionObserver与我们在上一节中使用过的PerformanceObserver不同。

The IntersectionObserver takes 2 arguments a callback and a options object. The options object will have 3 properties

IntersectionObserver接受两个参数:回调和选项对象。 选项对象将具有3个属性

root: The element you are trying to test the intersection against. In most cases this will be the viewport which will be the value of null.

root :您要测试相交的元素。 在大多数情况下,这将是视口,其值为null

rootMargin: The margins around the root element. ex: "10px"

rootMargin :根元素周围的边距。 例如:“ 10px”

threshold: How much of the element is visible before isIntersecting is true. ex: 0.5 means isIntersecting  is true when 50% of the element is visible. 0 means the very top of the element and 1.0 means the entire element.

threshold :在isIntersecting为true之前,可见多少元素。 例如:0.5表示当50%的元素可见时isIntersecting为true。 0表示元素的最上层,1.0表示整个元素。

The entry will return an object like so:

该条目将返回一个对象,如下所示:

isIntersecting:  Essentially used to determine if the element is visible which would be true when the threshold is reached.

isIntersecting :本质上用于确定元素是否可见,达到阈值时为true。

And now the code:

现在的代码:

//Get the element you want to track with useRef
const intersectTarget = useRef(null)

//Use the observer inside the component you want to track scroll
  useEffect(() => {
    const opts = {
            root: null,
            rootMargin: '0px',
            threshold: 0
    }
    const callback = list => {
      list.forEach(entry => {
        if(entry.isIntersecting) {
            ReactGA.event({
              category: 'Scroll',
              action: 'Scrolled to heading 2',
              value: entry.intersectionRatio
            })
          }
       })
    }
    const observerScroll = new IntersectionObserver(callback, opts)

    observerScroll.observe(intersectTarget.current)
  }, [])

//jsx
  <h1 ref={intersectTarget}
      id="heading2"
		>
     Second Heading
  </h1>

The main idea here is to first initialize the useRef hook. Then use the ref on the element you want to track for scroll. The callback and observer will be called in the useEffect hook and the element can be passed to the .observe() method with the name of the ref and the .current property.

这里的主要思想是首先初始化useRef挂钩。 然后在要跟踪滚动的元素上使用ref。 回调和观察者将在useEffect挂钩中调用,并且可以使用ref名称和.current属性将元素传递到.observe()方法。

Note: The intersection observer will fire on the initial page load even if the element is not visible. This is normal and you will see that the isIntersecting property is false.

注意 :即使元素不可见,交集观察器也会在初始页面加载时触发。 这是正常现象,您将看到isIntersecting属性为false。

Note also: At the time of this writing there is also an isVisible property on the entry, but it does not function as its name suggests. It stays false even when the element visible. It is not documented anywhere so I cant comment on its purpose, but I would suggest using isIntersecting   property instead.  

另请注意:在撰写本文时,该条目上还有一个isVisible属性,但它并不像其名称所暗示的那样起作用。 即使元素可见,它也保持为假。 它没有记录在任何地方,所以我不能评论它的用途,但是我建议改用isIntersecting属性。

径赛项目 (Track Events)

The basic idea to tracking events is to send GA hits inside of the function call attached to an event handler. There really isn’t much more to it than that.

跟踪事件的基本思路是在附加到事件处理程序的函数调用内部发送GA匹配。 确实没有什么比这更多的了。

One thing to note is if your user is submitting a form you can specify the     transport: beacon property in your event hit, which will let you reliably send the hit even if the page is reloaded to another page. This isn't so much of an issue in a single page app like React, but if you did want to do this, just know this option is available.

需要注意的一件事是,如果用户正在提交表单,则可以在事件transport: beacon指定transport: beacon属性,即使将页面重新加载到另一个页面上,也可以使您可靠地发送匹配。 在像React这样的单页面应用程序中,这并不是什么大问题,但是如果您确实想这样做,只需知道此选项可用即可。

See the navigator beacon for more info

有关更多信息,请参见导航信标

I will show you how to track a form submit, but this pattern will work with basically any event. Again you are simply sending the hit in a function attached to the event handler.

我将向您展示如何跟踪表单提交,但是这种模式基本上适用于任何事件。 同样,您只是在附加到事件处理程序的函数中发送匹配。

...
  const handleSubmit = (event) => {
    event.preventDefault();
    ReactGA.event({
     category: 'Form',
     action: 'Form Submit',
     transport: 'beacon'
   });
    apiCall('/apicall', event.target.value)
  };
  
  ...
  
  <form onSubmit={handleSubmit}>
  ...
  </form>
  
  ...

Quick Performance Tips and Heuristics

快速性能提示和启发式

Biggest area for improvement I see for a lot of developers is to code things from scratch instead of using a library. Tree shaking reduces bloat a little bit, but there is still considerable bloat compared to coding something yourself. Which will allow you to only write the code you need.  Try to use as little libraries as possible. Instead of using a library for a few functions, try to just look at the source code of the library and try to implement those functions yourself. Also keep in mind that most libraries have to prioritize ease of use and personalization over performance.

对于许多开发人员来说,最大的改进领域是从头开始编写代码,而不是使用库。 树木摇晃可以稍微减少膨胀,但是与自己编写代码相比,膨胀仍然很大。 这将使您仅编写所需的代码。 尝试使用尽可能少的库。 不要将库用于某些功能,而应仅查看库的源代码并尝试自己实现这些功能。 还请记住,大多数库必须优先考虑易用性和个性化而不是性能。

Some other ones:

其他一些:

  • For event firing like scroll you will definitely need debouncing/throttling. You don't need to do this for observers.  

    对于像滚动这样的事件触发,您肯定需要进行反跳/限制。 您无需为观察者执行此操作。
  • Only import functions and variables you need and let tree shaking discard unused code.

    仅导入所需的函数和变量,并让摇晃的树丢弃未使用的代码。
  • Do not pass in an anonymous function to events.

    不要将匿名函数传递给事件。
  • Turn your React app into a PWA allowing users to download and install your webapp locally on their device.

    将您的React应用程序变成PWA,允许用户在其设备上本地下载和安装您的Webapp。
  • Reduce payloads with code splitting and lazy loading.

    通过代码拆分和延迟加载减少有效负载。
  • Decrease file size by using gzip or similar compression

    通过使用gzip或类似压缩来减小文件大小
  • Serve images from a CDN

    从CDN提供图像
  • Enable caching through your http headers on server responses.

    在服务器响应上启用通过HTTP标头进行缓存。
  • Optimize images. See the google fundamentals guide for a full guide on how to do so.

    优化图像。 有关如何执行此操作的完整指南,请参见Google基础知识指南。
  • Use the new CSS Flexbox for layout. Avoid Layout Thrashing

    使用新CSS Flexbox进行布局。 避免布局打乱

  • Only Use transforms and opacity for css changes. So instead of changing height and width use scale X and scaleY

    仅对CSS更改使用转换和不透明度。 因此,不要更改高度和宽度,而是使用比例尺X和scaleY

Luckily, A lot of these optimizations, like minification and gzip, are done for automatically when you run the npm build command on a React Project.

幸运的是,当您在React Project上运行npm build命令时,许多优化(如缩小和gzip)都是自动完成的。


结论 (
Conclusion)

Thanks for reading! If you found any other creative metrics or clever ways to track users, let me know in the comments.

谢谢阅读! 如果您发现任何其他创造性指标或跟踪用户的巧妙方法,请在评论中告诉我。

Follow me on twitter for more tutorials in the future: https://twitter.com/iqbal125sf

在Twitter上关注我,以获取将来的更多教程: https//twitter.com/iqbal125sf

Blog Posts:https://www.searchenginejournal.com/a-technical-seo-guide-to-lighthouse-performance-metrics/292703/#close

博客文章: https : //www.searchenginejournal.com/a-technical-seo-guide-to-lighthouse-performance-metrics/292703/#close

https://infrequently.org/2017/10/can-you-afford-it-real-world-web-performance-budgets/

https://infrequently.org/2017/10/can-you-afford-it-real-world-web-performance-budgets/

https://speedcurve.com/blog/user-timing-and-custom-metrics/

https://speedcurve.com/blog/user-timing-and-custom-metrics/

https://designsystem.digital.gov/performance/

https://designsystem.digital.gov/performance/

https://hackernoon.com/react-performance-primer-64fe623c4821

https://hackernoon.com/react-performance-primer-64fe623c4821

https://reactjs.org/docs/optimizing-performance.html

https://reactjs.org/docs/optimizing-performance.html

Observers:https://css-tricks.com/paint-timing-api/

观察者: https : //css-tricks.com/paint-timing-api/

https://css-tricks.com/breaking-performance-api/

https://css-tricks.com/breaking-performance-api/

https://hackernoon.com/tracking-element-visibility-with-react-and-the-intersection-observer-api-7dfaf3a47218

https://hackernoon.com/tracking-element-visibility-with-react-and-the-intersection-observer-api-7dfaf3a47218

https://www.smashingmagazine.com/2018/01/deferring-lazy-loading-intersection-observer-api/

https://www.smashingmagazine.com/2018/01/deferring-lazy-loading-intersection-observer-api/

https://www.sitepen.com/blog/improving-performance-with-the-paint-timing-api/

https://www.sitepen.com/blog/improving-performance-with-the-paint-timing-api/

Google Based:https://developers.google.com/web/fundamentals/performance/user-centric-performance-metrics

基于Google: https //developers.google.com/web/fundamentals/performance/user-centric-performance-metrics

https://developers.google.com/web/fundamentals/performance/navigation-and-resource-timing/

https://developers.google.com/web/fundamentals/performance/navigation-and-resource-timing/

https://developers.google.com/web/tools/chrome-devtools/speed/get-started

https://developers.google.com/web/tools/chrome-devtools/speed/get-started

https://marketingplatform.google.com/about/optimize/

https://marketingplatform.google.com/about/optimize/

https://developers.google.com/analytics/devguides/collection/analyticsjs/user-timings

https://developers.google.com/analytics/devguides/collection/analyticsjs/user-timings

https://support.google.com/analytics/answer/1033068#Anatomy

https://support.google.com/analytics/answer/1033068#Anatomy

https://developers.google.com/analytics/devguides/collection/analyticsjs/single-page-applications

https://developers.google.com/analytics/devguides/collection/analyticsjs/single-page-applications

https://support.google.com/analytics/answer/1033068

https://support.google.com/analytics/answer/1033068

https://docs.google.com/document/d/1GGiI9-7KeY3TPqS3YT271upUVimo-XiL5mwWorDUD4c/preview#

https://docs.google.com/document/d/1GGiI9-7KeY3TPqS3YT271upUVimo-XiL5mwWorDUD4c/preview#

https://www.doubleclickbygoogle.com/articles/mobile-speed-matters/

https://www.doubleclickbygoogle.com/articles/mobile-speed-matters/

翻译自: https://www.freecodecamp.org/news/performance-and-user-tracking-in-react-with-google-analytics/

react with

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值