5 stories

You need neither PWA nor AMP to make your website load fast

1 Share

There has been a trend of new “revolutionary” techniques on the Web that basically let you do stuff possible decades ago.


First, AMP (Accelerated Mobile Pages). Think about it: web, in general, failed to be fast, so Google invents a parallel web where they simply don’t let you use JavaScript. Oh, and they let you use a couple of Google-approved AMP JS components. But wait, can’t regular web run without JavaScript? Of course it can. Can regular web include custom JS components? You bet. Can it be fast? Netflix recently found out that if they remove 500 Kb of JavaScript from a static (!!!) webpage it will load WAY faster and users will generally be happier. Who would have thought, right?

So why was AMP needed? Well, basically Google needed to lock content providers to be served through Google Search. But they needed a good cover story for that. And they chose to promote it as a performance solution.

Thing is, web developers don’t believe in performance. They say they do, but in reality, they don’t. What they believe in is hype. So if you hype old tricks under a new name, then developers can say “Now, finally, I can start writing fast apps. Thank you Google!”. Like if Google ever stopped you from doing so beforehand.

“But AMP is new! <amp-img> does so much more than <img>!”

It might, but what stops Google, if it really has an intention to help, from releasing it as a regular JS library?

So hype worked, lots of developers bought the cover story and rushed creating a parallel version of every webpage they serve with “AMP-enabled” performance boost.


“Hey boss, let’s rewrite our website to make it load fast!”
“Fuck off!”
“But studies show that every second of load time…”
“I said fuck off!”


“Hey boss, let’s rewrite our website with AMP. It’s a new tech by Google…”
“Drop everything! Here, take $$$”
“It also might improve…”
“I don’t care. Get on this NOW!”

I’m not saying practices promoted by AMP are bad or useless. They are good practices. But nothing stops you from following them in the regular web. Nothing has ever stopped you from writing performant pages, from the very inception of the web. Google hardly invented CDNs and async script loading. But nobody cared because old tech and good practices are never as tempting as something branded as “new”.


Enter PWA. Progressive Web Applications. Or Apps. Progressive Web Apps. Whatever.

So the idea was to be able to create a native-like experience but with web stack. What was the Web missing? Installing apps. Offline mode. Notifications (Ew). Working in the background. Yeah, that’s basically it. That’s it.

Again, I’m not going to say these things are wrong. They are not. If you want to create a native-like app using web technologies, you’ll have to use something like that. And it makes sense for apps like a shopping list or, I don’t know, alarm clock?

The problem with PWA is, well, there are two problems.

First is that most apps would be better off as websites rather than apps. Websites load each resource gradually, as it’s needed, unlike apps which have to fetch everything at install (that’s why app bundle sizes are usually way bigger than websites). Sites are more efficient but you can’t use them while offline.

But most “apps” today are online-only anyways! You can’t call Uber while being offline, and why would you open Uber app otherwise? Tinder is useless offline. You can’t date empty chat screens. You can’t join a meetup at Meetup.com without network connection. You can’t choose or book a hotel, you can’t transfer money or check your account balance offline. And nobody wants to re-read old cached tweets from Twitter or yesterday photos from Instagram. It just doesn’t make any sense.

So yeah, I would prefer those “apps” to be just websites. Believe it or not, there are benefits to that. I enjoy smaller download size, especially if I visit a site occasionally just for a quick look. I enjoy that websites do not consume my resources in the background. When I close it it unloads and does not constantly download new versions of its own libraries, which developers frequently need to deploy. I’m more than ready to sacrifice offline mode for that.

The second problem with PWA, and more relevant to our topic, is that it somehow got associated with performance.

The thing is, it has nothing to do with performance. I mean, nothing new. You were always able to cache resources to make navigation between pages quick, and browsers are pretty good at doing so. With HTTP/2 you can efficiently fetch resources in bulk and even push resources from the server for a “more instant” experience.

So managing resource cache yourself, in a ServiceWorker, seems more like a burden than a blessing. HTTP caching is also declarative, well-tested and well understood at this point, in other words, hard to screw up. Which you can’t say about your ServiceWorker. Caching is one of two hardest things in Computer Science. I personally had a bad experience with Meetup.com PWA when an error in their cache code made the whole site unusable to the point where it wouldn’t open meetup pages. And unlike HTTP, it’s not that easy to reset. Nope, refresh didn’t help.

