Optimisation et gain d’espace sous Firefox 3

21 05 2009

Encore un script Python avec une GUI ! Cette fois, c’est pour aider Firefox sous Ubuntu à ranger un peu mieux sa chambre.

Firefox

Firefox

Ce billet a été fortement inspiré du billet Optimiser le démarrage de Firefox de Bob sur Webdevonlinux.

Il y explique comment optimiser les bases de données au format SQLite 3 utilisées par Firefox 3.

En plus de cela, le script Python fourni ici propose d’arrêter et de redémarrer Firefox s’il est en cours d’exécution.

Autant le dire tout de suite, ce n’est pas avec une méthode académique que Firefox est arrêté !

Je décline toute responsabilité bla bla bla.

Pré-requis

Le script utilise zenity, qui devrait déjà être installé et sqlite3 qu’il faut installer avec la commande :

sudo apt-get install sqlite3

Installation

Télécharger le script firefoxsqlitcompress.

Copier le script dans votre répertoire ~/bin. Il peut porter le nom que vous voulez, moi je l’ai appelé “firefoxsqlitecompess”.

Donnez-lui les droits en exécution :

Donner les droits en exécution au script

Donner les droits en exécution au script

Il est ensuite possible de créer un lanceur sur le bureau. Sous Nautilus, faites apparaître le menu contextuel en cliquant avec le bouton de droite de la souris sur le bureau :

Menu contextuel de Nautilus

Menu contextuel de Nautilus

Cliquer sur Créer un lanceur…, la fenêtre suivante apparaît :

Créer un lanceur sur le bureau

Créer un lanceur sur le bureau

Choisissez Application comme type de lanceur, donnez le nom que vous voulez et sélectionnez le script avec le bouton Parcours…. Il est également possible de changer l’icône en cliquant dessus.

Utilisation

Lancez le script. Si Firefox est en cours d’exécution, la fenêtre suivante apparaît :

Firefox est en cours d’exécution

Firefox est en cours d’exécution

Si vous cliquez sur le bouton Annuler, le script n’ira pas plus loin. Vous pouvez arrêter Firefox manuellement et relancer le script. Si vous cliquez sur Valider, Firefox sera arrêté.

Pendant l’optimisation, la fenêtre de progression suivante s’affiche :

Optimisation des bases de données en cours

Optimisation des bases de données en cours

Une fois l’optimisation terminée, Firefox est relancé (s’il était en cours d’exécution au lancement du script). Et voilà !

Fonctionnement

Arrêt de Firefox

Il n’existe apparemment pas de méthode officielle pour arrêter Firefox depuis la ligne de commande.

Sous Unix, il est possible d’envoyer un signal de fin à tout processus appartenant à l’utilisateur courant. Firefox ne fait pas exception. Mais il n’est pas correctement géré.

Si on arrête Firefox avec une commande du style :

kill pid_de_firefox

Firefox s’arrête bien mais il nous accueille avec la fenêtre suivante lors du redémarrage :

Restauration de session après crash

Restauration de session après crash

Quand Firefox reçoit un signal, il s’arrête mais laisse le fichier sessionstore.js en plan. Ce fichier est utilisé pour conserver l’état de la session en cours au cas où Firefox planterait.

Ce fichier est aussi utilisé lorsque vous avez plusieurs onglets ouverts, que vous quittiez normalement et que vous cliquiez sur le bouton Ok de la fenêtre ci-dessous :

Fermeture de Firefox avec plusieurs onglets ouverts

Fermeture de Firefox avec plusieurs onglets ouverts

Sauf que, cette fois, Firefox ne vous affichera pas de message d’erreur au redémarrage.

Et pourquoi ?

Parce que, dans ce cas-là, l’état de la session est placé à stopped :

  • arrêt brutal : session:{state: »running »}
  • arrêt normal : session:{state: »stopped »}

La solution à laquelle je suis arrivée a donc été d’éditer le fichier sessionstore.js et d’y remplacer running par stopped.

Ce n’est pas bien compliqué. Mais pas très académique !

Je ne peux donc pas garantir qu’il n’y aura aucune perte de ce côté-là. D’un autre côté, je l’ai fait plusieurs fois sans perdre quoi que ce soit. À vous de voir…

