HNHacker News
TopNewBestAskShowJobs

gregable

1,271 karma · joined September 17, 2010

http://gregable.com/
submissionscomments
gregable··on AMP pages displaying your own domain
Good question.

Conceptually, you can think of a signed exchange as a 301 redirect to a new URL which has already been cached by the browser (so there is no 2nd network event). The cache was populated by the contents of the signed exchange, assuming the signature validates.

There is no "reaching into the document" from the previous click or anything weird like that.

gregable··on AMP pages displaying your own domain
There is a little confusion here, understandable. Google search will not show these signed exchanges in an iframe, the pages are full frame.

Try it for yourself. Using Chrome 73 or later (you probably already have this), and a mobile browser (either a phone or mobile emulation), try the query [amp dev success stories].

It will only use signed exchanges in Chrome because currently only Chrome supports signed exchanges. The search engine explicitly looks for the browser to state that it supports signed exchanges in an Accept header, like any other new technology.

Yes, any page can use this. So, for example if you went and fetched a signed exchange from https://amppackageexample.com/ (or any other site that supports one, this is just an example), you could then serve that from your own server, more or less just like any other file (the less is that you need to set the right Content-Type header, but it otherwise works just like serving an image or a zip file).

Then, if a user visited the URL on your site https://yoursite.com/cached-copy-of-amppackageexample.com/ then the browser would display https://amppackageexample.com/ in the URL bar, as though that URL had 301 redirected, but without the extra network fetch.

Google search does exactly this, just loading a cached copy of the Signed Exchange, and any other cache (or even any website) can do the same.

gregable··on Announcing AMP Real URL
The problem with prefetching the publisher URL from a search results page is that it leaks the user's query intent to an origin they have not visited, which violates the user's privacy.

By prefetching a signed exchange from the same origin as the search results page, privacy is preserved. Once the user clicks on a result, the user intent can be shared with the third party origin, no problem, and is in the AMP cache.

gregable··on AMP pages displaying your own domain
Good question. The signing is done by the publisher, using the same digital signature infrastructure that is used for TLS (https). So, the publisher alone has the signing key, and any browser can verify the signature by comparing to the public certificate, signed by a certificate authority.
gregable··on AMP pages displaying your own domain
The javascript is heavily cached, so will not give a request on every page load.

That is not the intention. If javascript is disabled entirely, Google Search won't even load AMP pages. The scenario you describe of a user loading an AMP page directly without javascript enabled is somewhat rare.

gregable··on AMP pages displaying your own domain
In general, this sounds like an interesting use case.

One thing to note is that the specification currently limits the lifetime of a signed exchange to 7 days. It's possible that by exploring some of these use cases, especially offline, the spec could be improved with respect to some of these constraints.

gregable··on Announcing AMP Real URL
If you have a round-trip-time of 1 second, it will take you 1 second to load a text file with 1 byte in it. However, an amp page will have loaded before you clicked, so it will take only the handful of millis in CPU time to swap frames and display.
gregable··on AMP pages displaying your own domain
The linker (google in this case) could rewrite the link to use a redirector if they choose. If Javascript is off, AMP and thus Signed Exchanges are disabled on Google search results anyway.

You misunderstand the 8 second CSS animation in the AMP boilerplate. Here's the code (simplified):

  <style>
    body { animation:-amp-start 8s steps(1,end) 0s 1 normal both}
    @keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}
  </style>
  <noscript>
    <style amp-boilerplate>
      body{animation:none}
    </style>
  </noscript>
See the noscript section: if javascript is disabled, the CSS displays the body immediately. If Javascript is enabled, but for some reason the AMP javascript fails to load, after 8 seconds, the page is displayed anyway. The page is probably somewhat broken without the javascript loading, but the 8s is a fallback, not code to slow down non-javascript browsers.
gregable··on Announcing AMP Real URL
Let me see if I can explain this a little better.

Anyone can cache a signed exchange from anyone else. So, for example if you went and fetched a signed exchange from https://amppackageexample.com/ (or any other site that supports one, this is just an example), you could then serve that from your own server, more or less just like any other file (the less is that you need to set the right Content-Type header, but it otherwise works just like serving an image or a zip file).

Then, if a user visited the URL on your site https://yoursite.com/cached-copy-of-amppackageexample.com/ then the browser would display https://amppackageexample.com/ in the URL bar, as though that URL had 301 redirected, but without the extra network fetch.

Google search does exactly this, just loading a cached copy of the Signed Exchange, and any other cache (or even any website) can do the same.