But it would’ve been ok if ServiceWorker was a tradeoff: you pay complexity fee but get exciting new capabilities. Except you don’t. Nothing useful that you can do with ServiceWorker you can’t do with HTTP cache/AJAX/REST/Local Storage. It’s just a complexity hole you’ll sink countless workhours in.

PWA, as well as AMP, doesn’t even guarantee your website would be anywhere near “fast” or “instant”. It’s kind of funny how Tinder case study shows that login screen (one text input, one button, one SVG logo and a background gradient) takes 5 seconds to load on a 4G connection! I mean, they had to add loader for 2-5 seconds so users don’t close this bullshit immediately. And they call it fast.

This is fast:

How did they do it? By fucking caring about performance. As simple as that.

Oh, also not serving a gazillion of JavaScript bundles and not rendering on a client with React served over GraphQL via fetch polyfill. That probably helped too.

ServiceWorker or AMP, if your landing page is 170+ requests for 3.1 Mb for an image and four form fields, it can’t load fast no matter how many new frameworks you throw at it.


So what’s the verdict? To write fast websites with AMP and PWA you still need to understand performance optimization deeply. Without that, the only choice you have is to go with the hype.

But remember that neither AMP nor PWA would magically make your website any faster than say just a regular rewrite would.

Airbnb famous 800Kb index page. I would expect more care perf-wise from 900+ developers with average salary of $290,000/year. Even SublimeText gives up highlighting this bullshit at some point.

Once you understand performance, though, you’ll notice you need neither AMP nor PWA. Just stop doing bullshit and web suddenly starts to work instantly. AMP didn’t invent CDN and <noscript>. PWA didn’t invent caching. Static web still runs circles around any modern-day much-hyped framework.

“But the users! They want our fancy-schmancy interactivity. They DEMAND animations!”

I’ll tell you one thing. No one enjoys staring at the loading screen for 5 seconds. Loader being animated doesn’t make any difference. If you can’t into performance, at least don’t pretend it’s a feature.

  1. Although I don’t think we need more notifications in our life either. Especially not from random web pages we visit. Even not from native apps—I keep my phone in permanent Do Not Disturb mode with a short list of whitelisted apps. ↩︎
  2. By the way, since you first opened this article my ServiceWorker has downloaded 0 Kb of useless data in background. I hope you are on WiFi :) ↩︎
Read the whole story
1094 days ago
Share this story

So You Want To Compete With Steam

1 Share
So You Want To Compete With Steam

So You Want To Compete With Steam

I get a lot of pitches for "Steam competitors" in my inbox. 99% of them are doomed to failure, but the worst part is the vast majority are doomed before they even start. It continually amazes me how many people are able to invest so much time, effort, and money into a serious business venture without first surveying the impossible task before them.

So let's begin. Here's how you can build a successful business that competes directly with Steam:


You've probably heard of Blue Ocean Strategy -- Nintendo famously did it with the Wii, and by all accounts are repeating the exercise with the Switch. Instead of joining a giant feeding frenzy of sharks where you have to fight for your life just to grab a tiny piece (a "Red Ocean"), you swim out to some pristine fishing grounds the other sharks haven't found yet and feast all by yourself.

This is not to say that in principle I think nobody should ever try to compete with Steam. The marketplace definitely needs the competition, and I'm very open to hearing ideas about how to make things better for everyone.

I'm just saying that if I was an investor considering your pitch, I'd run.

Being Better Isn't Good Enough

For whatever reason, you've decided not to take my advice and you're still going to take on Steam, either head-on, or trying to mix it up with some neat gimmick.

Unfortunately, you can't just build a better mousetrap, because you'll be absolutely murdered by Steam's impenetrable network effects. Even if every aspect of your service is better than Steam's in every possible way, you're still up against the massive inertia of everybody already having huge libraries full of games on Steam. Their credit cards are registered on Steam, their friends all play on Steam, and most importantly, all the developers, and therefore all the games, are on Steam.

Furthermore, despite all of the constant (and justified!) complaints everyone has about Steam's services, you're kidding yourself if you think you, as a startup, are going to do a better job on every single one. For one, there's no way in hell you're going to be able to manage the amount of traffic and server load they do. Second, you don't have the institutional memory and processes built up over years and years to deal with all the crazy edge cases, hacking, and general abuse of your system.

