|
129 | 129 |
|
130 | 130 | a[href^="https://csswizardry.com"]::after, |
131 | 131 | a[href^="https://github.com"]::after, |
132 | | - a[href^="https://fonts.google.com/"]::after { |
| 132 | + a[href^="https://fonts.google.com/"]::after, |
| 133 | + a[href^="https://www.speedcurve.com/"]::after { |
133 | 134 | content: ""; |
134 | 135 | display: inline-block; |
135 | 136 | width: 1ch; |
|
153 | 154 | background-image: url(https://www.gstatic.com/images/icons/material/apps/fonts/1x/catalog/v5/favicon.svg); |
154 | 155 | } |
155 | 156 |
|
| 157 | + a[href^="https://www.speedcurve.com/"]::after { |
| 158 | + background-image: url(https://www.speedcurve.com/favicon.ico); |
| 159 | + } |
| 160 | + |
| 161 | + abbr { |
| 162 | + cursor: help; |
| 163 | + } |
| 164 | + |
| 165 | + dfn { |
| 166 | + font-style: normal;; |
| 167 | + } |
| 168 | + |
156 | 169 | img, video { |
157 | 170 | max-width: 100%; |
158 | 171 | height: auto; |
|
161 | 174 |
|
162 | 175 | :target { |
163 | 176 | background-color: #ffc; |
164 | | - outline: 10px solid #ffc; |
165 | 177 | scroll-margin-top: 1.5rem; |
166 | 178 | } |
167 | 179 |
|
| 180 | + h2:target { |
| 181 | + outline: 10px solid #ffc; |
| 182 | + } |
| 183 | + |
| 184 | + pre, |
168 | 185 | .c-snippet { |
169 | 186 | display: block; |
170 | 187 | background-color: #002a35; |
@@ -535,6 +552,71 @@ <h2><code><video></code> Demo</h2> |
535 | 552 |
|
536 | 553 |
|
537 | 554 |
|
| 555 | + <h2 id=analytics>Analytics</h2> |
| 556 | + |
| 557 | + <p>If your <dfn id=dfn:rum><abbr title="Real User Monitoring">RUM</abbr></dfn> |
| 558 | + or analytics provider accepts the <code>window.obs</code>-style data, you can |
| 559 | + send it off to them! You don’t <em>need</em> to use Obs.js to adapt or change |
| 560 | + your site—you can use it as a purely observational tool to learn more about |
| 561 | + your audience:</p> |
| 562 | + |
| 563 | + <img src=./assets/speedcurve.png width=1500 height=887 alt="SpeedCurve |
| 564 | + dashboard comparing low vs high latency cohorts. Low latency shows faster |
| 565 | + Largest Contentful Paint (1.08s vs 2.9s), with other metrics largely |
| 566 | + unchanged."> |
| 567 | + |
| 568 | + <p>I send all of my data off to my friends at <a |
| 569 | + href="https://www.speedcurve.com/">SpeedCurve</a>. With that, I can begin |
| 570 | + segmenting my <a href=#dfn:rum>RUM</a> data and designing strategies to serve |
| 571 | + different demographics.</p> |
| 572 | + |
| 573 | + <p>Here’s the exact snippet I use to send Obs.js data to <a |
| 574 | + href="https://www.speedcurve.com/">SpeedCurve</a>:</p> |
| 575 | + |
| 576 | + <script type=module class=c-snippet> |
| 577 | + /** |
| 578 | + * All the data previously captured by Obs.js is now sent to SpeedCurve! |
| 579 | + * |
| 580 | + * I ❤️ SpeedCurve! |
| 581 | + */ |
| 582 | + |
| 583 | + (() => { |
| 584 | + // Bail out if SpeedCurve is not available. |
| 585 | + if (!window.LUX || typeof window.LUX.addData !== 'function') return; |
| 586 | + |
| 587 | + const obs = window.obs || Object.create(null); |
| 588 | + |
| 589 | + // Keys we intend to send. Keep in sync with obs.js |
| 590 | + const keys = [ |
| 591 | + 'canShowRichMedia', |
| 592 | + 'connectionCapability', |
| 593 | + 'conservationPreference', |
| 594 | + 'cpuBucket', |
| 595 | + 'cpuCategory', |
| 596 | + 'dataSaver', |
| 597 | + 'deliveryMode', |
| 598 | + 'deviceCapability', |
| 599 | + 'downlinkBucket', |
| 600 | + 'downlinkCategory', |
| 601 | + 'ramBucket', |
| 602 | + 'ramCategory', |
| 603 | + 'rttBucket', |
| 604 | + 'rttCategory', |
| 605 | + 'shouldAvoidRichMedia' |
| 606 | + ]; |
| 607 | + |
| 608 | + for (const key of keys) { |
| 609 | + if (Object.prototype.hasOwnProperty.call(obs, key)) { |
| 610 | + window.LUX.addData(key, obs[key]); |
| 611 | + } |
| 612 | + } |
| 613 | + })(); |
| 614 | + </script> |
| 615 | + |
| 616 | + |
| 617 | + |
| 618 | + |
| 619 | + |
538 | 620 | <h2 id=showcase>Showcase</h2> |
539 | 621 |
|
540 | 622 | <p>These fine folk are using <a |
@@ -606,40 +688,6 @@ <h2 id=showcase>Showcase</h2> |
606 | 688 |
|
607 | 689 |
|
608 | 690 |
|
609 | | - <script type=module> |
610 | | - (() => { |
611 | | - // Bail out if SpeedCurve is not available. |
612 | | - if (!window.LUX || typeof window.LUX.addData !== 'function') return; |
613 | | - |
614 | | - const obs = window.obs || Object.create(null); |
615 | | - |
616 | | - // Keys we intend to send. Keep in sync with obs.js |
617 | | - const keys = [ |
618 | | - 'canShowRichMedia', |
619 | | - 'connectionCapability', |
620 | | - 'conservationPreference', |
621 | | - 'cpuBucket', |
622 | | - 'cpuCategory', |
623 | | - 'dataSaver', |
624 | | - 'deliveryMode', |
625 | | - 'deviceCapability', |
626 | | - 'downlinkBucket', |
627 | | - 'downlinkCategory', |
628 | | - 'ramBucket', |
629 | | - 'ramCategory', |
630 | | - 'rttBucket', |
631 | | - 'rttCategory', |
632 | | - 'shouldAvoidRichMedia' |
633 | | - ]; |
634 | | - |
635 | | - for (const key of keys) { |
636 | | - if (Object.prototype.hasOwnProperty.call(obs, key)) { |
637 | | - window.LUX.addData(key, obs[key]); |
638 | | - } |
639 | | - } |
640 | | - })(); |
641 | | - </script> |
642 | | - |
643 | 691 | <script type=application/ld+json> |
644 | 692 | { |
645 | 693 | "@context": "https://schema.org", |
|
0 commit comments