So, if you publish a signed exchange, you are allowing all caches to do this, not just a selected cache. However, since the document is signed, absolutely no caches can modify the document or the browser will reject it and error handle (typically just making an actual redirect to your domain).

I hope that helps to understand.

gregable··on Announcing AMP Real URL
This is an application of the W3C's Extensible Web Manifesto (https://www.w3.org/community/nextweb/2013/06/11/the-extensib...)
gregable··on AMP pages displaying your own domain
The behavior for browsers without support is to show the google.com/amp URL as before, along with a small html-based bar with additional information about the original domain and share intents.
gregable··on AMP pages displaying your own domain
The publisher's cookie-based analytics will operate on the origin in the URL bar in this case. The document (though not the delivery server) will have access to publisher origin cookies.

Conceptually, you can think of a signed exchange as a 301 redirect to a new URL which has already been cached by the browser (so there is no 2nd network event). The cache was populated by the contents of the signed exchange, assuming the signature validates.

gregable··on AMP pages displaying your own domain
You may be thinking of this use cases section here: https://wicg.github.io/webpackage/draft-yasskin-webpackage-u...
gregable··on AMP pages displaying your own domain
The browser displays the URL from the origin that digitally signed the unmodified content.

A browser already doesn't show you what server delivered the content. That would be your wifi AP, cell phone tower, or ISP node. The internet has already long established that we can trust content without trusting intermediaries.

There are two elements that are important: integrity and privacy. The content integrity is protected via a digital signature, the "signed" part of "signed http exchanges". The signature proves that the document hasn't been tampered with.

Regarding privacy: The intermediary (a search engine in this case) already has the content being delivered as a result of crawling it. It also knows the user clicked on a link to get that content, and knows the user's ip address. Even without AMP or Signed Exchanges, the privacy situation is the same. Once the page is loaded, all further interactions with the origin are normal https traffic, so later requests are not different in privacy either.

What this enables, for search results, is the ability to load the bytes of the content before the user clicks a search result. If the browser prefetched those bytes with the origin's awareness, then the user's privacy with respect to the search query would be violated, making prefetch problematic. With this setup, documents can be prefetched while preserving user privacy and after the user clicks all browser behavior continues as normal from that point forward.

gregable··on Announcing AMP Real URL
This, and in particular, the network has much higher _latency_ over mobile. AMP is aggressive about reducing the number of round trips between browser and server.
gregable··on Announcing AMP Real URL
Yes, though in the use case here, the party linking to the content has already read the content anyway by crawling it. This would be true if your entire session were delivered this way, but instead it's only the first click from a page linking to the signed exchange URL. The party linking also already knows the user's IP, knows what URL the user is going to, and can know the content. There is no loss of privacy.
gregable··on Announcing AMP Real URL
Good questions:

> Who's javascript/cookies run in a real URL amp page, if any?

The document operates as the signed origin, so cookies, CORS etc all operate as the signed origin (the one in the URL bar). The HTTP request is made using the request URL's origin however, so the server delivering the signed exchange has no cookie access to the signed origin's cookies.

> What happens if I hit refresh, does it reload the AMP page or the real page?

A refresh will cause the browser to make a normal HTTPS request to the origin in the URL bar. A refresh works identically to what it has in the past, essentially.

> Can a webpage that isn't Google use real domain AMP pages?

Yes. It is a spec that browsers can support, and any site can use. There is nothing Google specific, or even AMP specific, about the specification.

> In that case, can their javascript influence the page at all? (ie change the look, put elements over it, make http requests)

No. Conceptually, you can think of a signed exchange as a 301 redirect to a new URL which has already been cached by the browser (so there is no 2nd network event). The cache was populated by the contents of the signed exchange, assuming the signature validates.

gregable··on Announcing AMP Real URL
I wouldn't interpret this as the browser lying any more than the fact that your wifi router delivered the AMP document to your browser and your browser didn't show your wifi router in the URL bar.

The document is digitally signed by the publisher, using the publisher's own private key on the publisher's own server. This signature is then verified by your browser on the other end and verified against a CA issued certificate. The intermediaries don't matter in terms of the content, they are just a pipe at this point that can optimize network paths and allow for prefetching of the bytes.

The specification only allows a short lifetime for signed documents (7 days maximum, configurable to be shorter by the publisher), preventing long-lived caching drift. Refreshing will reload from the origin directly.

gregable··on Google launches AMP for email
Actually, the spec accepts both `<html emoji-4email>` and just `<html amp4email>`.