But okay, you're going to start small so you don't need to deal with all that stuff just yet. And let's grant that somehow, miraculously, you're going to start with a service that is every bit as good as Steam's. Okay, here's what you have to do to not get shot in the face before you even arrive at the starting line.

Minimum Requirements to Not Fail Right Away

If you've set yourself on this task, and you haven't read Joel Spolsky's Strategy Letter II: Chicken or Egg Problems, go read it now. Re-read it every morning. This is the heart of your problem and all your challenges flow from this. Memorize it.

You need customers. You can't get those customers without a lot of big, popular, games. You can't get developers to upload those games without customers. You can't get customers without games.

So your path to not fail before you even start looks something like this:

  1. Straight up bribe developers to post their games
  2. Posting games must be zero-friction
  3. Straight up bribe players to use your system
  4. Playing/buying games must be zero-friction

You have to do all four of these things, and nail every single one, just to begin. Do that and your chances of success rise from a flat 0% to an impressive ~1%, rounded up.

Bribe developers

Steam competitors are slowly starting to realize this. I used to get pitches that offered the familiar 70/30 revenue split, but they would "Solve Discovery", or would "give us lots of attention". Translation: "You'll have all four of our customers all to yourselves because nobody else wants to be on our store, and we'll give you some sweet shout-outs on Twitter!"

Yeah no thanks.

Look, if you're offering a 70/30 split in this day and age you're delusional. You have to earn that 30% cut, and the way you earn it is by having a big audience and a lot of hungry customers. Personally speaking, a store with the market size of GOG is my cutoff point for 30%. If you're not even as big as GOG, asking for 30% is laughable.

What about 80%?

Not good enough.

How bout 90%?


Umm... 95%?

Look sweetie, here's the thing. There's already a store out there that offers 100% revenue share. It's called Itch.io. Big name developers aren't exactly crawling over each other to post their games there, but if the only thing I'm considering is revenue share, Itch has already got you beat. AND, Itch probably already has you beat on a bunch other metrics too.

But I have to ask for something!

I totally sympathize. But look here -- Itch, that loveable small-time Indie boutique, is run by two guys as a lifestyle business. They don't have investors. They don't really care if they ever beat Steam. They make enough to keep on going, and they'd rather build something cool than try to grow big fast (which is honestly a super refreshing approach these days).

You, on the other hand, probably do have investors. And God help you if they're VC, because they want to see a 10X return. If you merely do kinda well, they'll consider it a failure, so your only path to victory is a blowout success. You need growth. You need to get developers on board, now.

So just give developers money already. You've got money, right? Truckloads of it? Great -- that's the cost of entry for this business.

Go find the developers with the shiniest games and straight up pay them to put their games on your system. And no, developers don't want coupons or vouchers or Bitcoin, they want cash money $USD.

Great, you've greased some palms. Now it's time to grease the wheels.

Zero Friction for Developers

You're gonna have your work cut out for you to have a service that's even as good as a small timer like Itch.

Believe it or not, Itch has some excellent developer tools. Honestly, probably the best in the whole business. Not only do they have a super easy web-based uploader, but their command line tools, Butler and Wharf, are best in class too. They far exceed what I've seen from Steam, Gog, and Humble in terms of ease of use, speed, efficiency, and reliability. There's currently no easier or faster store to upload your game to than Itch.

You're going to need to be at least as fast and easy. Because even though Itch will let me take 100% of revenue, and has amazing tools that I recommend to everyone who will listen, I still find it a pain to go over to Yet Another Storefront and upload Yet Another Build whenever I issue a new patch. This mental friction takes a real cost, especially when I have a Windows, Mac, and Linux build to patch.

You as Yet Another Storefront get this mental friction simply by existing. The deck is already stacked against you. All you can do is add as close to zero as possible to it.

EDIT: Oh, and if you're designing your API? You need a really good reason for it to not look exactly like Steam's. Actually, no, you don't. There is no good reason. It needs to look exactly like Steam's, ideally being a drop-in replacement for the dll (copyright laws allowing). A developer needs to spend as close to zero seconds as possible reconfiguring their game for your system. If they have to recompile a special build just for you it's gonna be tough going.