Compactage des bases de données

SQLite

SQLite

Les fichiers de bases de données de SQLite 3, comme ceux d’autres bases de données, grossissent au fur et à mesure de leur utilisation. Elles maigrissent rarement car cette opération est coûteuse en temps.

C’est un peu comme la défragmentation d’une partition.

À titre d’exemple, voici ce que donne le compactage des bases sur mon installation de Firefox :

Fichiers Avant Après
content-prefs.sqlite 7168 7168
cookies.sqlite 560128 413696
downloads.sqlite 31744 2048
formhistory.sqlite 113664 108544
permissions.sqlite 2048 2048
places.sqlite 3211264 2527232
search.sqlite 2048 2048
urlclassifier3.sqlite 55545856 20750336
webappsstore.sqlite 12288 12288
Totaux 56,7 Mio 22,7 Mio

Ça fait tout de même 34 Mio sur 56,7 d’économisés.

Pour compacter une base de données SQLite 3, il faut simplement exécuter la commande VACUUM dessus.

Redémarrage de Firefox

Redémarrer Firefox est la partie la moins compliquée, si ce n’est qu’il faut penser à supprimer les sorties standard et d’erreur qui pourraient venir polluer notre terminal.

Code source

#!/usr/bin/env python
# coding=utf8
from os import getenv,getuid,kill,waitpid
from subprocess import call,Popen,PIPE
from os.path import abspath,join,exists
from signal import SIGTERM

def recup_rep_profiles():
  base_profile=join(getenv('HOME'),".mozilla","firefox")
  profiles_ini=join(base_profile,"profiles.ini")

  rep_profiles=[]
  lignes=open(profiles_ini).read().splitlines()
  for ligne in lignes:
    ligne=ligne.strip()
    if ligne.startswith("Path="):
      rep_profiles.append(join(base_profile,ligne[5:]))

  return rep_profiles

def patch_sessionstore(sessionstore):
  if not exists(sessionstore): return

  chaine=open(sessionstore,"rb").read()
  chaine=chaine.replace('session:{state:"running"}})','session:{state:"stopped"}})')
  open(sessionstore,"wb").write(chaine)

def recup_firefox_pids():
  lignes=Popen(['pgrep','-x','firefox','-U',str(getuid())],stdout=PIPE).communicate()[0]
  firefox_pids=[]
  for ligne in lignes.splitlines():
    ligne=ligne.strip()
    if not ligne: continue
    firefox_pids.append(int(ligne))

  return firefox_pids

def kill_firefox(firefox_pids):
  for pid in firefox_pids: kill(pid,SIGTERM)

# Récupère les chemins vers les profiles
profiles=recup_rep_profiles()

# Récupère les PID des processus Firefox en cours d’exécution
pids=recup_firefox_pids()

# Demande confirmation si Firefox est en cours d’exécution
if pids:
  retour=call(['zenity','--question','--title=Attention','--text=Firefox est encours d’exécution\nSi vous cliquez sur Valider, Firefox sera fermé le temps d’effectuer l’optimisation et relancé après'])
  if retour==1: exit(1)

  # Arrête Firefox
  kill_firefox(pids)

  # Patche les fichiers sessionstore.js
  for profile in profiles:
    patch_sessionstore(join(profile,"sessionstore.js"))

# Compacte les bases de données
progress=Popen(["zenity","--title","Optimisation","--text","Optimisation en cours...","--progress","--pulsate","--auto-close"],stdin=PIPE)
for profile in profiles:
  Popen(['find',profile,'-name','*.sqlite','-print','-exec','sqlite3','{}','VACUUM',';'],stdout=progress.stdin)

progress.stdin.close()

# Relance Firefox s’il était lancé
if pids:
  Popen(['firefox'],stderr=open("/dev/null"),stdout=open("/dev/null"))

Actions

Information

One response

22 05 2010
gh0st

Si plusieurs instances ( via …fichier… nouvelle fenêtre ) sont lancées Firefox n’est pas fermé correctement. Sinon Merci 😉

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s




%d blogueurs aiment cette page :