Solving API Performance Issues with Cross Domain Ajax - javascript

I'm in the process of building out an infrastructure to support a gaming platform we intend to scale out to hundreds of thousands of users. Since this is in the entertainment / gaming industry, we are expecting a heavy load from each user session, therefore, performance is of upmost importance.
We are trying to parallelize as much of the architecture as possible, meaning API, databases, and applications run off of different servers that can be horizontally scaled. One of the applications is a web app, and we're having the most trouble with this due to a specific scenario involving the same origin policy on legacy browsers.
This application running in the web browser will need speedy access to the models only available through the centralized API. While this is great for our dedicated mobile clients, browsers unfortunately need fully CORS support to interface directly with our API. This is problematic because some of the HTTP verbs are not supported on all browsers (put / delete). Our only known workarounds are, rewrite the API to create more abstraction (we believe this is not a best practice and will increase development time and potentially performance) and work with only POST using JSONP or create a proxy (which will add an extra two leg to the trip and double the latency performance).
Bottom line is, we have boiled this question down to... are these the only two options, or is there something else we aren't considering, and if so, which of these solutions would be better suited to a gaming platform.

Another option to consider is JSONP. By wrapping a JSON response to enable it to be loaded as a script tag, you can avoid problems with the same origin policy.
I can't speak to performance issues of your specific application without knowing the app in detail. I would think that you would see similar performance on the server with JSONP, since your major difference over other methods would be that you are concantenating an extra string.

SOP should not be the problem. Use JSONP for domain-across requests. Wrapping the answer in in a callback method should not be the problem for your server-side part and sould be transparent for the rest of the application. Doesn't break REST style. On client-side library the use of JSONP should also be transparent for the rest of the application.
So, what's about PUT and DELETE? Simply perform a POST and set the X-HTTP-Method-Override header with the intended method. Your webservice handler on the serverside should recognize the header and imply the request with the method from the header. All transparent to the rest of the application.

While JSONP certainly does have "universal" support - it's still a bit hacky and has a few negative side effects: mainly that you can't capture errors.
The reason JSONP works everywhere is because requests made by the script tag fall within the confines of a "simple request", as defined by the CORS specification.
My point? Instead of using JSONP, you could also modify your API (or at least the most commonly accessed parts of it) to fit within the confines of a simple request. Then you get full ability to handle errors without any of the performance impact of preflight requests.
For the places you must use preflight requests, you can cache the preflight responses.
I have a full write up on this technique at Two Strategies for Crossing Origins with Performance in Mind

Related

Offline Version of Single Page Applications

What are the techniques and the tools, libraries and frameworks necessary to make a SPA in java (and javascript)?
Consider an application served by a server A. This server might go offline.
What I need is a partially functional, read-only version of that application on a second server B, but fully navigable.
Server B can only serve static files: html, css, js, images.
Server A has access to server B and can push data to it as required and on a regular basis.
My second requirement is to suffer as less as possible from vendor lock-in, so I should be using as little frameworks as possible.
The third requirement is: there should be no necessity of any tool on the client's side, in the browser.
Please list the possible techniques, and where applicable, also at least one tool/framework/library, so I can search for alternatives to that one if, for whatever reason, it doesn't fit my bill.
If you accept any client-side code:
Yes, the best answer are service workers.
You can read about various caching techniques on Jake's site
Easiest plugin to make your website accessible offline is https://github.com/GoogleChrome/sw-precache.
Service workers are framework-agnostic, you can use them with all frameworks or without one in JavaScript.
You will need typical backend (Java/PHP?) or even static html files, and JavaScript client-side code.
If you don't accept any client-side code and accept 3rd parties:
The only solution is to have some kind of proxy like CloudFlare - your DNS will point to CloudFlare, and they you set up what will happen.
If you don't accept any cliend-side code and don't accept 3rd parties:
If you want your solution exactly as you've described, you should use some kind of load balancer like HAProxy (http://www.haproxy.org/), which will route your traffic to failover server. You can read about this here: http://blog.haproxy.com/2013/12/23/failover-and-worst-case-management-with-haproxy/