Bribe Players

Okay, let's say you've spent your war chest on attracting developers with big awesome games that people want to play. You've also made the best, most amazing backend possible for developers so whenever they mumble in their sleep their game is automagically uploaded to your servers, and a rainbow colored slip-and-slide unfurls ready to direct a torrent of cash money dollars into their bank account.

Even with all the awesome best latest newest games on your system, and developers totally on board, you still need to drag players kicking and screaming over to your system. Because all their games, and all their friends, and all their workshop mods, and all their everything is currently on Steam.

So, make it worth their while. But how?

Money works, but that can be tricky -- every other store already offers more discounts than quintuple coupon day at Wal-Mart, and trying to undercut them on retail price won't work either, because it's an industry standard to put price-matching clauses in distribution contracts.

Well, you can just give players money, or coupons, or vouchers, or microtransaction cash, or whatever, but this is tricky too. First of all, opening an offer like this up to a general audience is asking for scammers and bots, and second, you can't undermine your developers. If you want to give games or in-game awards away for free, or let people buy them with vouchers, the developer is going to want that treated as a real sale. Otherwise what's the point? If they want to give stuff away for pennies, they could just go in a Bundle (which are themselves way past their prime).

My point is, you need to offer players a real incentive to switch over to your platform, and whatever that is, it's certainly going to cost you money.

Zero Friction for Players

Okay, you've got your developers, you've made the best backend possible, you're offering great player incentives. Now players need to just actually show up and start spending money.

Great, now you just need to build a game client that's every bit as good as Steam, or Itch, or GOG Galaxy, because by now you've surely realized you're not just competing with Steam, you're competing with everyone. This is going to be super hard, because all of those companies have invested tons and tons of time and effort into their clients, and people still complain about all their problems, and you're a startup that so far has a product with exactly zero hours of being live and tested by the real world.

And here's another problem -- if you went head on against Steam instead of coming up with some cool and zany alternate means of experiencing games, you went and built a download client. I've already got the Steam, Itch, and GOG Galaxy clients installed, and that probably puts me in like 0.1% of the total game playing population. Nobody wants to install things these days. And even if they do, you'd better make sure it's rock solid.

A lot of the most important things about a client are on the backend of it -- things like downloading, applying patches, installing, dealing with overaggressive antivirus, etc. And there's tradeoffs -- you can optimize things for players by insisting on a certain type of game binary package from developers, but that adds friction on the developer side. And if you accept just any old random file (a .zip, a .rar, a .tar.gz, an NSIS Windows installer), if you don't standardize and process all that nonsense then the player has to deal with it. Steam and maybe GOG can get away with more obtuse delivery formats and pipelines because they've got some actual size to them, you can't.

And by the way, Itch is already way ahead of you on accepting any random garbage format, unpacking it and making sense of the contents, and spitting a convenient user experience out the other end. Given that Itch's stuff is all open source, if I get even one hint that you've decided to roll your own entire pipeline from scratch, I'm gonna call up your investors and your parents to tell them you've got a deadly case of Not Invented Here Syndrome and recommend immediate quarantine.

What You Really Need

Okay, you've read all that and you still want to compete with Steam? You're sure you don't want to try something else that might make you richer and happier, like, I dunno, join a monastery and take a vow of eternal poverty and lifelong fasting?

Okay then.

You've done all the minimum things you need to do to Not Fail Immediately. You've dodged all the bullets on your long walk to the edge of the diving board and you're ready to jump head-first into an ocean full of hungry sharks. You are now worthy of the secret. Here's what you really need to compete with Steam.

Super Powers

That's right. You need something so special and crazy and unique to you that no other company can do it, or at least nowhere near as well as you. Notice I said Super Powers, plural. You're gonna need more than one. Because that's what your competition has.

  • Steam is Steam and has all the games and all the players and all the money.
  • GOG has retro games, and retro gamers, and also CDProjekt Red.
  • Amazon has Twitch and Amazon Prime and Jeff Bezos, who cannot be killed until the six horcruxes scattered across the galaxy are gathered and cast into the fires of Mount Doom.
  • Blizzard has all the AAA Blizzard games and all the money.
  • Origin has all the AAA EA games and all the money.
  • TenCent has one Metric China of customers, a special relationship with their government, and all the money.
  • Humble is at least as good as you at most things and already has a bunch of people locked into a fancy little subscription service and they give more money to charity than you.
  • Itch has the best tools and lowest overhead, and also by the way the devotion of all the scrappy small-time indies you thought were free for the taking.

