模板户:专注于dede模板,织梦源码,织梦模板,网站模板,dedecms模板,网站源码,dedecms教程以及各类手机网站模板和企业网站模板分享.

织梦模板

VIP

CMS教程

站长学院

随机织梦教程

最新织梦教程

织梦模板随机Tags

关键词排名 原创 用户体验 玩具外贸网站源码 关键词优化 搜索引擎 汽车配件织梦模板 网站title 太阳能光伏网站源码 网站 财务会计网站源码 餐饮管理织梦模板 餐饮加盟网站源码 关键词 汽车润滑油网站源码 蜘蛛 优化 织梦伪静态 高亮 个人网站

GA跟踪代码在网站上的设置和优化

www.mobanhu.com / 2018-12-13 08:10:40
老陈 地球上的叶子

Google Analytics is a powerful yet quite complicated tool. And unfortunately, the truth is most people who use it don’t reap its full benefits.

GA是一个强大的而且非常复杂的工具,很不幸,真相是很多使用它的人并不知道如何使用这个工具获利

There’s a lot of excellent and free content out there that explains how to use Google Analytics, but most of it is rather narrowly focused on use cases that primarily apply to marketers and advertisers; very little is geared toward web developers who simply want to better understand how people are using the sites they build.

现在有很多免费文章解读如何使用GA,但是大部分内容只是聚焦于使用案例,面向营销人员和广告投放人员,很少有针对网站开发人员,帮助他们更好的理解用户是如何查看用户在他们开发的网站上面的行为

For the past three years I’ve worked on Google Analytics (specifically on the web tracking side), and in that time I’ve learned far more than I ever thought I would. I’ve been able to dive deep into some of GA’s amazing features, and I’ve also run up against some of its annoying shortcomings.

过去三年,我的工作内容就是GA(主要是web tracking side),在那段时间我学到的比我以前想当然的多得多,我可以深入研究GA令人惊叹的功能,我已经提升了很多高级应用以拟补GA本身的默认功能的不足

This article is sort of a culmination of everything I’ve learned over the past three years, and it’s aimed specifically at web developers. Since this article is a bit on the long side, I’ve broken it up into several distinct topics, so you can read it in parts and more easily reference something later.

本文是我过去三年学到的所有内容的精华,它专门针对Web开发人员。 由于本文有点偏颇,我将其分解为几个不同的主题,因此您可以将其分成几部分阅读,以后更容易引用。

 

  • Loading analytics.js

  • Tracking custom data

  • Error tracking

  • Performance tracking

  • Using autotrack plugins

  • Testing your implementation

  • Filtering out local/spam data

  • Reporting and visualizing your data

I’ve also created the analyticsjs-boilerplate repo on Github as a complement to this article. It includes all the code I mention here as well as a working example showing how all the pieces fit together. If you’re one of the many web developers out there who just copy/pastes the default tracking snippet and calls it a day, I highly recommend using this boilerplate instead.

我也在github创建了analyticsjs-公式模板作为本文的补充,它包含了我在这里提到的所有的代码,同时还有一个可以运行的例子,给你展示如何把一块块的代码整合起来,如果你是很多开发人员中的一位,只会每天copy/pasted  调用default tracking snippet,我强烈推荐你是用我提到的样板

Loading analytics.js

In my opinion, it’s never acceptable for analytics to degrade the user experience of a site. In other words, tracking scripts should always be loaded asynchronously (this includes libraries like analytics.js as well as your own tracking code), and the data you send to analytics services should never interfere with other network requests needed for your site.

我的见解,如果Analytics的加载降低了网站的用户体验是不可接受的,换句话说,跟踪代码应该是异步加载的(包括一些libraries比如analytics.js,和你自己的跟踪代码),同时,当你发送这些数据到analytics server的时候,永远不能干扰其他用户访问你网站的需要

The async tracking snippet is the current, officially recommended way to load analytics.js on modern websites, and for the most part it works great. The goal of this snippet is to ensure analytics.js is loaded as soon as possible but also asynchronously so it doesn’t block the loading of other critical resources.

The async tracking snippet是当前官方推荐的加载analytics.js到现代网站的方式,很多时候它可以运行得很好,这个代码片段的目的是确保analytics.js以异步加载的方式尽快加载到你的网站,它不会锁定、占用网站其他关键资源的加载

While the current tracking snippet is good, it can definitely be better. One problem with the async tracking snippet is, by default, it will still create two HTTP requests (one for the analytics.js script and one to send the initial pageview) that will push back the load event, which will affect other load-based metrics and potentially delay code scheduled to run after the window loads.

尽管现在的tracking snippet很好,但是他还可以定义的更好一些,有一个关于异步加载的问题就是:

默认情况下,它还是会创建2个http 请求(一个给analytics.js,另一个用于发送初始的pageview),这样仍然会阻碍 load event,这将影响其他基于加载的指标比如页面加载延迟,并可能延迟必须再窗口加载后才可以运行的代码计划。

There are two ways to solve this problem, the first is to wait until after the loadevent fires to run the tracking code, but this is undesirable since it will potentially result in missed pageviews from users who bounce early.

有两种方式可以解决这个问题,第一个方法:就是等页面所有的load event都执行完了,再运行跟踪代码,但是这种方式不受推崇,因为它很可能导致如果由于用户过早的跳出率一些pageviews没有统计到

The second option is to use the beacon transport mechanism to send all hits, which uses navigator.sendBeacon() under the hood. Since hits sent with sendBeacon()don’t affect loading (or unloading) of the current page, it has the best of both worlds.

第二种方式就是使用 beacon transport mechanism来发送所有的hit,在内部它调用navigator.sendBeacon() ,因为hits的发送是用sendBeacon(),不会影响当前页面的加载,这方式对双方(网页加载和跟踪)是最好的选择

Here’s what the modified snippet looks like when using the beacon transport mechanism. Note the addition of the set command specifying transport, beacon, which tells the tracker to use navigator.sendBeacon() for all subsequent hits:

下图是如果你使用beacon transport 机制编辑代码过后的snippet看起来的样子,请注意附加的代码set指令与transport和beacon结合,这个是为了告诉tracker使用navigator.sendBeacon()为随之而来的所有hits进行数据发送

<script>window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};
ga(create, UA-XXXXX-Y, auto);ga(set, transport, beacon);ga(send, pageview);</script><script async src="https://www.google-analytics.com/analytics.js"></script>

Putting your tracking code in a separate file

将跟踪代码放在一个独立的文件

The default tracking snippet instructions recommend adding the snippet code to the <head> of all pages on your site. If you’re just using the snippet as is, that’s probably fine, but as we add more code to track additional user interactions (which we will throughout this post), keeping all that code in the <head> is a bad idea.

默认的跟踪代码介绍,推荐把代码片段加到网站所有页面的<head>之间,如果你只是这样用,也可以,但是如果我们需要添加更多的代码跟踪用户interaction(这个话题我们将贯穿本文),把代码放在<head>是bad idea

I prefer to put all my analytics-related code in a separate file that I load asynchronously after my other site code has finished loading.
我更喜欢把与跟踪相关的所有代码放在一个独立的文件,等到我的网站的其他代码都加载完了,再用异步加载的方式加载这个代码文件

If you use a build tool that supports code splitting (like Webpack), you can lazily initialize your tracking code from your script’s main entry point like this:

如果你喜欢一个开发工具支持代码分离(比如webpack),你可以从你代码的注入口比如下图慢吞吞地初始化跟踪代码。

// index.jsconst main = () => {  // Load custom tracking code lazily, so its non-blocking.
  import(./analytics/base.js).then((analytics) => analytics.init());// Initiate all other code paths here...};// Start the app through its main entry point.main();

Your custom tracking code will then live in its own module and can be initialized via its exported init() function:

你定制的跟踪代码,会在它的own module保持有效,可以通过导出的init这个函数初始化。

// analytics/base.jsexport const init = () => {  // Initialize the command queue in case analytics.js hasnt loaded yet.
  window.ga = window.ga || ((...args) => (ga.q = ga.q || []).push(args));

  ga(create, UA-XXXXX-Y, auto);
  ga(set, transport, beacon);
  ga(send, pageview);
};

Now your template files only includes the <script async> tag to load analytics.js as well as your site’s regular JavaScript code:

现在你的模板文件只是包含了 <script async>代码用于同时加载analytics和你网站的正则表达式js代码

<!-- Loads the sites main script --><script src="path/to/index.js"></script><!-- Loads analytics.js asynchronously --><script async src="https://www.google-analytics.com/analytics.js"></script>