When do you want more/less http requests? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
It seems like to have you page load fast, you would want a series of small http requests.
If it was one big one, the user might have to wait much longer to see that the page was there at all.
However, I'v heard that minimizing your HTTP requests is more efficient. For example, this is why sprites are created for multiple images.
Is there a general guideline for when you want more and when you want less?
Multiple requests create overhead from both the connection and the headers.
Its like downloading the contents of an FTP site, one site has a single 1GB blob, another has 1,000,000 files totalling a few MB. On a good connection, the 1GB file could be downloaded in a few minutes, but the other is sure to take all day because the transfer negotiation ironically takes more time that the transfer itself.
HTTP is a bit more efficient than FTP, but the principle is the same.
What is important is the initial page load, which needs to be small enough to show some content to the user, then load additional assets outside of the user's view. A page with a thousand tiny images will benefit from a sprite always because the negotiations would not only cause strain to the connection, but also potentially the client computer.
EDIT 2 (25-08-2017)
Another update here; Some time has passed and HTTP2 is (becoming) a real thing. I suggest reading this page for more information about it.
Taken from the second link (at the time of this edit):
It is expected that HTTP/2.0 will:
Substantially and measurably improve end-user perceived latency in
most cases, over HTTP/1.1 using TCP. Address the "head of line
blocking" problem in HTTP.
Not require multiple connections to a server to enable parallelism,
thus improving its use of TCP, especially regarding congestion
control.
Retain the semantics of HTTP/1.1, leveraging existing documentation
(see above), including (but not limited to) HTTP methods, status
codes, URIs, and where appropriate, header fields.
Clearly define how HTTP/2.0 interacts with HTTP/1.x, especially in
intermediaries (both 2->1 and 1->2).
Clearly identify any new extensibility points and policy for their
appropriate use.
The bold sentence (emphasis mine) explains how HTTP2 will handle requests differently from HTTP1. Whereas HTTP1 will create ~8 (differs per browser) simultaneous (or "parallel") connections to fetch as much resources as possible, HTTP2 will re-use the same connection. This reduces overall time and network latency required to create a new connection which in turn, speeds up asset delivery. Additionally, your webserver will also have an easier time keeping ~8 times less connections open. Imagine the gains there :)
HTTP2 is also already quite widely supported in major browsers, caniuse has a table for it :)
EDIT (30-11-2015)
I've recently found this article on the topic 'page speed'. this post is very thorough and it's an interesting read at worst so I'd definitely give it a shot.
Original
There are too many answers to this question but here's my 2cents.
If you want to build a website you'll need few basic things in your tool belt like HTML, CSS, JS - maybe even PHP / Rails / Django (or one of the 10000+ other web frameworks) and MySQL.
The front-end part is basically all that gets sent to the client every request. The server-sided language calculates what needs to be sent which is how you build your website.
Now when it comes to managing assets (images, CSS, JS) you're diving into HTTP land since you'll want to do as few requests as possible. The reason for this is that there is a DNS penalty.
This DNS penalty however does not dictate your entire website of course. It's all about the balance between amount of requests and read- / maintainability for the programmers building the website.
Some frameworks like rails allow you to combine all your JS and CSS files into a big meta-like JS and CSS file before you deploy your application on your server. This ensures that (unless done otherwise) for instance ALL the JS and ALL the CSS used in the website get sent in one request per file.
Imagine having a popup script and something that fetches articles through AJAX. These will be two different scripts and when deploying without combining them - each page load including the popup and article script will send two requests, one for each file respectively.
The reason this is not true is because browsers cache whatever they can whenever they can because in the end browsers and people who build websites want the same thing. The best experience for our users!
This means that during the first request your website will ever answer to a client will cache as much as possible to make consecutive page loads faster in the future.
This is kind of like the browser way of helping websites become faster.
Now when the brilliant browserologists think of something it's more or less our job to make sure it works for the browser. Usually these sorts of things with caching etc are trivial and not hard to implement (thank god for that).
Having a lot of HTTP requests in a page load isn't an end-of-the-world thing since it'll only slow your first request but overall having less requests makes this "DNS-penalty" thing appear less often and will give your users more of an instant page load.
There are also other techniques besides file-merging that you could use to your advantage, when including a javascript you can choose it to be async or defer.
For async it means the script will be loaded and executed in the background whenever it's loaded, regardless of order of inclusion within HTML. This also pauses the HTML parser to execute the script directly.
For defer it's a bit different. It's kind of like async but files will be executed in the correct order and only after the HTML parser is done.
Something you wouldn't want to be "async" would be jQuery for instance, it's the key library for a lot of websites and you'll want to use it in other scripts so using async and not being sure when it's downloaded and executed is not a good plan.
Something you would want to be "async" is a google analytics script for instance, it's effectively optional for the end-user and thus should be labelled as not important - no matter how much you care about the stats your website isn't built for you but by you :)
To get back to requests and blend all this talk about async and deferred together, you can have multiple JS on your page for instance and not have the HTML parser pause to execute some JS - instead you can make this script defer and you'll be fine since the user's HTML and CSS will load while the JS parser waits nicely for the HTML parser.
This is not an example of reducing HTTP requests but it is an example of an alternative solution should you have this "one file" that doesn't really belong anywhere except in a separate request.
You will also never be able to build a perfect website, nor will http://github.com or http://stackoverflow.com but it doesn't matter, they are fast enough for our eyes to not see any crazy flashing content and those things are truly important for end-users.
If you are curious about how much requests is normal - don't. It's different for every website and the purpose of the website, tho I agree some things do go over the top sometimes but it is what it is and all we have to do is support browsers like they are supporting us - Even looking at IE / Edge there since they are also improving (slowly but steady anyways).
I hope my story made sense to you, I did re-read before the post but couldn't find anything while scouting for irregular typing or other kinds of illogical things.
Good luck!
The HTTP protocol is verbose, so the ratio of header size to payload size makes it more efficient to have a larger payload. On top of that, this is still a distributed communication which makes it inherently slow. You also, usually, have to set up and tear down the TCP connection for each request.
Also, I have found, that the small requests repeat data between themselves in an attempt to achieve RESTful purity (like including user data in every response).
The only time small requests are useful is when the data may not be needed at all, so you only load it when needed. However, even then it may be more performant to.simply retrieve it all in one go.
You always want less requests.
The reason we separate any javascript/css code in other files is we want the browser to cache them so other pages on our website will load faster.
If we have a single page website with no common libraries (like jQuery) it's best if you include all the code in your html.