Good luck out there, and mind the sharks.

Discuss this on Hacker News

Read the whole story
1410 days ago
Share this story

Opera 50 Beta RC with Cryptocurrency Mining Protection

1 Comment

Hello everyone,

Opera’s big number 50 release is edging closer to its stable release. Today, we are delivering the release candidate, which includes an innovative anti-Bitcoin mining feature, extended VR360 support for Oculus, and Chromecast.

So please check Opera 50 beta RC out and let us know how it works!

NoCoin – Cryptocurrency Mining Protection

Bitcoins are really hot right now, but did you know that they might actually be making your computer hotter? Your CPU suddenly working at 100 percent capacity, the fan is going crazy for seemingly no reason and your battery quickly depleting might all be signs that someone is using your computer to mine for cryptocurrency.

This cryptocurrency mining can sometimes continue after you have first visited the site. But we, as the only major browser with an integrated ad blocker, have a built-in solution to keep miners from trespassing onto your machine.

After we recently updated the rules for our built-in ad blocker mechanism, we eliminated cryptocurrency mining scripts that overuse your device’s computing ability. Simply enable Opera’s ad blocker to prevent cryptocurrency mining sites from doing their dirty work on your computer.

You can find and change NoCoin in Settings (Preferences on macOS) > Basic > Block ads and under the Recommended lists of ad filters.

With NoCoin turned on, pages embedded with cryptocurrency mining scripts will be blocked in a similar way our mechanism blocks ads.

Changelog is here.

Have fun testing and Happy Holidays!!

Chromium was updated to version 63.0.3239.84 .

Installation links:

Read the whole story
1443 days ago
Doubt that Berners-Lee ever thought weʼd eventually have to add tech to our Web browsers to prevent them from mining for cryptocurrency.
Share this story

Introducing SourceTree for Windows – a free desktop client for Git


The SourceTree team is thrilled to announce the latest addition to our family Atlassian distributed version control system (DVCS) family –SourceTree for Windows.

For some time now many Windows developers have been requesting a native counterpart to the SourceTree Mac desktop client. Windows developers, say goodbye to the command line and use the full capabilities of Git through SourceTree’s beautifully simple interface (and stop being jealous of what your Mac friends are using).

Download SourceTree for Windows


A simple, powerful Git client

SourceTree for Windows a git client

SourceTree for Windows simplifies how you interact with Git repositories so you can focus on coding.

  • Get your team up and running using common Git commands from a simple user interface
  • Manage all your Git repositories, hosted or local, through a single client
  • Put Git commands at your fingertips: commit, push, pull and merge with just one-click
  • Use advanced features such as patch handling, rebase, shelve and cherry picking
  • Connect to your repositories inBitbucket, Stash, Microsoft TFS or GitHub

Perfect for Git newbies

SourceTree toolbar

SourceTree was built to make Git approachable for every developer – especially those new to Git.Every Git command is just a click away using the SourceTree interface.

  • Create and clone repos from anywhere
  • Commit, push, pull and merge
  • Detect and resolve conflicts
  • Search repository histories for changes

Visualize your repositories

SourceTree keeps track of code activity and provides an at-a-glance view of everything from projects to repositories to changesets.

Visualize your Git repos

Use SourceTree’s Bookmarks to get a real-time, aggregated view of all your projects and repositories. Jump directly to the changeset graph to visualize tovisualize changesets across multiple branches and forks.

Powerful enough for Git veterans

Diff view

SourceTree makes Git simple for everyone, but also makes Git experts faster and more productive. Review your outgoing and incoming changesets, cherry-pick between branches, create and apply patches, rebase, shelve changesets and more with lightning speed.

Git one-stop shop

Atlassian offers a full complement of tools that will help you and your dev team make the most of Git. Whether you’re working on Mac or Windows, behind the firewall or in the cloud, Atlassian’s family of Git tools will bring you the power of Git while making adoption a breeze.

Connect to the cloud or behind the firewall