Note that if you’re not using a build system with code splitting features, you can get the same effect by compiling your tracking code separately and loading it via <script async> just like you do with analytics.js.[1] Also note that you don’t have to worry about load order; analytics.js is specifically designed to handle cases where it loads first, last, or not at all (e.g. in cases where its blocked by an extension):

请注意,如果你没有使用代码分离功能的 build system,你可以得到相同的效果:通过单独编译你的tracking code,以<script async>的形式加载,就像你加载analytics.js.一样

<!-- Loads the sites main script --><script src="path/to/index.js"></script><!-- Loads analytics.js and custom tracking code asynchronously --><script async src="https://www.google-analytics.com/analytics.js"></script><script async src="/path/to/tracking-code-bundle.js"></script>

Tracking custom data

A dimension in Google Analytics is a way to subdivide your usage data into categories. For example, some built-in dimensions available to you in reports are BrowserDevice CategoryLanguagePage, etc.

GA的维度是细分数据的一种方式,举个例子,部分内置的dimensions比如浏览器,设备分类,语言,页面,等等,你都可以在report看到

While the built-in dimensions are great, there are many dimensions that would be incredibly useful that are not tracked by analytics.js. Luckily, Google Analytics has a feature called custom dimensions, so you can implement and track whatever dimensions you want.

虽然内置的维度功能很强大,还有很多有意义的维度,ayalytics.js没有跟踪到,幸运的是,GA有一个功能叫做自定义维度,所以你也可以跟踪你想要跟踪的。

In the rest of this section I’ll list the custom dimensions I track on every site and explain why I use them.

文章的其他部分,我会列出每个网站我跟踪的自定义维度,并说明我为什么用这些自定义维度。

Tracking Version

Any time you make changes to software it’s important to version your changes so you can isolate a specific feature set to a specific version number. This is as true with analytics implementations as it is with anything else.

任何时候,当你修改你的代码,很重要的一点,你要给每个版本一个版本号,这样,你可以区分每个版本特定的功能, 不管对分析实现而言,或者其他任何事情都是一样的。

If you update your analytics implementation to start tracking a bunch of new dimensions, or if you change the format of the data you’re collecting (for whatever reason), you probably only want to report on data from the subset of users who are running your latest changes.

如果你更新了analytics implementation,开始增加了一堆新的维度,或者你修改了你收据的数据格式,不管什么理由,你可能只想你的报告体现的数据,是运行最新更改的用户子集中的数据。

The easiest way to do this in Google Analytics is to create a custom dimensioncalled Tracking Version, and set its scope to “Hit” (since it will apply to all hits).

最早的方式,是在GA里面增加一个自定义维度跟踪版本,设置它的scope to hit

In analytics.js you refer to a custom dimension by its index, but I think that gets confusing pretty quickly after you’ve created a few custom dimensions (which we will), so I always create an object that maps custom dimension names to their index.

在GA,你用index的值定位一个custom dimension,但是我想,当你创建了一些自定义维度之后,index很快就会显得混乱,我们确实也会这么做,所以我会创建一个object用于映射自定义维度的dimension name和他们的index

const dimensions = {  TRACKING_VERSION: dimension1,
};

Now, if you set this custom dimension value on the tracker, it will send that value with all future hits. If this is your first tracking version, set it to 1.

现在,如果你在tracker上面给这个自定义维度设置了一个值,它会在今后所有的hits都发送这个数据,如果这是你的第一个跟踪版本,设置1

const TRACKING_VERSION = 1;ga(create, UA-XXXXX-Y, auto);
ga(set, transport, beacon);ga(set, dimensions.TRACKING_VERSION, TRACKING_VERSION);ga(send, pageview);

With this new dimension, any time you make a breaking change to your tracking implementation you can increment the version number. Then, at reporting time, you can segment your reports to only include sessions from users where the first hit contains the matching tracking version.

使用这个新的维度,任何时候你修改了跟踪代码,你可以累加这个版本号,1,2,3,4.查看报告的时候,你可以这样细分你的报告,只包含这些session:他们的第一个hit是当你更新这个跟踪版本之后

Here’s what the segment definition I use looks like (as you can see, I’m on version 13):

下面是我定义的segment definition,你看到的,我的版本号是13

A segment definition to only include sessions for the current tracking version

Client ID

Google Analytics uses a client ID to associate individual hits with a particular user. Unless you’ve customized your setup, analytics.js automatically generates this value for you, stores it in the browser’s cookies, and sends it with all hits.

GA使用client id用于联系真实的hit+针对某个特定的用户,除非你定制你的setup,否则analytics会自动帮你生成这个数值,保存在浏览器的cookies,然后与所有的hit一起发送到GA的服务器

Google Analytics uses this client ID internally, but doesn’t make it available to you in reports.

GA在其内部使用这个client id,你在report上是看不到的

Luckily, (as you’ve probably guessed) you can work around this limitation by creating a custom dimension called Client ID, setting its scope to “User”, and assigning it the same value as the native client ID created by analytics.js.

幸运的是,你或许也猜到了,你可以围绕这个限制,通过创建一个自定义维度命名为client id,设置它的scope为 user,像analytics.js创建原始值的client id为他分配数值。

To understand why this is useful, consider the following scenario: let’s say you notice some click events in your reports on a page where the button being clicked isn’t supposed to be visible. So you ask yourself: how is it possible my site got into this broken state?

要明白这个id的用途,考虑以下情况,我们假设你注意在你的报告页面上有的一些点击事件,本来这些按钮的点击是不可见的,那么你可以自问,我的网站代码怎么坏了

With access to the Client ID dimension, you can debug this problem by picking any of the users who got into that bad state and then creating a report to see only the interactions of that user (by filtering to only include hits matching that user’s client ID).

通过访问这个client id的维度,你通过这样调试这个问题:选择某个进入这批区域的的用户,创建一个报告纸查看这个用户的所有交互。

Without this Client ID dimension you can only report on users in aggregate, which has obvious limitations.

如果没有这个client id的维度,你只能看到user的聚合数据,这个有很大的缺陷

To get the client ID value created by analytics.js in your tracking code, you invoke the get() method to read the value stored on the tracker. Then you can invoke the set() method to assign that value to your newly created custom dimension:

要通过你跟踪代码里的analytics.js创建这个cliend id的值,你可以截止get()方法读取存储在tracker里面的值,然后你可以借助set方法将这个值分配到你最近创建的新的自定义维度

const dimensions = {  TRACKING_VERSION: dimension1,CLIENT_ID: dimension2,};// ...ga((tracker) => {  var clientId = tracker.get(clientId);tracker.set(dimensions.CLIENT_ID, clientId);});

This code works by passing a function to the ga() command queue, which will be invoked with the default tracker object as soon as analytics.js is loaded.

这个代码的工作原理是这样的,通过传递一个函数到ga()command 队列,只要加载analytics.js,就会使用默认跟踪器对象调用该队列。

Window ID

Sometimes users interact with your site with more than one window or tab open at a time. Google Analytics doesn’t currently collect window/tab-specific data, but you can if you create another custom dimension called Window ID, set its scope to “Hit”, and assign it a random value at page load time. That way every hit sent from the current window context can be later associated with that window context through the Window ID dimension.

有时候,用户跟你网站的交互同一时候超过多个窗口或者多个tab,GA不会立即收集window/tab特定的数据,但是你可以通过创建一个叫windows id的 自定义维度,设置它的scope为hit,在页面加载期间赋予一个随机值,这样,从当前窗口上下文发送的每个hit可以稍后通过窗口ID维度相关联。

This is particularly useful for single page apps where a user can have many pageviews without ever doing a full page reload.

这对于单页应用程序特别有用,在这些应用程序里,一个用户可以浏览很多页面,而无需进行完整页面重新加载

To create a unique value, you’ll have to include a function to generate it. I like this uuid() function because it’s very short, but you can use whatever function you like:

要创建唯一值,您必须包含一个函数来生成它。 我喜欢这个uuid()函数,因为它很短,但你可以使用你喜欢的任何函数:

const uuid = function b(a) {  return a ? (a ^ Math.random() * 16 >> a / 4).toString(16) :
      ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, b);
};

Then set the Window ID value on your tracker object before you send any data to Google Analytics:

const dimensions = {  TRACKING_VERSION: dimension1,  CLIENT_ID: dimension2,WINDOW_ID: dimension3,};export const init = () => {  // ...
  ga(set, dimensions.WINDOW_ID, uuid());// ...};

Hit ID, time, and type

The Google Analytics interface lets you easily report on aggregate data, but if you want to get access to individual user, session, or hit-level data, you’re mostly out of luck.

GA的接口让你很容易查看聚合数据,但是如果你想查看真实用户,session,或者hit 级别的数据,大部分时候不走运,看不到

There is a feature called BigQuery Export that allows you to export all your data (which gives you hit-level granularity), but it’s only available to premium customers, so the vast majority of users won’t have access to it.

有一个功能叫做big query export允许你把所有的数据都导出来,(提供给你的是hit 级别颗粒度的数据,),但是这个功能仅限于GA的付费用户,所以大多数的用户是无法访问这个功能

Luckily, with a few more custom dimensions you can get most of the way there. The trick is to add unique, hit-specific metadata to every hit that gets sent to Google. Then, at reporting time, you just specify these hit-level dimensions and voila! You can isolate individual hits in your reports.

幸运的是,通过一些附加的自定义维度,你可以达到大部分目的,这个计谋是为每个hit增加唯一的,hit级别的meta data然后发送到GOOGLE,查看报告的时候,你只需要选择这些hit级别的维度,瞧,你可以在报告里看到单独的真实的hit

I mentioned previously that tracking Client ID via a custom dimension is immensely useful when debugging unexpected user-interaction data. These hit-level custom dimensions make that even easier as they allow you to drill down into individual user interactions (anonymously of course), and see everything these users are doing, when, and in what order they’re doing it. Ultimately allowing you to make your site better for everyone.

上面我提到,跟踪client id赋予一个自定义维度是很有意义的,当你调试意外的用户交互数据的时候,这些hit 级别的额自定义维度让分析变得更容易,因为他们允许你深入到真会的用户交互,查看这些用户做了什么,什么时候,在哪个订单他们做了什么,总的来说,你可以让你的网站对用户变得更好

To track the Hit IDHit Time, and Hit Type custom dimensions, first create them in Google Analytics and set their scope to “Hit”. Then, in your tracking code, override the buildHitTask and set these values on the model, thus ensuring they’re applied to every hit:

要跟踪hit id,hit time,hit类型,首先要在GA创建他们的scope to hit,接着,在你的跟踪代码,覆盖buildHitTask,在这个模型上设置这些自定义维度的value,这样确保他们可以应用到every hit

const dimensions = {  // ...
  HIT_ID: dimension4,HIT_TIME: dimension5,HIT_TYPE: dimension6,};export const init = () => {  // ...
  ga((tracker) => {    const originalBuildHitTask = tracker.get(buildHitTask);
    tracker.set(buildHitTask, (model) => {model.set(dimensions.HIT_ID, uuid(), true);model.set(dimensions.HIT_TIME, String(+new Date), true);model.set(dimensions.HIT_TYPE, model.get(hitType), true);originalBuildHitTask(model);
    });
  });  // ...};

The Hit ID dimension is set to the result of calling our uuid() function (like we did with Window ID), the Hit Time dimension is set to the current timestamp, and the Hit Type dimension is set to the value already stored on the tracker (which, like with client ID, is tracked by GA but not made available in reports):

HIT ID维度值是来自于调用 uuid()的执行结果,就像我们处理window id一样,HIT time 维度的时间当前时间,hit type使用已经存储在跟踪器对象的值(就像client id,是GA可以跟踪的,但是在report里面是看不到的)

Error tracking

Do you know for sure if your code is running as intended (and without error) for every user who visits your site? Even if you do comprehensive cross-browser/device testing prior to releasing your code, there’s still the possibility that something went wrong or that some browser/device combination you didn’t test will fail.
你知道如何确保你的跟踪代码按照你的想法没有错误的运行以跟踪访问你网站的每个用户,即使你结合了跨设备跨浏览器测试之后,发布你的代码,还是有可能存在一个错误或者某些跨设备跨浏览器的综合运行你没有测试到

There are paid services like Track:js and Rollbar that do this for you, but you can get a lot of the way there for free with just Google Analytics.

有一些付费服务比如 Track:js 和 Rollbar可以帮你做这个事情,但是你可以获得很多免费的方式仅仅对GA

I track unhandled errors by adding a global error event listener as the very first <script> in the <head> of the page. It’s important to add this first, so it catches all errors:

我通过在页面<head>中的第一个<script>来添加全局错误事件侦听器,来跟踪未处理的错误。 第一步一定要添加它,这很重要的,因此它可以捕获所有错误:

<script>addEventListener(error, window.__e=function f(e){f.q=f.q||[];f.q.push(e)});</script>

This code stores any unhandled errors in an array on the listener function itself. Then, once the rest of the analytics code has loaded, you can report on these errors with the following functions:

此代码将任何未处理的错误存储在侦听器函数本身的数组中。 然后,一旦加载了其余的分析代码,您就可以使用以下函数报告这些错误的信息:

export const init = () => {  // ...
  trackErrors();// ...};export const trackError = (error, fieldsObj = {}) => {
  ga(send, event, Object.assign({    eventCategory: Script,    eventAction: error,    eventLabel: (error && error.stack) || (not set),    nonInteraction: true,
  }, fieldsObj));
};const trackErrors = () => {  const loadErrorEvents = window.__e && window.__e.q || [];  const fieldsObj = {eventAction: uncaught error};  // Replay any stored load error events.
  for (let event of loadErrorEvents) {
    trackError(event.error, fieldsObj);
  }  // Add a new listener to track event immediately.
  window.addEventListener(error, (event) => {
    trackError(event.error, fieldsObj);
  });
};

Note: the nonInteraction field is set to true to prevent this event from influencing bounce rate calculations. If you’re curious as to why this is important you should read more about non-interaction events.

注意:nonInteraction字段设置为true以防止此事件影响跳出率计算。如果您很好奇为什么这很重要,那么您应该阅读有关非交互事件的更多信息

The above logic loops through each stored error on the error event listener and reports it. It then adds a new listener to immediately send uncaught errors to Google Analytics as they occur.

上面的逻辑循环遍历错误事件侦听器上的每个存储错误并报告它。然后,它会添加一个新的侦听器,以便在发生时立即将未捕获的错误发送给Google Analytics。

Note: you can use a similar strategy to track unhandled Promise rejections via the unhandledrejection event, but that gets a bit more complicated since a Promise rejection can be initially unhandled but then handled later. For simplicity, it’s not included it in this post, but you’ll probably want to add it to your error tracking implementation if you want full coverage.

注意:您可以使用类似的策略通过(unhandledrejection未处理的拒绝)事件跟踪未处理的Promise rejections,但由于Promise拒绝最初可能未处理但稍后处理,因此会更复杂一些。为简单起见,它不包含在这篇文章中,但如果您想要全面覆盖,您可能希望将其添加到错误跟踪实现中。

Exception hits vs events

Experienced Google Analytics users might be wondering why I’m sending these errors as event hits rather than exception hits (a feature which was added to Google Analytics specifically for this purpose).

经验丰富的Google Analytics用户可能会想知道为什么我将这些错误作为事件点击,而非异常点击发送(专门为此目的,已经有一个功能被添加到Google Analytics中)。

The simple reason is that exceptions hits do not show up in the Real Time reportand event hits do. It’s a shame because, of all the hit types that you’d want to know about in real time, exception hits are clearly at the top of that list.

原因很简单,exceptions hit不会出现在实时报告,而event hit会。 这是一种耻辱,因为在您想要实时了解的所有hit type,exception hits本来应该是位于该列表的顶部(但是没有)。

Performance Tracking

Several years ago Google Analytics introduced Site Speed tracking, allowing you to report on most of the metrics in the Navigation Timing API. This was a great initial step, but unfortunately (as with the exception hit type) it has too many limitations to be useful. If you really care about these metrics, you’ll probably want to track them yourself.

几年前,Google Analytics(分析)引入了网站速度跟踪功能,允许您报告Navigation Timing API中的大多数metric。 这是一个很好的初始步骤,但不幸的是(与 exception hit 类型一样)它有太多限制才有用。 如果您真的很在意要查看这些指标,您可能需要自己跟踪它们。

The Site Speed feature works because analytics.js automatically sends a timing hiton page load for 1% of your users. The problem is 1% is not a particularly representative sample for most sites, and there’s no way to increase this limit because the sampling is enforced on both the client and the server at processing time.

网站速度功能有效,因为analytics.js会自动为1%的用户发送定时页面加载。 问题是1%对于大多数站点来说不是特别有代表性的样本,并且没有办法突破此限制,因为在处理时需要同时在客户端和服务器上强制执行采样。

The other problem is timing hits aren’t available in segments, which means you can’t run a report—for example—that only includes users whose pageload took longer than 10 seconds.

另一个问题是时间点击在segments中不可用,这意味着您查看这样的运行报告 – 例如 – 仅包含页面加载时间超过10秒的用户。

Custom metrics (similar to custom dimensions) do not have either of these limitations, so that’s what I use to do all my performance tracking.

自定义指标(类似于自定义维度)没有这些限制,因此我用来执行所有性能跟踪。

Custom performance metrics

To see how to track performance via custom metrics, consider three of the more commonly referenced performance metrics from the Navigation Timing API that can be used to measure the critical rendering path:

要了解如何通过自定义指标跟踪效果,请考虑导航计时API中可用于衡量关键呈现路径的三个更常见的性能指标:

  • responseEnd: the point when the server finishes delivering the response to the browser.

  • domContentLoadedEventStart: when all the page’s content is processed and loaded in the DOM, and the browser can start rendering the page.

  • loadEventStart: when all the page’s initial resources are loaded.

  • responseEnd:服务器完成向浏览器提交响应的时间点。
    domContentLoadedEventStart:当在DOM中处理并加载所有页面内容时,浏览器可以开始呈现页面。
    loadEventStart:加载所有页面的初始资源时。
    在Google Analytics中创建上述三个自定义指标(并将其范围设置为“点击”并将其格式类型设置为“整数”)后,您可以使用此代码来跟踪它们:

Once you’ve created the above three custom metrics in Google Analytics (and set their scope to “Hit” and their formatting type to “Integer”), you can use this code to track them:

const metrics = {  RESPONSE_END_TIME: metric1,  DOM_LOAD_TIME: metric2,  WINDOW_LOAD_TIME: metric3,
};export const init = () => {  // …
  sendNavigationTimingMetrics();
}const sendNavigationTimingMetrics = () => {  // Only track performance in supporting browsers.
  if (!(window.performance && window.performance.timing)) return;  // If the window hasnt loaded, run this function after the `load` event.
  if (document.readyState != complete) {    window.addEventListener(load, sendNavigationTimingMetrics);    return;
  }  const nt = performance.timing;  const navStart = nt.navigationStart;  const responseEnd = Math.round(nt.responseEnd - navStart);  const domLoaded = Math.round(nt.domContentLoadedEventStart - navStart);  const windowLoaded = Math.round(nt.loadEventStart - navStart);  // In some edge cases browsers return very obviously incorrect NT values,
  // e.g. 0, negative, or future times. This validates values before sending.
  const allValuesAreValid = (...values) => {    return values.every((value) => value > 0 && value < 1e6);
  };  if (allValuesAreValid(responseEnd, domLoaded, windowLoaded)) {
    ga(send, event, {      eventCategory: Navigation Timing,      eventAction: track,      nonInteraction: true,
      [metrics.RESPONSE_END_TIME]: responseEnd,
      [metrics.DOM_LOAD_TIME]: domLoaded,
      [metrics.WINDOW_LOAD_TIME]: windowLoaded,
    });
  }
};

Now you can get the average load time values by dividing the totals for Response End Time,DOM Load Time, and Window Load Time by the metric Total Events.

现在,您可以通过将响应结束时间,DOM加载时间和窗口加载时间的总和除以度量标准总事件来获取平均加载时间值。

Median vs. average

I’m sure many of you read that last sentence and thought: I don’t want to know the average, I want to know the median!

我相信很多人读到最后一句话并且想:我不想知道平均值,我想知道中位数!

Not having median values is a common criticism of Google Analytics, and for good reason. But if you’ve implemented the hit-level custom dimensions I suggested above, you’ll be able to calculate median values yourself because you’ll have hit-level granularity. More on this in the reporting section below.

没有中位数值是谷歌分析的人们经常批评的疑点,并且有充分的批判理由。但是如果你已经实现了我上面提到的命中级别自定义维度,那么你将能够自己计算中值,因为你将拥有命中级别的粒度。有关详情,请参阅下面的报告部分。

Using autotrack plugins

I’m obviously a bit biased here since I created the autotrack library, but it’s probably worth pointing out that the main reason I did is because I found myself reimplementing the same features, over and over again, on every site I built.

自从我创建自动跟踪库以来,我显然有点偏颇,但我可能值得指出,我做的主要原因是因为,我发现自己在我建立的每个网站上,反复重复实现相同的功能。所以需要把重复的事情提取出来做一个library

Since I was doing this, I knew others probably were too, and it seemed crazy to me that there wasn’t a more official way to track the things that basically everyone wants to track.

由于我这样做,我知道其他人可能也是这样,而且对我来说似乎很疯狂,没有更正式的方式来跟踪基本上每个人都想跟踪的事情。

I won’t go into too much detail here because you can read all about what these plugins do in the autotrack documentation, but I wanted to briefly mention the plugins I use on pretty much every site:

我不会在这里详细介绍,因为您可以在autotrack文档中阅读所有这些插件的内容,但我想简要提一下我在几乎所有网站上使用的插件:

outboundLinkTracker

A must have since Google Analytics doesn’t track navigations to external domains.

必须拥有的理由:因为Google Analytics不会跟踪外部域的导航。

cleanUrlTracker

Hate seeing a bunch of marketing params in the URLs of your page reports? Yeah, me too. This plugin solves that problem in a developer-friendly way (as opposed to having to use view filters).

讨厌在页面报告的URL中看到一堆营销参数? 我也是。 这个插件以开发人员友好的方式解决了这个问题(而不是必须使用视图过滤器)。

maxScrollTracker

Tracking how far down the page a user scrolls is actually a fairly complex problem. It’s also pretty easy to accidently cripple your user’s scroll experience when not done right. This plugin handles all of these complications for you.

跟踪用户滚动页面的距离实际上是一个相当复杂的问题。 如果做得不对,很容易意外地削弱用户的滚动体验。 这个插件为您处理所有这些复杂情况。

pageVisibilityTracker

Session duration in Google Analytics is actually a very broken metric. It doesn’t track the time spent on the final page of a session (meaning single-page visits have a session duration of 0), and it doesn’t account for time when the page was open but in a background tab. Using page visibility is a much better and more accurate way of tracking how long a user was active on your site.

Google Analytics中的会话持续时间实际上是一个非常破碎的指标。 它不跟踪在会话的最后一页上花费的时间(意味着单页访问的会话持续时间为0),并且它不考虑这些页面页面打开时间(但是用户很快就切换tab)。 使用网页可见性是一种更好,更准确的方式,可以跟踪用户在您网站上的有效期。

urlChangeTracker

Obviously not every site is a single page application. But if yours is, it’s far easier to include this plugin than it is to try to track dynamic pageviews manually.

显然不是每个站点都是单页面应用程序。 但是,如果是,那么包含此插件比尝试手动跟踪动态网页浏览要容易得多。

Testing your implementation

When creating autotrack, I did a ton of experimentation and testing on these plugins before releasing them publicly. Anytime you implement tracking for a new feature on your site, you run the risk of getting something wrong, and since Google Analytics doesn’t let you modify or revise your data after sending it, the price of getting it wrong can be high.

在创建自动跟踪时,我在公开发布之前对这些插件进行了大量的实验和测试。 每当您为网站上的新功能实施跟踪时,您都会冒错误的风险,而且由于Google Analytics不会让您在发送数据后修改数据,因此错误的代价可能会很高。

To deal with this, I almost always use at least two trackers on my site. One that sends data to my production property, and one that sends data to my test property.

为了解决这个问题,我几乎总是在我的网站上使用至少两个跟踪器。 一个将数据发送到我的生产属性,另一个将数据发送到我的测试属性。

My test tracker is used to send experimental data—implementations I’m testing to ensure they work as expected. I only start tracking a feature with my production tracker once I’m confident its correct.

我的测试跟踪器用于发送我正在测试的实验数据实现,以确保它们按预期工作。 一旦我确信它是正确的,我才开始跟踪我的生产跟踪器的功能。

I’ve included a multiple-trackers example in analyticsjs-boilerplate, but you can get the basic gist of how it works from the code below. Essentially, you give each tracker a distinct name (and tracking ID), and then you prepend all commands with the corresponding name:

我在analyticsjs-boilerplate中包含了一个多跟踪器示例,但您可以从下面的代码中获得它的工作原理的基本要点。 基本上,您为每个跟踪器指定一个不同的名称(和跟踪ID),然后使用相应的名称添加所有命令:

ga(create, UA-XXXXX-Y, auto,prod);
ga(create, UA-XXXXX-Z, auto,test);

ga(prod.send, pageview);
ga(test.send, pageview);

Filtering out local/spam data

Sometimes spammers will send fake data to your Google Analytics account to promote their shady businesses. If you don’t believe me, just search for “Google Analytics spam”, and you find plenty of people complaining the problem and suggesting fixes.

有时,垃圾邮件发送者会向您的Google Analytics帐户发送虚假数据,以宣传其糟糕的业务。如果你不相信我,只需搜索“谷歌分析垃圾邮件”,你会发现很多人抱怨这个问题并建议修复。

However, sometimes the bad data being sent is your own fault—perhaps you ran your entire test suite but forgot to disable analytics.js in your CI environment.

但是,有时发送的错误数据是您自己的错误 – 也许您运行了整个测试套件但忘记在CI环境中禁用analytics.js。

There’s a simple solution to both of these problems, and that’s to use View Filters. I use the following two filters on all my sites:

这两个问题都有一个简单的解决方案,那就是使用View Filters。我在我的所有网站上使用以下两个过滤器:

  • A hostname filter (e.g. only URL hostnames matching philipwalton.com)

  • A RegExp match filter for a custom dimension value specific to my site (e.g. Tracking Version or Hit ID)

主机名过滤器(例如,仅匹配philipwalton.com的URL主机名)
针对特定于我的网站的自定义维度值的RegExp匹配筛选器(例如,跟踪版本或命中ID)

In order for a hit to be processed by Google Analytics, it has to pass all view filters. Since hits sent while running your site locally (or on a staging server) won’t match the hostname, they won’t show up. And even if a spammer were savvy enough to send hits matching the hostname, it’s incredibly unlikely that they’d also match one of your custom dimensions.

为了让Google Analytics处理匹配,必须传递所有视图过滤器。由于在本地(或在临时服务器上)运行站点时发送的命中将与主机名不匹配,因此它们不会显示。即使垃圾邮件发送者足够精明,可以发送与主机名匹配的匹配,但他们也不太可能匹配您的自定义维度。

In my experience these two filters have been 100% effective at keeping unwanted data out.

根据我的经验,这两个过滤器在剔除不需要的数据方面100%有效。

Reporting and visualizing your data

If you’ve followed all the techniques in this post or implemented analyticsjs-boilerplate on your site, the most important piece of advice I can give you for reporting on your data is to learn these features: custom reports, calculated metrics, and the Analytics Reporting API.

报告和可视化您的数据
如果您已经按照本文中的所有技术或在您的网站上实施了analyticsjs-boilerplate,那么我可以为您提供报告数据的最重要建议是学习以下功能:自定义报告,计算指标和Google Analytics报告API。

Custom reports

The standard reports in Google Analytics are useful, but if you’ve done anything custom (e.g. created custom dimensions or custom metrics), then you need to use custom reports to access and visualize that data.

自定义报告
Google Analytics中的标准报告很有用,但如果您已完成任何自定义操作(例如创建的自定义维度或自定义指标),则需要使用自定义报告来访问和可视化该数据。

For example, in the section on tracking custom data I mentioned isolating individual users with the Client ID dimension and individual page loads with the Window ID dimension. Here’s a report listing all the pageviews (in Hit Time order) from a particular user’s first session, showing both Page and Window ID.

例如,在跟踪自定义数据的部分中,我提到使用客户端ID维度隔离单个用户,并使用Window ID维度隔离单个页面。这是一份报告,列出了特定用户第一次会话的所有综合浏览量(按生命时间顺序),同时显示了页面和窗口ID。

A Google Analytics custom report showing pageviews from a single user’s session

As you can see from the above report, this user started their session by reading an article and then navigated to the home page (in the same window). They then opened up four new articles, all in different windows. While this data isn’t particularly interesting, it should give you an idea of just how much more detail you can get by implementing the custom dimensions above.

Google Analytics自定义报告
Google Analytics自定义报告,显示来自单个用户会话的综合浏览量
从上面的报告中可以看出,该用户通过阅读文章开始了他们的会话,然后导航到主页(在同一窗口中)。然后,他们在不同的窗口中打开了四篇新文章。虽然这些数据不是特别有趣,但它应该让您了解通过实现上述自定义维度可以获得更多细节。

To create this report I picked a random client ID and session from one of my other reports (I chose a session that contained multiple unique pageviews to make it more interesting). Then I created a custom report that filtered only hits matching that Client ID and Session Count dimension:

为了创建此报告,我从其他报告中选择了一个随机客户端ID和会话(我选择了一个包含多个唯一网页浏览量的会话,以使其更有趣)。然后我创建了一个自定义报告,只筛选匹配该客户端ID和会话计数维度的匹配:

The configuration for above custom report

Calculated metrics

Calculated metrics allow you to define new metrics that can be derived from existing metrics.

计算的指标
通过计算指标,您可以定义可从现有指标派生的新指标。

For example, the autotrack maxScrollTracker plugin tracks the maximum scroll percentage for each page in a given session. However, since Google Analytics only reports metric totals across all sessions in a report’s date range, this value isn’t particularly useful on its own.

例如,autotrack maxScrollTracker插件跟踪给定会话中每个页面的最大滚动百分比。但是,由于Google Analytics仅报告报告日期范围内所有会话的指标总计,因此该值本身并不特别有用。

However, when you create a calculated metric to compute the average Max Scroll Depth value per unique pageviews in a session, you suddenly have a very useful metric.

但是,当您创建计算指标以计算会话中每个唯一网页浏览量的平均最大滚动深度值时,您突然有一个非常有用的指标。

Here’s a screenshot of a custom report I created showing pages with the highest average max scroll percentage on this site over the past 7 days.

这是我创建的自定义报告的屏幕截图,显示过去7天内此网站上平均最大滚动百分比最高的网页。

Top pages by average max scroll percentage

And the following screenshot shows how this calculated metric is configured:

The Avg. Max Scroll Percentage / Page calculated metric definition

Medians, histograms, and distributions

I mentioned above that you can use the hit-level custom dimensions to calculate medians and other distribution data.

我在上面提到过,您可以使用命中级自定义维度来计算中位数和其他分布数据。

As an example of why distribution data is useful, consider the max scroll report above. While the averages shown there are a good way to compare one dimension to another, they don’t show the complete picture of how users typically scroll on my site.

作为分发数据有用的原因的示例,请考虑上面的最大滚动报告。虽然显示的平均值有一种比较一个维度与另一个维度的好方法,但它们并未显示用户通常如何在我的网站上滚动的完整图片。

The histogram below shows a distribution of max scroll percentage (per session) across all users who scrolled over the past few days. The median value was 80%.

下面的直方图显示了过去几天滚动的所有用户的最大滚动百分比(每个会话)的分布。中值为80%。

Tip: to get median values in Google Analytics, all you have to do is add the Hit ID dimension to your report, sort the metric values in ascending order, and then read the middle value.

提示:要在Google Analytics中获取中值,您只需将Hit ID维度添加到报表中,按升序对指标值进行排序,然后读取中间值。

Max Scroll Percentage distribution.

As you can see from this chart, the largest bucket by far is users who scrolled all the way to the bottom of the page. This chart tells a vastly different story from the 44.60% average number in the previous report, and it emphasizes the value in having hit-level reporting granularity.

从这张图表中可以看出,到目前为止最大的存储桶是一直滚动到页面底部的用户。此图表显示了与上一份报告中44.60%平均数字截然不同的故事,并强调了具有命中级别报告粒度的价值。

To create histograms like the one above you’ll need to use the Analytics Reporting API to fetch the data and then a visualization library (the example above uses Google Charts) to create the chart, so it’s a bit more complicated than just using the Google Analytics UI, but for more advanced reporting needs, it’s definitely worth investing in learning these tools to get the most out of your data.

要创建如上所示的直方图,您需要使用Analytics Reporting API来获取数据,然后使用可视化库(上面的示例使用Google Charts)来创建图表,因此它比仅使用Google更复杂一些分析用户界面,但对于更高级的报告需求,绝对值得投资学习这些工具以充分利用您的数据。

Another good example of visualizing hit-level metric distribution is the performance data we measured in last year’s Google I/O webapp. We created a custom dimension that indicated whether or not the browser was loading the page via a Service Worker, and we created a metric to track time to first paint. From this data we were able to see how service worker usage impacts load times across desktop and mobile.

可视化命中级度量分布的另一个好例子是我们在去年的Google I / O webapp中测量的性能数据。我们创建了一个自定义维度,指示浏览器是否通过Service Worker加载页面,我们创建了一个度量标准来跟踪第一次绘制的时间。通过这些数据,我们可以了解服务工作者的使用情况如何影响桌面和移动设备的加载时间

On desktop the median time to first paint was 583 ms when controlled by a service worker vs. 912 ms when not controlled.

在桌面上,当服务工作者控制时,第一次绘制的中间时间为583毫秒,而不受控制则为912毫秒。

Time to first paint distribution for the Google I/O WebApp (Desktop).

On mobile the median was 1634 ms when controlled by a service worker vs. 1933 ms when not controlled.

是第一次为Google I / O WebApp(桌面)绘制分发的时间。
在移动设备上,当服务人员控制时,中位数为1634毫秒,而不受控制则为1933毫秒。

Time to first paint distribution for the Google I/O WebApp (Mobile).

Conclusions

There are a lot of features developers would like that Google Analytics doesn’t track by default. However, with only a bit of configuration and extra code, you can do almost everything you want with Google Analytics’ existing extensibility features today.

是第一次为Google I / O WebApp(移动)绘制分发的时间。
结论
开发人员希望Google Analytics不会默认跟踪这些功能。但是,只需要一些配置和额外的代码,您现在几乎可以使用Google Analytics现有的可扩展性功能完成所有工作。

This article provides a brief introduction into my rationale for including a lot of these features in my “boilerplate” analytics.js implementation. If you want to keep up to date with the current state of best practices, you should follow the analyticsjs-boilerplate repo on Github. I plan to keep it updated as new tracking techniques and best practices emerge.

本文简要介绍了我在“样板”analytics.js实现中包含大量这些功能的基本原理。如果您想了解最新实践的最新状态,您应该遵循Github上的analyticsjs-boilerplate repo。随着新的跟踪技术和最佳实践的出现,我计划对其进行更新。


    本文由AB模板网:织梦模板整理发布, 转载请说明出处:https://www.mobanhu.com
    随机站长资讯
    高级精美的家私企业网站源码 家私家纺类网
    农业绿色生态水果企业dede源码
    驾校类企业网站源码 驾校网站模板
    绿色LED灯管类织梦源码 照明企业网站模板
    蓝色通用织梦博客模板 资讯文章类网站源码
    红色大气装饰公司织梦源码 建筑装修装潢企
    网站建设企业模板 互联网网络营销类网站源
    html5响应式手机自适应网站模板(兼容手机
    黑色HTML5工作室网络公司网站整站模板(适
    简洁大气网站建设网络设计类企业织梦模板
    html5+css3高端网站建设工作室源码 酷炫的h
    红灰色大气网络工作室织梦模板
    织梦dedecms幻灯片模糊解决办法
    织梦dedecms巧用标签实现图片自动Alt功能,
    织梦dedecms文章列表循环标签增加notypeid
    织梦dedecms专题模板应用分析及使用案例
    dedecms织梦让二级栏目标题去除“/”斜杠和
    关于出现“对不起,您安装的不是正版应用..
    Discuz(Can not write to cache files)有关
    Discuz通过修改文章标题更好的实现SEO的方
    DiscuzX中存在不合法的文件被上传的修复方
    关于Discuz x3.1页面空白解决方法
    通用营销工业机械展示型企业织梦模板 电子
    简洁外贸公司电子科技产品网站源码 白色织
    蓝色大气的通信类电子科技企业通用网站源码
    娱乐多媒体类企业公司织梦模板 娱乐设备网
    高端大气数码产品电子类企业源码模板
    高级精美的家私企业网站源码 家私家纺类网
    农业绿色生态水果企业dede源码
    驾校类企业网站源码 驾校网站模板
    绿色LED灯管类织梦源码 照明企业网站模板
    蓝色通用织梦博客模板 资讯文章类网站源码
    红色大气装饰公司织梦源码 建筑装修装潢企
    网站建设企业模板 互联网网络营销类网站源
    html5响应式手机自适应网站模板(兼容手机
    黑色HTML5工作室网络公司网站整站模板(适
    简洁大气网站建设网络设计类企业织梦模板
    html5+css3高端网站建设工作室源码 酷炫的h
    红灰色大气网络工作室织梦模板
    织梦dedecms幻灯片模糊解决办法
    织梦dedecms巧用标签实现图片自动Alt功能,
    织梦dedecms文章列表循环标签增加notypeid
    织梦dedecms专题模板应用分析及使用案例
    dedecms织梦让二级栏目标题去除“/”斜杠和
    关于出现“对不起,您安装的不是正版应用..
    Discuz(Can not write to cache files)有关
    Discuz通过修改文章标题更好的实现SEO的方
    DiscuzX中存在不合法的文件被上传的修复方
    关于Discuz x3.1页面空白解决方法
    通用营销工业机械展示型企业织梦模板 电子
    简洁外贸公司电子科技产品网站源码 白色织
    蓝色大气的通信类电子科技企业通用网站源码
    娱乐多媒体类企业公司织梦模板 娱乐设备网
    高端大气数码产品电子类企业源码模板
    高级精美的家私企业网站源码 家私家纺类网
    农业绿色生态水果企业dede源码
    驾校类企业网站源码 驾校网站模板
    绿色LED灯管类织梦源码 照明企业网站模板
    蓝色通用织梦博客模板 资讯文章类网站源码
    红色大气装饰公司织梦源码 建筑装修装潢企
    网站建设企业模板 互联网网络营销类网站源
    html5响应式手机自适应网站模板(兼容手机
    黑色HTML5工作室网络公司网站整站模板(适
    简洁大气网站建设网络设计类企业织梦模板
    html5+css3高端网站建设工作室源码 酷炫的h
    红灰色大气网络工作室织梦模板
    织梦dedecms幻灯片模糊解决办法
    织梦dedecms巧用标签实现图片自动Alt功能,
    织梦dedecms文章列表循环标签增加notypeid
    织梦dedecms专题模板应用分析及使用案例
    dedecms织梦让二级栏目标题去除“/”斜杠和
    关于出现“对不起,您安装的不是正版应用..
    Discuz(Can not write to cache files)有关
    Discuz通过修改文章标题更好的实现SEO的方
    DiscuzX中存在不合法的文件被上传的修复方
    关于Discuz x3.1页面空白解决方法
    通用营销工业机械展示型企业织梦模板 电子
    简洁外贸公司电子科技产品网站源码 白色织
    蓝色大气的通信类电子科技企业通用网站源码
    娱乐多媒体类企业公司织梦模板 娱乐设备网
    高端大气数码产品电子类企业源码模板
    高级精美的家私企业网站源码 家私家纺类网
    农业绿色生态水果企业dede源码
    驾校类企业网站源码 驾校网站模板
    绿色LED灯管类织梦源码 照明企业网站模板
    蓝色通用织梦博客模板 资讯文章类网站源码
    红色大气装饰公司织梦源码 建筑装修装潢企
    网站建设企业模板 互联网网络营销类网站源
    html5响应式手机自适应网站模板(兼容手机
    黑色HTML5工作室网络公司网站整站模板(适
    简洁大气网站建设网络设计类企业织梦模板
    html5+css3高端网站建设工作室源码 酷炫的h
    红灰色大气网络工作室织梦模板
    织梦dedecms幻灯片模糊解决办法
    织梦dedecms巧用标签实现图片自动Alt功能,
    织梦dedecms文章列表循环标签增加notypeid
    织梦dedecms专题模板应用分析及使用案例
    dedecms织梦让二级栏目标题去除“/”斜杠和
    关于出现“对不起,您安装的不是正版应用..
    Discuz(Can not write to cache files)有关
    Discuz通过修改文章标题更好的实现SEO的方
    DiscuzX中存在不合法的文件被上传的修复方
    关于Discuz x3.1页面空白解决方法
    通用营销工业机械展示型企业织梦模板 电子
    简洁外贸公司电子科技产品网站源码 白色织
    蓝色大气的通信类电子科技企业通用网站源码
    娱乐多媒体类企业公司织梦模板 娱乐设备网
    高端大气数码产品电子类企业源码模板
    高级精美的家私企业网站源码 家私家纺类网
    农业绿色生态水果企业dede源码
    驾校类企业网站源码 驾校网站模板
    绿色LED灯管类织梦源码 照明企业网站模板
    蓝色通用织梦博客模板 资讯文章类网站源码
    红色大气装饰公司织梦源码 建筑装修装潢企
    网站建设企业模板 互联网网络营销类网站源
    html5响应式手机自适应网站模板(兼容手机
    黑色HTML5工作室网络公司网站整站模板(适
    简洁大气网站建设网络设计类企业织梦模板
    html5+css3高端网站建设工作室源码 酷炫的h
    红灰色大气网络工作室织梦模板
    织梦dedecms幻灯片模糊解决办法
    织梦dedecms巧用标签实现图片自动Alt功能,
    织梦dedecms文章列表循环标签增加notypeid
    织梦dedecms专题模板应用分析及使用案例
    dedecms织梦让二级栏目标题去除“/”斜杠和
    关于出现“对不起,您安装的不是正版应用..
    Discuz(Can not write to cache files)有关
    Discuz通过修改文章标题更好的实现SEO的方
    DiscuzX中存在不合法的文件被上传的修复方
    关于Discuz x3.1页面空白解决方法
    通用营销工业机械展示型企业织梦模板 电子
    简洁外贸公司电子科技产品网站源码 白色织
    蓝色大气的通信类电子科技企业通用网站源码
    娱乐多媒体类企业公司织梦模板 娱乐设备网
    高端大气数码产品电子类企业源码模板
    高级精美的家私企业网站源码 家私家纺类网
    农业绿色生态水果企业dede源码
    驾校类企业网站源码 驾校网站模板
    绿色LED灯管类织梦源码 照明企业网站模板
    蓝色通用织梦博客模板 资讯文章类网站源码
    红色大气装饰公司织梦源码 建筑装修装潢企
    网站建设企业模板 互联网网络营销类网站源
    html5响应式手机自适应网站模板(兼容手机
    黑色HTML5工作室网络公司网站整站模板(适
    简洁大气网站建设网络设计类企业织梦模板
    html5+css3高端网站建设工作室源码 酷炫的h
    红灰色大气网络工作室织梦模板
    织梦dedecms幻灯片模糊解决办法
    织梦dedecms巧用标签实现图片自动Alt功能,
    织梦dedecms文章列表循环标签增加notypeid
    织梦dedecms专题模板应用分析及使用案例
    dedecms织梦让二级栏目标题去除“/”斜杠和
    关于出现“对不起,您安装的不是正版应用..
    Discuz(Can not write to cache files)有关
    Discuz通过修改文章标题更好的实现SEO的方
    DiscuzX中存在不合法的文件被上传的修复方
    关于Discuz x3.1页面空白解决方法
    通用营销工业机械展示型企业织梦模板 电子
    简洁外贸公司电子科技产品网站源码 白色织
    蓝色大气的通信类电子科技企业通用网站源码
    娱乐多媒体类企业公司织梦模板 娱乐设备网
    高端大气数码产品电子类企业源码模板
    高级精美的家私企业网站源码 家私家纺类网
    农业绿色生态水果企业dede源码
    驾校类企业网站源码 驾校网站模板
    绿色LED灯管类织梦源码 照明企业网站模板
    蓝色通用织梦博客模板 资讯文章类网站源码
    红色大气装饰公司织梦源码 建筑装修装潢企
    网站建设企业模板 互联网网络营销类网站源
    html5响应式手机自适应网站模板(兼容手机
    黑色HTML5工作室网络公司网站整站模板(适
    简洁大气网站建设网络设计类企业织梦模板
    html5+css3高端网站建设工作室源码 酷炫的h
    红灰色大气网络工作室织梦模板
    织梦dedecms幻灯片模糊解决办法
    织梦dedecms巧用标签实现图片自动Alt功能,
    织梦dedecms文章列表循环标签增加notypeid
    织梦dedecms专题模板应用分析及使用案例
    dedecms织梦让二级栏目标题去除“/”斜杠和
    关于出现“对不起,您安装的不是正版应用..
    Discuz(Can not write to cache files)有关
    Discuz通过修改文章标题更好的实现SEO的方
    DiscuzX中存在不合法的文件被上传的修复方
    关于Discuz x3.1页面空白解决方法
    通用营销工业机械展示型企业织梦模板 电子
    简洁外贸公司电子科技产品网站源码 白色织
    蓝色大气的通信类电子科技企业通用网站源码
    娱乐多媒体类企业公司织梦模板 娱乐设备网
    高端大气数码产品电子类企业源码模板
    高级精美的家私企业网站源码 家私家纺类网
    农业绿色生态水果企业dede源码
    驾校类企业网站源码 驾校网站模板
    绿色LED灯管类织梦源码 照明企业网站模板
    蓝色通用织梦博客模板 资讯文章类网站源码
    红色大气装饰公司织梦源码 建筑装修装潢企
    网站建设企业模板 互联网网络营销类网站源
    html5响应式手机自适应网站模板(兼容手机
    黑色HTML5工作室网络公司网站整站模板(适
    简洁大气网站建设网络设计类企业织梦模板
    html5+css3高端网站建设工作室源码 酷炫的h
    红灰色大气网络工作室织梦模板
    织梦dedecms幻灯片模糊解决办法
    织梦dedecms巧用标签实现图片自动Alt功能,
    织梦dedecms文章列表循环标签增加notypeid
    织梦dedecms专题模板应用分析及使用案例
    dedecms织梦让二级栏目标题去除“/”斜杠和
    最新站长资讯
    高级精美的家私企业网站源码 家私家纺类网
    农业绿色生态水果企业dede源码
    驾校类企业网站源码 驾校网站模板
    绿色LED灯管类织梦源码 照明企业网站模板
    蓝色通用织梦博客模板 资讯文章类网站源码
    红色大气装饰公司织梦源码 建筑装修装潢企
    网站建设企业模板 互联网网络营销类网站源
    html5响应式手机自适应网站模板(兼容手机
    黑色HTML5工作室网络公司网站整站模板(适
    简洁大气网站建设网络设计类企业织梦模板
    html5+css3高端网站建设工作室源码 酷炫的h
    红灰色大气网络工作室织梦模板
    织梦dedecms幻灯片模糊解决办法
    织梦dedecms巧用标签实现图片自动Alt功能,
    织梦dedecms文章列表循环标签增加notypeid
    织梦dedecms专题模板应用分析及使用案例
    dedecms织梦让二级栏目标题去除“/”斜杠和
    关于出现“对不起,您安装的不是正版应用..
    Discuz(Can not write to cache files)有关
    Discuz通过修改文章标题更好的实现SEO的方
    DiscuzX中存在不合法的文件被上传的修复方
    关于Discuz x3.1页面空白解决方法
    通用营销工业机械展示型企业织梦模板 电子
    简洁外贸公司电子科技产品网站源码 白色织
    蓝色大气的通信类电子科技企业通用网站源码
    娱乐多媒体类企业公司织梦模板 娱乐设备网
    高端大气数码产品电子类企业源码模板
    高级精美的家私企业网站源码 家私家纺类网
    农业绿色生态水果企业dede源码
    驾校类企业网站源码 驾校网站模板
    绿色LED灯管类织梦源码 照明企业网站模板
    蓝色通用织梦博客模板 资讯文章类网站源码
    红色大气装饰公司织梦源码 建筑装修装潢企
    网站建设企业模板 互联网网络营销类网站源
    html5响应式手机自适应网站模板(兼容手机
    黑色HTML5工作室网络公司网站整站模板(适
    简洁大气网站建设网络设计类企业织梦模板
    html5+css3高端网站建设工作室源码 酷炫的h
    红灰色大气网络工作室织梦模板
    织梦dedecms幻灯片模糊解决办法
    织梦dedecms巧用标签实现图片自动Alt功能,
    织梦dedecms文章列表循环标签增加notypeid
    织梦dedecms专题模板应用分析及使用案例
    dedecms织梦让二级栏目标题去除“/”斜杠和
    关于出现“对不起,您安装的不是正版应用..
    Discuz(Can not write to cache files)有关
    Discuz通过修改文章标题更好的实现SEO的方
    DiscuzX中存在不合法的文件被上传的修复方
    关于Discuz x3.1页面空白解决方法
    通用营销工业机械展示型企业织梦模板 电子
    简洁外贸公司电子科技产品网站源码 白色织
    蓝色大气的通信类电子科技企业通用网站源码
    娱乐多媒体类企业公司织梦模板 娱乐设备网
    高端大气数码产品电子类企业源码模板
    高级精美的家私企业网站源码 家私家纺类网
    农业绿色生态水果企业dede源码
    驾校类企业网站源码 驾校网站模板
    绿色LED灯管类织梦源码 照明企业网站模板
    蓝色通用织梦博客模板 资讯文章类网站源码
    红色大气装饰公司织梦源码 建筑装修装潢企
    网站建设企业模板 互联网网络营销类网站源
    html5响应式手机自适应网站模板(兼容手机
    黑色HTML5工作室网络公司网站整站模板(适
    简洁大气网站建设网络设计类企业织梦模板
    html5+css3高端网站建设工作室源码 酷炫的h
    红灰色大气网络工作室织梦模板
    织梦dedecms幻灯片模糊解决办法
    织梦dedecms巧用标签实现图片自动Alt功能,
    织梦dedecms文章列表循环标签增加notypeid
    织梦dedecms专题模板应用分析及使用案例
    dedecms织梦让二级栏目标题去除“/”斜杠和
    关于出现“对不起,您安装的不是正版应用..
    Discuz(Can not write to cache files)有关
    Discuz通过修改文章标题更好的实现SEO的方
    DiscuzX中存在不合法的文件被上传的修复方
    关于Discuz x3.1页面空白解决方法
    通用营销工业机械展示型企业织梦模板 电子
    简洁外贸公司电子科技产品网站源码 白色织
    蓝色大气的通信类电子科技企业通用网站源码
    娱乐多媒体类企业公司织梦模板 娱乐设备网
    高端大气数码产品电子类企业源码模板
    高级精美的家私企业网站源码 家私家纺类网
    农业绿色生态水果企业dede源码
    驾校类企业网站源码 驾校网站模板
    绿色LED灯管类织梦源码 照明企业网站模板
    蓝色通用织梦博客模板 资讯文章类网站源码
    红色大气装饰公司织梦源码 建筑装修装潢企
    网站建设企业模板 互联网网络营销类网站源
    html5响应式手机自适应网站模板(兼容手机
    黑色HTML5工作室网络公司网站整站模板(适
    简洁大气网站建设网络设计类企业织梦模板
    html5+css3高端网站建设工作室源码 酷炫的h
    红灰色大气网络工作室织梦模板
    织梦dedecms幻灯片模糊解决办法
    织梦dedecms巧用标签实现图片自动Alt功能,
    织梦dedecms文章列表循环标签增加notypeid
    织梦dedecms专题模板应用分析及使用案例
    dedecms织梦让二级栏目标题去除“/”斜杠和
    关于出现“对不起,您安装的不是正版应用..
    Discuz(Can not write to cache files)有关
    Discuz通过修改文章标题更好的实现SEO的方
    DiscuzX中存在不合法的文件被上传的修复方
    关于Discuz x3.1页面空白解决方法
    通用营销工业机械展示型企业织梦模板 电子
    简洁外贸公司电子科技产品网站源码 白色织
    蓝色大气的通信类电子科技企业通用网站源码
    娱乐多媒体类企业公司织梦模板 娱乐设备网
    高端大气数码产品电子类企业源码模板
    高级精美的家私企业网站源码 家私家纺类网
    农业绿色生态水果企业dede源码
    驾校类企业网站源码 驾校网站模板
    绿色LED灯管类织梦源码 照明企业网站模板
    蓝色通用织梦博客模板 资讯文章类网站源码
    红色大气装饰公司织梦源码 建筑装修装潢企
    网站建设企业模板 互联网网络营销类网站源
    html5响应式手机自适应网站模板(兼容手机
    黑色HTML5工作室网络公司网站整站模板(适
    简洁大气网站建设网络设计类企业织梦模板
    html5+css3高端网站建设工作室源码 酷炫的h
    红灰色大气网络工作室织梦模板
    织梦dedecms幻灯片模糊解决办法
    织梦dedecms巧用标签实现图片自动Alt功能,
    织梦dedecms文章列表循环标签增加notypeid
    织梦dedecms专题模板应用分析及使用案例
    dedecms织梦让二级栏目标题去除“/”斜杠和
    关于出现“对不起,您安装的不是正版应用..
    Discuz(Can not write to cache files)有关
    Discuz通过修改文章标题更好的实现SEO的方
    DiscuzX中存在不合法的文件被上传的修复方
    关于Discuz x3.1页面空白解决方法
    通用营销工业机械展示型企业织梦模板 电子
    简洁外贸公司电子科技产品网站源码 白色织
    蓝色大气的通信类电子科技企业通用网站源码
    娱乐多媒体类企业公司织梦模板 娱乐设备网
    高端大气数码产品电子类企业源码模板
    高级精美的家私企业网站源码 家私家纺类网
    农业绿色生态水果企业dede源码
    驾校类企业网站源码 驾校网站模板
    绿色LED灯管类织梦源码 照明企业网站模板
    蓝色通用织梦博客模板 资讯文章类网站源码
    红色大气装饰公司织梦源码 建筑装修装潢企
    网站建设企业模板 互联网网络营销类网站源
    html5响应式手机自适应网站模板(兼容手机
    黑色HTML5工作室网络公司网站整站模板(适
    简洁大气网站建设网络设计类企业织梦模板
    html5+css3高端网站建设工作室源码 酷炫的h
    红灰色大气网络工作室织梦模板
    织梦dedecms幻灯片模糊解决办法
    织梦dedecms巧用标签实现图片自动Alt功能,
    织梦dedecms文章列表循环标签增加notypeid
    织梦dedecms专题模板应用分析及使用案例
    dedecms织梦让二级栏目标题去除“/”斜杠和
    关于出现“对不起,您安装的不是正版应用..
    Discuz(Can not write to cache files)有关
    Discuz通过修改文章标题更好的实现SEO的方
    DiscuzX中存在不合法的文件被上传的修复方
    关于Discuz x3.1页面空白解决方法
    通用营销工业机械展示型企业织梦模板 电子
    简洁外贸公司电子科技产品网站源码 白色织
    蓝色大气的通信类电子科技企业通用网站源码
    娱乐多媒体类企业公司织梦模板 娱乐设备网
    高端大气数码产品电子类企业源码模板
    高级精美的家私企业网站源码 家私家纺类网
    农业绿色生态水果企业dede源码
    驾校类企业网站源码 驾校网站模板
    绿色LED灯管类织梦源码 照明企业网站模板
    蓝色通用织梦博客模板 资讯文章类网站源码
    红色大气装饰公司织梦源码 建筑装修装潢企
    网站建设企业模板 互联网网络营销类网站源
    html5响应式手机自适应网站模板(兼容手机
    黑色HTML5工作室网络公司网站整站模板(适
    简洁大气网站建设网络设计类企业织梦模板
    html5+css3高端网站建设工作室源码 酷炫的h
    红灰色大气网络工作室织梦模板
    织梦dedecms幻灯片模糊解决办法
    织梦dedecms巧用标签实现图片自动Alt功能,
    织梦dedecms文章列表循环标签增加notypeid
    织梦dedecms专题模板应用分析及使用案例
    dedecms织梦让二级栏目标题去除“/”斜杠和
    关于出现“对不起,您安装的不是正版应用..
    Discuz(Can not write to cache files)有关
    Discuz通过修改文章标题更好的实现SEO的方
    DiscuzX中存在不合法的文件被上传的修复方
    关于Discuz x3.1页面空白解决方法
    通用营销工业机械展示型企业织梦模板 电子
    简洁外贸公司电子科技产品网站源码 白色织
    蓝色大气的通信类电子科技企业通用网站源码
    娱乐多媒体类企业公司织梦模板 娱乐设备网
    高端大气数码产品电子类企业源码模板
    高级精美的家私企业网站源码 家私家纺类网
    农业绿色生态水果企业dede源码
    驾校类企业网站源码 驾校网站模板
    绿色LED灯管类织梦源码 照明企业网站模板
    蓝色通用织梦博客模板 资讯文章类网站源码
    红色大气装饰公司织梦源码 建筑装修装潢企
    网站建设企业模板 互联网网络营销类网站源
    html5响应式手机自适应网站模板(兼容手机
    黑色HTML5工作室网络公司网站整站模板(适
    简洁大气网站建设网络设计类企业织梦模板
    html5+css3高端网站建设工作室源码 酷炫的h
    红灰色大气网络工作室织梦模板
    织梦dedecms幻灯片模糊解决办法
    织梦dedecms巧用标签实现图片自动Alt功能,
    织梦dedecms文章列表循环标签增加notypeid
    织梦dedecms专题模板应用分析及使用案例
    dedecms织梦让二级栏目标题去除“/”斜杠和
    关于出现“对不起,您安装的不是正版应用..
    Discuz(Can not write to cache files)有关
    Discuz通过修改文章标题更好的实现SEO的方
    DiscuzX中存在不合法的文件被上传的修复方
    关于Discuz x3.1页面空白解决方法
    首页 免费源码 VIP专区 会员中心
    收缩