Are there any reasons to mix WebSockets and XHR?

I am developing a SPA - some of the features require real time bidirectional communication and some do not.
Are there any reasons for mixing XHR and Websockets here?
I suspect since I need to use WebSockets anyway, just using WebSockets for everything makes the most sense, but I'm wondering if there are any considerations I haven't taken into account.
It depends on what the outcome of the XHR request is compared to the websocket connection? Websockets are generally faster by not creating a HTTP header and allow a much larger amount of data to be transferred.
From experience I would work incredibly hard on making all requests / transactions in an application the same - applying DRY principles can make your and everyone else who has to work on the project lives a lot easier.
This really depends on what you are doing in your application. You've hit the nail in the head with this statement:
some of the features require real time bidirectional communication and some do not.
If you need a real time full duplex communication channel then resorting to polling, long-polling, streaming, etc hacks over HTTP just to keep the same king of API everywhere might be a pain.
The same goes for websockets. If you are using websockets in one place switching everything to websockets to have the same API everywhere might turn out to be a pain.
Websocket technology is still maturing, it does not yet enjoy a full set tools or frameworks as Ajax (HTTP) does. A lot of server-side and client-side frameworks deal easily with RESTful APIs accessed over Ajax. Not quite so for websockets yet. For this reason for a large set of use cases it makes sense to stick with Ajax and use websockets only where necessary.
There is also the difference in style. In a RESTful API you are navigating resource URLs, in websocket you only have one endpoint that receives commands. If you can fit all interactions in one style then use one style, just make sure you are not loosing something from the tools/frameworks still centered around Ajax/HTTP.

Output caching - is it still viable?

I've had quite a few goes at Googling an answer to this, but have been unable to find one that satisfies the question.
I'm using C# with web forms. I have many opportunities to cache pages such as Privacy, Terms etc, since they hardly ever change.
However, I'm unsure on the effect of javascript when combined with output caching. I understand about fragment caching, donut caching et al, but with Ajax, jQuery and now Polymer, this client side stuff isn't going anywhere.
So can output caching be used in tandem with client side technologies or has the facility to use output caching now disappeared forever?
Sure you can use Web.Forms output caching and non-cached Ajax requests together, for example making an Ajax request you can easily add some parameter to JS AJAX request that will be filled with current timestamp:
GET http://example.com/api?method=getUsers&_t=1428927438
Each API call has unique variable/parameter that prevents caching
If anything, it's even easier.
Using client-side script allows the combination of different elements with different cache policies on the same page.

Is application/json-p text/json-p already implementable?

I've read http://www.json-p.org/ which states a safer and stricter subset of JSON-P.
The most critical piece of this proposal is that browser vendors must
begin to enforce this rule for script
tags that are receiving JSON-P
content, and throw errors (or at least
stop processing) on any non-conforming
JSON-P content.
My question is Is that subset of JSON-P already implementable?
No, there is no current way to implement/enforce what is proposed, as changes to how browsers process the script tag are required. If you really wanted to implement the proposal, you could build a proxy service on your server which does the JSONP verification for you.
The only real problem this proposal is trying to solve is to make JSONP requests more secure for consumers of JSONP enabled services. However, I honestly think this security problem is a non-issue.
As long as web service consumers are using trusted JSONP services, there is no JSONP specific security threat. If you think the service you are consuming might be untrustworthy, simply don't use it. You can find an alternative service or proxy the untrustworthy service through your own server to clean/verify the response.
The same vulnerabilities which exist for JSONP also exist for ordinary script tags. People link to third party JavaScript libraries all the time with few issues. As an example, people everywhere use Google's copy of jQuery. Google could easily poison this file and fish user data from any webpage which uses this library.
The moral of the story: Only use APIs/services you trust

Categories

Resources