Clone from Bitbucket or Stash right into SourceTree

Thanks to hosting services like Bitbucket, many small teams working with Git repositories begin coding in the cloud. Connect SourceTree to Bitbucket’s free unlimited private repositories to easily manage your Git repositories from the SourceTree interface.

Stash, Atlassian’s Git repository manager for Enterprises, makes it simple to manage your Git Server – behind the firewall. With powerful two-way integration, Stash and SourceTree make it easy for your team to develop with Git. SourceTree can discover and fetch your Stash repositories. And one-click clone operations get you the source you need fast.

If you don’t have Stash or Bitbucket yet, not a problem, SourceTree for WIndows works with any Git repository, including GitHub, Microsoft Team Foundation Server or your own Git server.

What’s coming next?


We received great feedback from the SourceTree for Windows private beta users (a huge thank you). We will continue to push frequent updates and features to SourceTree for Windows users. We plan to bring all the great features that are part of SourceTree for Mac to Windows as well. What can you expect in the near future:

  • Mercurial support
  • Git-flow support
  • Custom actions
  • JIRA integration
  • and heaps more


We will continue to push out frequent releases for the Mac client. Stay tuned for an upcoming release featuring:

  • Interactive rebase support
  • Updated icons
  • Desktop notifications

Get SourceTree for Free!

If you’re new to Git, or just want a handy tool to make you even faster, download SourceTree – it’sfreeat our brand spankin’ new website.

Download SourceTree for Windows

Read the whole story
3180 days ago
Waiting for Mercurial support...
Share this story
1 public comment
3181 days ago
This looks like fun.

How to expose async methods in a Windows Runtime Component

1 Comment

We need to follow precise rules when we develop a Windows Runtime Component. One of the most important is that we have restrictions on the types that can be exposed. For example, we can’t have public methods that return Task.

Suppose we have the following class inside a Windows Runtime Component:

public sealed class MyLibrary
    public async Task<string> GetUriContentAsync(string uri)
        var httpClient = new HttpClient();
        var content = await httpClient.GetStringAsync(uri);

        return content;

When we compile it, we’ll obtain the following error message:

Method ‘MyRuntimeComponent.MyLibrary.GetUriContent(System.String)’ has a parameter of type ‘System.Threading.Tasks.Task’ in its signature. Although this generic type is not a valid Windows Runtime type, the type or its generic parameters implement interfaces that are valid Windows Runtime types. Consider changing the type ‘Task’ in the method signature to one of the following types instead: Windows.Foundation.IAsyncAction, Windows.Foundation.IAsyncOperation, or one of the other Windows Runtime async interfaces. The standard .NET awaiter pattern also applies when consuming Windows Runtime async interfaces. Please see System.Runtime.InteropServices.WindowsRuntime.AsyncInfo for more information about converting managed task objects to Windows Runtime async interfaces.

In particular, the message suggests us to “Consider changing the type ‘Task’ in the method signature to one of the following types”.

So, we need to return one of the allowed return types. An extension method defined on Task type greatly simplifies this. The idea is to creat a Task as usual, and then invoke this extension method to obtain a type that is valid for a Windows Runtime Component:

public sealed class MyLibrary
    public IAsyncOperation<string> GetUriContentAsync(string uri)
        return this.GetUriContentAsynHelper(uri).AsAsyncOperation();

    private async Task<string> GetUriContentAsynHelper(string uri)
        var httpClient = new HttpClient();
        var content = await httpClient.GetStringAsync(uri);

        return content;

The original GetUriContentAsync method is now a private helper method. Note that, as long as methods in Windows Runtime Component aren’t public, we don’t have any restrictions on return types. So, in this case it’s perfecly legal to return a Task.

Then, in the new version of GetUriContentAsync, we invoke the AsAsyncOperaion extension method on the result of GetUriContentAsyncHelper to obtain an IAsyncOperation object. It is a valid Windows Runtime return type that represents an asynchronous operation.

In this way, in a Windows Store app we can write something like this:

private async void button_Click(object sender, RoutedEventArgs e)
    MyLibrary lib = new MyLibrary();
    var content = await lib.GetUriContentAsync("http://marcominerva.wordpress.com");

    // ...

Read the whole story
3180 days ago
Taking note. #winrt
Share this story