My work and readings have lead me through a lot of things related to the simultaneity of connections from a browser (client) to a web server and the HTTP context in which all that happens. It is still a bit difficult for me to find the time to put all that in order, but below are a few good reads on the topic.
Respect for HTTP limits
First of all, you should know that HTTP 1.1′s RFC says (between many other things) that “a single-user client SHOULD NOT maintain more than 2 connections with any server or proxy”. This explains a lot as to why some websites can be very slow, while others can be very fast. It doesn’t explain, though, why a browser queues one single request to a server when it’s a request to a full page, but I can imagine this is a corrolary to this part of the HTTP’s RFC.
In any case, what that means is that, if you load a page from a web server and all the CSS, JS and images on this web server are located under the same domain name, you will only ever be able to download 2 at a time. When one resource has downloaded completely, your browser will be able to initiate the call to another resource. This sometimes makes websites appear “bit by bit” in an upsetting manner.
Now browsers used to respect that recommendation in the past, but that tended to limit the viewing speed of a website, so browsers developers started to allow for more. Today, for example, you can load the “about:config” page in Firefox and look for the network.http.max-persistent-connections-per-server variable. You will see it is set to 6 (which is the default now in Firefox). You can pretty much set it to 20 if you like, but beware that this is not necessarily the best setting (it might make it difficult for your browser to manage that many downloads at a time).
So, in conclusion, your browser is limited to 6 downloads (sometimes 4, sometimes 8) at a time, by default, although the standard says they should limit it to 2.
And this is why major websites have started multiplying the number of CDN domains they use: if the browser is limited to 6 downloads at a time *by domain*, why not multiplying the number of domains?
Well, it’s true: by increasing the number of domains (and these can also be subdomains), you increase the total number of files a single user can download, thus potentially increasing the download speed for your website.
What’s more, if you spread these domains between several web servers, you provide a spread bandwidth and the speed is further improved.
If you abuse this system though, you might get a reverse effect: the time it takes to resolve the IP addresses of all these domains might increase the load time for your site.
This is why some techniques are available to cover that last problem (which isn’t to say that you should use 20 different domain names for your site), whereby you can ask the browser to “prefetch” the translation of domain names to IP addresses while the other domain names haven’t been asked for yet. You do that by adding prefetch instructions into your HTML header section. This is apparently implemented by most browsers.
You can also hire a specialized service that makes CDNs resolution super-fast, which can save up to 500ms on connections to your website.
Manually user-level multi-threading PHP (sort of)
Something that is not directly an extension of the previous topics is that a web server will only execute one PHP process on one single core of a multi-core processor, so if you want to load a very heavy script two times in parallel, you’ll have to take into account that your browser will try to limit the number of concurrent connections to a server and actually queue them (one by one), which means it will be impossible for you to execute simultaneous requests and use the 16 cores of your super Xeon XYZ processor.
In order to “hack” this process, you can start several browsers at the same time. This will work (but there are only so many different browsers you can install on one computer). An extension to this is that you can start individual Firefox sessions by launching (on the command line or in your ini script) it this way: firefox –no-remote -ProfileManager. This way, you can manage 4 different Firefox sessions and even overload your server if your computer can manage more simultaneous instances of Firefox.
This is all for today. I’ll leave you with a few references which have helped me working out these details
Translating a web application is not an easy task (although it might seem so). Or rather, translating it well is not easy.
Using tools like gettext will help you, of course, but past the tools, there are a few things that do not seem to be well understood by web developers with little experience in foreign languages.
In this series of articles, I’ll try to give one example at a time of how to make a perfect translation.
In this first lesson, we’ll talk about the string identifiers, or the name of the translated item.
For example, let’s say you want to translate the string “Title” to many languages, so that when your users come to your page, they will see “Title” if they use your English version, and “Titre” if they use your French version.
Of course, you want to make sure most of the translators understand, from the identifier of the string itself, what this string refers to. For example, you could name it $title. Pretty clear, pretty obvious.
To avoid having lots of different ways to represent translateable strings, you should define a clear convention from the start. Something about using UpperCamelCaseToRepresentYourString or lower_camel_case_to_represent_your_string, or even ‘a pure text identifier always considered as an array index’. I have read once that, if you have to choose between UpperCamelCase and lower_camel_case, non-native English speakers have more difficulty understanding UpperCamelCase because it is more difficult to split the words (visually).
This being said, read the following before establishing your conventions…
Clashing with local variables
Oh but… wait… if you use “$title” kind-of-identifiers, then how are you going to do when you have to use a string identifier that you are already using for the computational elements of your script? Surely, there must be something to do about it…
Well yes, you can decide on 2 options here, which imply creating the notion of namespace, that is create identifiers that will be easily recognized as being part of a group, somehow:
* use one (or several) array(s), of which each index is the identifier (like $t['title'] = ‘Title’;)
* use prefixes to your variables (like $translate_title or $t_title = ‘Title’ to make it short)
Now wether you use namespaces or not, and whether you use upper camel case or not, you will have a problem when it comes to differentiate: ‘Title’ from ‘title’. You know, it so happens that some times you have to put a specific text element between parenthesis, and in this case you will need to put it in lowercase.
A quick solution to this is to use the strtoupper() and strtolower() strings in PHP, which allow you to put something in lower case or in upper case. There’s even a function to uppercase only the first letter. But that will not help one you start to have more than European languages, or when you end up in a tricky situation.
In terms of translations, it is generally accepted that you should try to define the different cases in different terms, and not try to programmatically convert strings to what they are not because, in some language, it will not be possible or logical to do so.
As such, try to be specific about your strings. If you really need to make a difference (for the term meaning or correctness), then indicate a suffix to your identifier, insisting on the fact it should we lowercase, uppercase or capitalized (in the last case, only the first letter is uppercase).
For example: $t_TitleItem_lower. This doesn’t break your convention, because the term is still identified by ‘TitleItem’, but you are giving something more of precision.