You can see what the spec accepts here: https://validator.ampproject.org/#htmlFormat=AMP4EMAIL

gregable··on Ask HN: Is it just me or is the AMP project making everything slower?
I'm with you, but it's the reality. I just searched for "NASA" on google news, clicked the first thing not from JPL (https://www.fool.com/investing/2019/01/12/whos-who-in-nasas-...) and it loaded 2.6MB cold cache.

Fetched the same on the AMP Cache: https://www-fool-com.cdn.ampproject.org/c/s/www.fool.com/amp... 200KB cold cache. Removing the likely cached resources (amp javascript, fontawesome cdn font) and the payload is ~35KB.

It's certainly possible to make a lightweight page, as hacker news is a great example, but people aren't doing it. For whatever reason, AMP seems to be effective at making the web actually follow best practices.

gregable··on Ask HN: Is it just me or is the AMP project making everything slower?
Precisely. The exact code is here:

https://www.ampproject.org/docs/fundamentals/spec/amp-boiler...

Here it is pretty-printed and simplified to not have the vendor-specific stuff:

  <style amp-boilerplate>
  body{
    animation:-amp-start 8s steps(1,end) 0s 1 normal both
  }
  @keyframes -amp-start{
    from{visibility:hidden}to{visibility:visible}
  }
  </style>
  <noscript>
    <style amp-boilerplate>
      body{animation:none}
    </style>
  </noscript>
The first bit is for browsers with javascript, but where the network is poor and can't load the minimal required highly cacheable javascript file within 8 seconds. It uses CSS just in case javascript really isn't working anyway such as being disabled per domain or something. The second bit is for browsers without javascript - the page is unblocked immediately.
gregable··on Ask HN: Is it just me or is the AMP project making everything slower?
The open question is would it be better or worse without AMP? It's likely that reddit (for example) would have just deployed an equally frustrating "mobile" page that loads even slower.

I just tried fetching http://www.reddit.com/ in an incognito window (no personalization) on a fast connection and it took 1.2s to get the first byte on the connection. I can't say if this is typical, but the AMP Cache has much faster delivery (~30ms) even before considering the preloading.

gregable··on Ask HN: Is it just me or is the AMP project making everything slower?
This CSS animation is just the backup in case the javascript doesn't load at all, really. After 8 seconds, the page gives up trying to prevent the flash of unstyled content and just renders, regardless of how bad the styling is. It also includes a <noscript> block that renders the page immediately if javascript is disabled. The 8s thing is for network issues. Graceful degradation.

Lots of documents (amp or not) use the same "hide the screen until layout is done" trick to avoid multiple relayouts as the initial javascript is running and CSS is being fetched. More often than ideal, they don't have a fallback if the javascript doesn't load at all. AMP mandates it with this CSS animation, which is far better than nothing.

Also when served from the AMP Cache (https://www-ehow-co-uk.cdn.ampproject.org/c/s/www.ehow.co.uk... for the example shown), the layout algorithm that javascript runs is applied by the AMP Cache instead and the 8-second timeout code is removed completely (view source and take a look). This doesn't work on all pages - there are some features that require a client-side context, but it does work on this one. Websites can run the same server-side layout algorithm on their origin using a node library (https://www.npmjs.com/package/amp-toolbox-optimizer). There is also work being done to improve all of this (server side layout on more documents, and making the system easier to run on your own site).

The 3s observation from the original post is interesting. It may just have been an estimation of the 8s, or it could have something to do with how the document is configured. Looking at this document, there are some <amp-font> tags that the document author has added with a 3000ms timeout. These are tags that instruct the AMP javascript to change the document CSS class depending on the success of failure of loading of a particular font. By default (not amp specific), if a document loads a webfont for a particular text, the browser will not display the text until the font is loaded. <amp-font> provides a CSS hook by which the author can do stuff like "hide the text for up to 3s, or when the font has loaded, whichever comes first". This page has some <amp-font> tags with a 3s timeout referencing fonts that have not been added to the document, which seems like a mistake from the document author, unsure. I was not able to reproduce the 3s experience though, so this may be incorrect speculation as to what happened.

gregable··on Google shifted $23B to tax haven Bermuda in 2017
As a different example:

A company dumps toxic chemicals into the air/water, and it results in horrible deaths and destruction to the environment which makes everyone's lives worse.

However, they've managed to do this in a completely legal way. Maybe they moved the dumping to a region without strong regulation. Maybe they found some legal loophole. Maybe they funded a politician's campaign who then carved out a legal loophole for them.

Would you still not blame the company or call their actions unethical in this case?

I personally would blame the company. I would consider their decisions unethical. I would also want to fix the laws so that I could legally hold them accountable, but I wouldn't absolve the company of responsibility until those laws were fixed.

How is tax avoidance all that different? Sure, it's not directly harming anyone. However, the lack of funding for the government means fewer social services and those services often are used to help people avoid horrible deaths (such as homeless freezing on the streets, veterans receiving medical care, or safety improvements to roads) and to improve the environment we live in (national parks, clean water initiatives, etc.).

gregable··on Norway's electric cars zip to new record: almost a third of all sales
I don't have numbers, and it very much depends on which grid we are talking about.

It's likely that some of the electricity came from renewables and little from coal. Even if from oil, the big power plants are more efficient than your car's engine at converting oil to power. There are losses and I don't know how those compare.

Also the grid gets greener over time, whereas your car engine only gets less efficient over time.

gregable··on Real URLs for AMP Cached Content Using Cloudflare Workers
These are currently drafts and are evolving with feedback, but Google is working with standards bodies and feedback from the web community.
gregable··on Real URLs for AMP Cached Content Using Cloudflare Workers
> experimental feature with no standardization

Web Packaging was originally proposed in 2015 as a W3C draft (https://www.w3.org/TR/2015/WD-web-packaging-20150115/) and the Signed Exchanges spec as an IETF specification (https://wicg.github.io/webpackage/draft-yasskin-http-origin-...)

There is also an open source project implementing it that anyone can use (https://github.com/ampproject/amppackager).

gregable··on In Chrome 71: Signed HTTP Exchanges
Good points, but mostly just confusion on the specification, I think.

> - the original server will not see your download request. This will skew their logs/statistics.

True in the strictest case if that site owner is strictly using http request logs for stats. The site owner must opt-in to this by signing their http exchanges, so this isn't something that will accidentally break someone unknowingly. Site owners have lots of ways of fixing this. More and more these days, logs are being recorded by javascript events anyway.

Note that this is also true of simple browser caching and prefetching. Caching preventing a request and prefetching adding a new one. This is why using server logs to understand audience behavior has limitations.

Also, this is one of the purposes of signed exchanges. In order to prefetch without violating the user's privacy, it's necessary to hide the download request from the origin server until after the user has clicked.

> - someone else will see what you are downloading instead. It's a privacy issue.

The originating server already has numerous ways of knowing all of this. Click tracking redirects, onclick event calls, etc can all register the user's click event off-site. Nearly all analytics tools already do this. The out-linking website owner also already can know the content of the page you will load as they can fetch it themselves. They will have done so in order to serve it as a signed exchange.

> It looks as if Signed HTTP Exchanges are opt-in at the moment.

In order to verify that the content is signed, a publisher must sign it using a private key. There really is no mechanism for this not to be opt-in in the future. The Signed Exchange format differs significantly from TLS connections (https) and there is no path to using the TLS connection to craft a signed exchange. The signed exchange spec in fact goes out of it's way to define a new certificate extension that is mutually exclusive with TLS certificates, so that a site owner must opt-in by way of getting a separate certificate issued.

gregable··on L.A.'s Most Derided Piece of Public Art Is About to Light Up Again
> Back in the 1970s, a computer used 8-bit tape, in binary code—picture a roll of paper tape with holes cut into it.

This seems like quite an ambitious project for 1975!

gregable··on Show HN: I made a privacy-first minimalist Google Analytics
Agreed, the first-party cookie is pretty self-evidently not a web-wide tracker.

There are lots of config options. Here's what I like to use:

  // Google Analytics Code.
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
  window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};

  // https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference
  ga('create', 'UA-XXX-XX', 'auto', {
      // The default cookie expiration is 2 years. We don't want our cookies
      // around that long. We only want just long enough to see analytics on
      // repeat visits. Instead, limit to 31 days. Field is in seconds:
      // 31 * 24 * 60 * 60 = 2678400
      'cookieExpires': 2678400,
      // We don't need a cookie to track campaign information, so remove that.
      'storeGac': false,
      // Anonymize the ip address of the user.
      'anonymizeIp': true,
      // Always send all data over SSL. Unnecessary, since the site only loads on
      // SSL, but defense in depth.
      'forceSSL': true});
  // Now, record 1 pageview event.
  ga('send', 'pageview');
← PreviousPage 6 of 13Next →