-
-
Notifications
You must be signed in to change notification settings - Fork 14
/
2011-accelerer-navigation-3g.html
226 lines (195 loc) · 10.6 KB
/
2011-accelerer-navigation-3g.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
---
title: 'Accélérer la navigation sur le web en 3G'
uuid: 3870852e-8399-48b9-93dd-0542cc0a9006
tags:
- outdated
- web
---
Mon portable disposant d'une connectivité 3G, j'ai décidé de prendre
l'abonnement le plus économique possible sans que celui-ci soit limité
en temps. J'ai finalement opté pour un abonnement à 10 € pour 250 Mio par
mois chez SFR.
# Proxy transparent et optimisant selon SFR
En naviguant un peu sur le site [Le Monde][lemonde], j'ai remarqué que
certaines requêtes étaient destinées à des IP du type
`10.141.0.4`. J'ai regardé rapidement avec les outils adéquats de
Chromium (onglet « Réseau ») ce que cela signifiait. Toutes les
images étaient servies depuis l'IP en question. Un proxy transparent
(repérable à l'entête `Via` qu'il ajoute) avait réécrit les balises
`<img>`. Les images ainsi servies étaient identiques aux originales
pour les plus petites ou de qualité réduite pour les autres.
Les balises `<style>` et `<script>` recevait également un traitement
de choc quand elles pointaient sur des ressources externes : le
contenu était reporté à l'intérieur du fichier HTML. Avant :
::html
<script src="http://s1.lemde.fr/js/lib/jquery/1.5.1/jquery.js"></script>
Après :
::html
<script oldSrc="http://s1.lemde.fr/js/lib/jquery/1.5.1/jquery.js" NG="replaced">
/*!
* jQuery JavaScript Library v1.5.1
*
* Copyright 2011, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
* […] */
</script>
Cela signifie que si un site fait appel à [jQuery][jquery], une
bibliothèque JavaScript très populaire, on se retrouve à télécharger
l'intégralité du code dans chacune des pages, soit un surpoids de 85 Kio !
Tous les navigateurs modernes supportent les
[connexions HTTP persistantes][keepalive] qui permettent de demander
plusieurs ressources au sein d'une même requête, ce qui est fort utile
dès que la latence augmente un peu. Il y a alors deux cas possibles :
1. Si la ressource est servie depuis le même serveur que la page
HTML, il est possible d'utiliser la même connexion pour obtenir
celle-ci, bien qu'il est possible qu'une nouvelle connexion soit
ouverte pour continuer à charger le reste du document, dans ce cas,
on se retrouve dans le second cas (certains navigateurs négocient par
avance cette connexion supplémentaire pour l'utiliser ensuite sans
aucun coût supplémentaire). On obtient donc un résultat similaire à
l'inclusion dans la page mais on peut utiliser le cache du navigateur
pour économiser la bande passante. Une pénalité de 100 ms est
toutefois à observer étant donné que le navigateur doit demander la
resource supplémentaire.
2. Si la ressource provient d'un autre serveur (comme dans l'exemple
ci-dessus), le navigateur va ouvrir une nouvelle connexion en
parallèle. Cela va induire un coût d'environ 300 ms (pour une
connexion 3G) afin d'établir cette nouvelle connexion TCP. Ces
300 ms sont incroyablement moins coûteuses que les 2 secondes
nécessaires pour retélécharger 85 Kio à chaque requête ! De plus, les
autres ressources statiques sont sans doute téléchargées depuis ce
serveur et cette connexion ne sera donc pas perdue. Il est même
probable qu'elle ait été nécessaire de toute façon (pour télécharger
les images par exemple).
!!! "Mise à jour (06.2011)" Dans une version précédente, j'avais mélangé le
mécanisme de [connexions persistantes][keepalive] avec le
[pipelining][pipelining]. Le premier permet de réutiliser une
connexion TCP existante mais chaque requête doit être émise l'une
derrière l'autre et doit attendre la réponse correspondante. Le second
permet d'envoyer plusieurs requêtes sans attendre les réponses. Comme
indiqué par [Éric Daspet](https://eric.daspet.name/) dans
un commentaire, le pipelining est en fait désactivé par défaut
sur la plupart des navigateurs. Toutefois, les connexions persistantes
sont bien supportées.
En cherchant un peu sur le web avec les mots clefs `oldSrc` et
`NG="replaced"`, on ne trouve pas grand chose sur le sujet. Au passage,
il semblerait de plus que cette technique casse certains composants,
comme TinyMCE, qui reposent sur la connaissance de leur emplacement
pour télécharger les ressources supplémentaires dont ils ont
besoin. SFR utiliserait un produit de [Flash Networks][flashnetworks] appelé
[Harmony Gateway][harmony]. J'ai demandé au service client des
renseignements supplémentaires, notamment s'il était possible de
débrayer cette fonctionnalité. Je n'ai à ce jour pas obtenu de
réponse.
En essayant un peu plus tard, je me suis rendu compte que la
réécriture du JavaScript n'avait plus lieu. Par contre, les images
étaient toujours servies depuis un serveur tiers. Le lendemain, un
autre essai m'a conduit à constater que le proxy transparent avait
disparu (plus d'entête `Via`). Étant donné que chaque essai a été
effectué à un endroit différent, il est possible que les serveurs
soient installés au plus près de l'abonné et que leurs configurations
soient différentes. Une autre explication est que SFR a désactivé
cette fonctionnalité pour moi, sans m'en avertir.
Configuré correctement, un tel accélérateur pourrait être proposé en
option par défaut aux abonnés. La plupart apprécieront le gain de
vitesse procuré par un tel équipement et ceux qui se soucient de la
[neutralité du net][neutrality] pourront désactiver cette option. Bien
sûr, il faut que celle-ci soit mise en avant de manière correcte, par
exemple en la présentant comme une option gratuite rattachée au
forfait.
# Mettre en place son propre proxy optimisant
Google fournit [`mod_pagespeed`][pagespeed], un logiciel pour
optimiser un site web à la volée. Il s'agit d'un module pour Apache
destiné à optimiser un unique site web. Cependant, comme Apache peut
agir en tant que serveur mandataire (avec `mod_proxy`), il est
possible de
[mettre en place `mod_pagespeed` pour n'importe quel site][pagespeedproxy].
Ce n'est pas très compliqué à configurer, à condition de se contenter
d'une version précompilée de
`mod_pagespeed`. [Téléchargez `mod_pagespeed`][1]. J'ai opté pour la
version Debian 64-bit.
::console
# touch /etc/default/mod-pagespeed
# dpkg -i ~/download/mod-pagespeed-beta_current_amd64.deb
Selecting previously deselected package mod-pagespeed-beta.
(Reading database ... 277699 files and directories currently installed.)
Unpacking mod-pagespeed-beta (from .../mod-pagespeed-beta_current_amd64.deb) ...
dpkg: dependency problems prevent configuration of mod-pagespeed-beta:
mod-pagespeed-beta depends on apache2.2-common; however:
Package apache2.2-common is not installed.
dpkg: error processing mod-pagespeed-beta (--install):
dependency problems - leaving unconfigured
Errors were encountered while processing:
mod-pagespeed-beta
# apt-get install -f
[…]
Unpacking apache2.2-common (from .../apache2.2-common_2.2.19-1_amd64.deb) ...
Processing triggers for man-db ...
Setting up apache2.2-common (2.2.19-1) ...
[…]
# apt-get install apache2-mpm-worker
[…]
Unpacking apache2-mpm-worker (from .../apache2-mpm-worker_2.2.19-1_amd64.deb) ...
Setting up apache2-mpm-worker (2.2.19-1) ...
Starting web server: apache2.
# a2enmod proxy_http
Considering dependency proxy for proxy_http:
Enabling module proxy.
Enabling module proxy_http.
To to activate the new configuration, you need to run:
/etc/init.d/apache2 restart
Il faut ensuite modifier le fichier `/etc/apache2/mods-enabled/proxy.conf`:
::apache
ProxyRequests On
<Proxy *>
AddDefaultCharset off
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Proxy>
Étant donné que placer le proxy sur le portable n'est pas très utile
(vous ne voulez pas rapatrier la version non optimisée du site web à
travers votre lien 3G), il faudrait installer tout ceci sur un autre
serveur et autoriser le portable à l'utiliser comme proxy. Cependant,
nous gardons cet exemple simpliste à titre d'illustration.
Il faut également modifier `/etc/apache2/mods-enabled/pagespeed.conf`
pour ajouter la directive `ModPagespeedDomain *` et ainsi autoriser
`mod_pagespeed` à réécrire n'importe quelle page. Redémarrez Apache
quand tout est fini et vérifiez que tout fonctionne correctement :
::console
$ curl -six http://localhost:80 http://www.lemonde.fr/ | grep ^X-Mod-Pagespeed
X-Mod-Pagespeed: 0.9.17.7-716
Parfait ! Essayons maintenant de nous rendre sur un site assez simple, comme
[Debian Backports](https://backports.debian.org/). Il sert une page
HTML avec deux feuilles de style :
![Debian Backports sans optimisation][s1]
[s1]: [[!!images/pagespeed-disabled.jpg]] "Debian Backports sans optimisation"
On a téléchargé les trois fichiers pour un total de 8 Kio, compression
comprise. Passons désormais par notre proxy :
![Debian Backports avec optimisation][s2]
[s2]: [[!!images/pagespeed-enabled.jpg]] "Debian Backports avec optimisation"
`mod_pagespeed` a diminué la taille du fichier HTML mais a surtout
combiné les deux fichiers CSS dont la taille globale a été réduite en
les *minifiant*. Il semble qu'un bug dans Chromium fausse l'affichage
de la quantité de données transférées quand on passe par un
proxy. J'ai vérifié avec Wireshark que Chromium reçoit bien des données
compressées pour environ 8 Kio. Le gain est assez ténu mais il devrait
être meilleur sur des sites plus complexes.
Naviguer sur Internet avec `mod_pagespeed` ne semble pas poser de
problèmes particuliers. Il semblerait donc qu'il s'agisse d'une
solution viable. Un bémol cependant : il n'optimise que les pages
qu'il a placées dans son cache. Cela signifie que la première fois que
l'on demande une page, on dispose d'une version non
optimisée. J'ignore s'il s'agit d'un comportement normal.
[1]: https://developers.google.com/speed/pagespeed/module/
[sfr]: https://www.sfr.fr/ "SFR"
[flashnetworks]: https://web.archive.org/web/2011/http://www.flashnetworks.com/
[harmony]: https://web.archive.org/web/20111118060153/http://www.flashnetworks.com/Content.aspx?Page=harmony_gateway
[lemonde]: https://web.archive.org/web/2011/https://mobile.lemonde.fr/ "Le Monde"
[pagespeedproxy]: https://web.archive.org/web/20110907095056/http://www.517sou.net/Article/mod_pagespeed-for-Apache2.aspx
[pagespeed]: https://github.com/apache/incubator-pagespeed-mod "modpagespeed"
[jquery]: https://jquery.com/
[pipelining]: https://fr.wikipedia.org/wiki/Pipelining_HTTP
[keepalive]: https://en.wikipedia.org/wiki/HTTP_persistent_connection
[neutrality]: https://fr.wikipedia.org/wiki/Neutralit%C3%A9_du_r%C3%A9seau