Pokud se dělá kompletní redesign webu, často dochází i ke změně URL. Pro dobré SEO, ale i pro běžné uživatele, je důležité správně přesměrovat staré URL na nové. Jenže těch může být u e-shopů a velkých webů i několik tisíc.
Když web poběží na nové doméně, na starém serveru se nastaví přesměrování a rychlost není nutné tak moc řešit, protože jen první návštěva zabere o nějakou tu dobu navíc. Pokud ale doména zůstane a přesměrování tisícovek adres bude v souboru .htaccess, dojde ke zpomalení každého requestu, včetně adres nového webu, stylů, JavaScriptu, obrázků atd.
Redirect vs. RewriteRule vs. PHP
Soubor .htaccess zpracován pro každý request, takže při velkém množství řádků se zpomalí vše. Důležité ale také je, že Apache prvně zpracuje celý soubor, a až poté začne provádět jednotlivé akce. Takže vložení často používaných přesměrování na začátek souboru příliš nepomůže. Rychlejší je také využít direktivy Redirect, než RewriteRule, která využívá regulárních výrazů a celkové zpracování nějaký ten čas navíc zabere.
Pokud lze staré URL jednoduchý pravidlem odfiltrovat od těch nových, je výhodnější provést přesměrování pomocí PHP. Soubor .htaccess se tak zkrátí, jeho vykonávání se zrychlí a běžné requesty nejsou ovlivněny. Vykonávaní PHP je navíc také rychlejší.
V grafu lze vyčíst zpomalení při narůstající velikosti souboru .htaccess a také skutečnost, že přesměrování prvním, nebo posledním, příkazem v souboru příliš roli nehraje.
Jak probíhalo testování
Skript pro měření je napsán v Pythonu, pro jeho jednoduchost, pro jeho rychlost, ale hlavně měřený čas je TTFB (Time to first byte). Každý request je proveden 100x a výsledky uloženy do CSV souboru. Následně jsou odebrána odlehlá pozorování (Když už jsem měl tu statistiku na VŠB) a vypočten průměr.
Prvně bylo vše zkoušeno na localhostu, poté i na serveru od Wedosu. I přes možné zkreslení internetovým připojením byl rozptyl hodnot velmi nízký, v řádek desítek či stovek nanosekund.
times = [] for x in xrange(1,100): req = requests.get("http://redirect.test/ab68/fc/51/497db0ca21119091a92e418e8a27984f", allow_redirects=False) elapsed = req.elapsed times.append([str(elapsed.total_seconds()).replace('.', ',')]) print x, elapsed.total_seconds() with open(os.path.dirname(os.path.realpath(__file__)) + '/requests.csv', 'wb') as csvfile: writer = csv.writer(csvfile, delimiter=';') writer.writerows(times)
Soubor .htaccess
Verzí souborů bylo více, každý ale vždy obsahoval první část s RewriteEngine on a poslední RewriteRule na index. URL adresy jsou SHA-1 hashe čísel od 1 do 1 000 a ve druém případě do 10 000.
RewriteEngine on RewriteBase / # Pouze při testování Redirect directivy Redirect 301 /b658/9f/c6/ab0dc82cf12099d1c2d40ab994e8410c http://google.com/ # ... dalších X záznamů # Pouze při testování RewriteRule directivy RewriteRule ^b658/9f/c6/ab0dc82cf12099d1c2d40ab994e8410c http://google.com/ [R=301,L] # ... dalších X záznamů # Přesměrování pomocí PHP - pokud lze staré URL jednoduše odfiltrovat RewriteRule ^[0-9a-f]{4}/ ./redirect.php [L] # Když neprojde žádný redirect RewriteRule ^(.*)/$ ./index.php [L,QSA]
Přesměrování pomocí PHP
Soubor PHP obsahoval stejné URL adresy jaké byly předtím vloženy do souboru .htaccess. Protože PHP implementuje pole jako HashTable, přesměrování proběhne vždy stejně rychle pro první i poslední záznam, nebylo tedy nutné dvojí měření.
$urls = [ '/b658/9f/c6/ab0dc82cf12099d1c2d40ab994e8410c' => "http://www.google.com", ... ]; header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$urls[$_SERVER['REQUEST_URI']]);
Má smysl to vůbec řešit?
Když jsem toto téma na jednom projektu řešil, na internetu jsem našel jen zmínku, že zpracování souborů .htaccess je dosti pomalé. Zpomalení jsem tedy očekával mnohem větší. Reálně ale časy nejsou příliš velké, aby bylo nutné se tímto problémem na projektech příliš zabývat. Pokud ale někdo nahání co největší skóre na PageSpeed Insight, může mu to pomoct.
K tomuto článku již není možné přidávat další komentáře