optymalizacja-cms-wordpress

Optymalizacja CMS Wordpress

Tagi: optymalizacja, pozycjonowanie, SEO, strona internetowa, WordPress

Maciej Skrzypczak

I. Archiwizacja danych

Przed rozpoczęciem pracy najpierw wykonuję kopię strony internetowej. Warto zadbać o codzienną archiwizację danych. Zawsze może się przydać kopia, w razie utraty danych cały serwis można szybko przywrócić. Nie można liczyć, że nigdy nie spotka nas awaria hostingu, nie zaatakuje wirus czy hacker.

  • BackUpWordPress.

II. Aktualizacja CMS WordPress i dodatków

Pierwszym etapem optymalizacji jest aktualizacja systemu oraz dodatków do najnowszych wersji. Jest to bardzo ważne, gdyż autorzy co pewien czas poprawiają błędy, usuwają dziury w zabezpieczeniach, zwiększają szybkość działania, czy dodają nowe, ciekawe funkcje.

III. Optymalizacja prędkości działania

Strony internetowe instalowane na WordPressie często wolno się wczytują, szczególnie w wieczornych godzinach, kiedy hostingi są najbardziej obciążone. Zacząć należy od zmiany na serwerze wersji PHP na 7 oraz wyłączenia zbędnych dodatków. Następnie instaluję plugin buforujący kod PHP, dzięki któremu dynamiczne strony otwierają się w postaci statycznych, oraz minimalizujący kod strony i wielkości zdjęć. Warto skonfigurować stronę pod globalny CDN Cloudflare (cloudflare.com), dzięki czemu strona będzie pobierana z najbliższych użytkownikowi lokalizacji na całym świecie.

  • P3 Plugin Performance Profiler, analiza i wyłączenie zbędnych dodatków,
  • WP Super Cache, buforowanie kodu PHP,
  • Autoptimize, minimalizacja kodu strony,
  • Above The Fold Optimization,
  • Jetpack z WordPress.com / Photon, kompresja zdjęć, integracja z CDN WordPress,
  • optymalizacja .htaccess, modyfikacja czasu buforowania kodu przez przeglądarkę, kompresja kodu dla przeglądarki:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule \.(php|html|htm|css|js|ico|jpg|jpeg|png|gif|swf|json|txt|eot|woff|woff2|ttf|svg)$ empty [R=404,L]

<FilesMatch "\.(css|js|ico|jpg|jpeg|png|gif|swf|xml|json|txt|eot|woff|woff2|ttf|svg|pdf|doc|xls)$">
 RequestHeader unset Cookie
 Header unset Set-Cookie
 Header unset Cookie
</FilesMatch>

<IfModule mod_expires.c>
 FileETag MTime

 ExpiresActive on
 ExpiresDefault "access plus 28 days"

 ExpiresByType text/html "access plus 3 hours"

 ExpiresByType application/json "access plus 3 hours"
 ExpiresByType text/xml "access plus 3 hours"
 ExpiresByType application/xml+rss "access plus 3 hours"

 ExpiresByType text/css "access plus 7 days"

 ExpiresByType text/javascript "access plus 14 days"
 ExpiresByType application/x-javascript "access plus 14 days"
 ExpiresByType application/javascript "access plus 14 days"

 ExpiresByType text/plain "access plus 28 days"

 ExpiresByType image/x-icon "access plus 28 days"
 ExpiresByType image/jpeg "access plus 28 days"
 ExpiresByType image/png "access plus 28 days"
 ExpiresByType image/gif "access plus 28 days"

 ExpiresByType application/x-shockwave-flash "access plus 28 days"

 ExpiresByType application/x-font-ttf "access plus 1 years"
 ExpiresByType application/x-font-opentype "access plus 1 years"
 ExpiresByType application/x-font-woff "access plus 1 years"
 ExpiresByType application/x-font-woff2 "access plus 1 years"
 ExpiresByType application/vnd.ms-fontobject "access plus 1 years"
 ExpiresByType image/svg+xml "access plus 1 years"

 ExpiresByType text/x-component "access plus 1 years"
</IfModule>

<IfModule mod_deflate.c>
 AddOutputFilterByType DEFLATE text/html
 AddOutputFilterByType DEFLATE text/plain

 AddOutputFilterByType DEFLATE application/json
 AddOutputFilterByType DEFLATE text/xml
 AddOutputFilterByType DEFLATE application/xml+rss

 AddOutputFilterByType DEFLATE text/css

 AddOutputFilterByType DEFLATE text/javascript
 AddOutputFilterByType DEFLATE application/x-javascript
 AddOutputFilterByType DEFLATE application/javascript

 AddOutputFilterByType DEFLATE application/x-shockwave-flash

 AddOutputFilterByType DEFLATE application/x-font-ttf
 AddOutputFilterByType DEFLATE application/x-font-opentype
 AddOutputFilterByType DEFLATE application/x-font-woff
 AddOutputFilterByType DEFLATE application/x-font-woff2
 AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
 AddOutputFilterByType DEFLATE image/svg+xml

 AddOutputFilterByType DEFLATE text/x-component

 # Remove browser bugs (only needed for really old browsers)
 BrowserMatch ^Mozilla/4 gzip-only-text/html
 BrowserMatch ^Mozilla/4\.0[678] no-gzip
 BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
 Header append Vary User-Agent
</IfModule>

IV. Optymalizacja bazy danych

Optymalizuje tabele bazy danych, opróżniam kosz, usuwam wersje wpisów, automatyczne szkice, spam oraz stare dane. Najwięcej miejsca zajmują wersje wpisów, dlaczego dodatkowo warto ograniczyć ich ilość do 100.

  • WP-Optimize.

V. Bezpieczeństwo

Po pierwsze przy instalacji WordPressa należy podać inną niż domyślna nazwę bazy danych. Nie wolno także stosować jako nazwy administratora domyślnego loginu "admin" czy "administrator". Jeżeli udzielamy się na stronie, nie powinno się wykorzystywać konta administratora do publikowania artykułów oraz komentowania, a pseudonim trzeba ustawić inny niż nazwa użytkownika. Dzięki temu unikniemy wielu ataków usiłujących na siłę wydobyć nasze hasło do serwisu.

  • Wordfence Security, zabezpieczenie przed podstawowymi atakami i wirusami,
  • Loginizer, ochrona logowania / brute force,
  • zabezpieczenie PHP:

function sr_security() {
  global $user_ID;

  if ($user_ID) {
    if ( !current_user_can('manage_options') ) {
      if (strlen($_SERVER['REQUEST_URI']) > 255 ||
          stripos($_SERVER['REQUEST_URI'], "eval(") ||
          stripos($_SERVER['REQUEST_URI'], "CONCAT") ||
          stripos($_SERVER['REQUEST_URI'], "UNION+SELECT") ||
          stripos($_SERVER['REQUEST_URI'], "base64")) {
        if (!headers_sent()) {
          header("HTTP/1.1 414 Request-URI Too Long");
          header("Status: 414 Request-URI Too Long");
          header("Connection: Close");
        }
        exit;
      }
    }
  }
}
add_action( 'init', 'sr_security' );

  • zabezpieczenie .htaccess, blokada wyszukiwania autorów, 5G BLACKLIST/FIREWALL:

RewriteCond %{QUERY_STRING} author=
RewriteRule .* empty [R=404,L]

# 5G BLACKLIST/FIREWALL
# @ http://perishablepress.com/5g-blacklist/

# 5G:[QUERY STRINGS]
<ifModule mod_rewrite.c>
 RewriteCond %{QUERY_STRING} (environ|localhost|mosconfig|scanner) [NC,OR]
 RewriteCond %{QUERY_STRING} (mod)\=\.?/? [NC,OR]
 RewriteCond %{QUERY_STRING} boot\.ini  [NC,OR]
 RewriteCond %{QUERY_STRING} echo.*kae  [NC,OR]
 RewriteCond %{QUERY_STRING} etc/passwd [NC,OR]
 RewriteCond %{QUERY_STRING} \=\\%27$   [NC,OR]
 RewriteCond %{QUERY_STRING} \=\\\'$    [NC,OR]
 RewriteCond %{QUERY_STRING} \.\./      [NC,OR]
 RewriteCond %{QUERY_STRING} \?         [NC]
 RewriteRule .* - [F]
</ifModule>

# 5G:[USER AGENTS]
<ifModule mod_setenvif.c>
 SetEnvIfNoCase User-Agent (casper|cmsworldmap|diavol|dotbot)   keep_out
 SetEnvIfNoCase User-Agent (flicky|ia_archiver|jakarta|kmccrew) keep_out
 SetEnvIfNoCase User-Agent (libwww|planetwork|pycurl|skygrid)   keep_out
 SetEnvIfNoCase User-Agent (purebot|comodo|feedfinder|turnit)   keep_out
 SetEnvIfNoCase User-Agent (zmeu|nutch|vikspider|binlar|sucker) keep_out
 <limit GET POST PUT>
  Order Allow,Deny
  Allow from all
  Deny from env=keep_out
 </limit>
</ifModule>

# 5G:[REQUEST STRINGS]
<ifModule mod_alias.c>
 RedirectMatch 403 (https?|ftp|php)\://
 RedirectMatch 403 /(cgi|https?|ima|ucp)/
 RedirectMatch 403 /(Permanent|Better)$
 RedirectMatch 403 (\=\\\'|\=\\%27|/\\\'/?|\)\.css\()$
 RedirectMatch 403 \.(cgi|asp|aspx|cfg|dll|exe|jsp|mdb|sql|ini|rar)$
 RedirectMatch 403 /(contac|fpw|install|pingserver|register)\.php$
 RedirectMatch 403 (base64|crossdomain|localhost|wwwroot|e107\_)
 RedirectMatch 403 (eval\(|\_vti\_|\(null\)|echo.*kae|config\.xml)
 RedirectMatch 403 \.well\-known/host\-meta
 RedirectMatch 403 /function\.array\-rand
 RedirectMatch 403 \)\;\$\(this\)\.html\(
 RedirectMatch 403 proc/self/environ
 RedirectMatch 403 msnbot\.htm\)\.\_
 RedirectMatch 403 /ref\.outcontrol
 RedirectMatch 403 com\_cropimage
 RedirectMatch 403 indonesia\.htm
 RedirectMatch 403 \{\$itemURL\}
 RedirectMatch 403 function\(\)
 RedirectMatch 403 labels\.rdf
 RedirectMatch 403 /playing.php
 RedirectMatch 403 muieblackcat
</ifModule>

# 5G:[BAD IPS]
<limit GET POST PUT>
 Order Allow,Deny
 Allow from all
 # uncomment/edit/repeat next line to block IPs
 # Deny from 123.456.789
</limit>

# 5G:[WordPress]
<ifModule mod_rewrite.c>
 RedirectMatch 403 /\$\&
 RedirectMatch 403 (?i)/\&(t|title)=
 RedirectMatch 403 (?i)/\.(bash|git|hg|log|svn|swp|tar)
 RedirectMatch 403 (?i)/(1|contact|i|index1|iprober|phpinfo|phpspy|product|signup|t|test|tz|visit|webshell|wp-signup).php
 RedirectMatch 403 (?i)/(author-panel|class|database|manage|phpMyAdmin|register|submit-articles|system|usage|webmaster)/?$
 RedirectMatch 403 (?i)/(=|_mm|cgi|cvs|dbscripts|jsp|rnd|userfiles)
</ifModule>

WordPress wykorzystywany jest często jako katalog SEO, tak więc każdy jego użytkownik jest potencjalnym celem ataku spamerów. Nie można pozostawić niezabezpieczonych formularzy, w przeciwnym razie zostaniemy zarzuceni masą automatycznie generowanych komentarzy, e-maili w skrzynce pocztowej.

  • Akismet, zabezpieczenie przed spamem,
  • zabezpieczenie formularza:

.DISABLE{display:none}

<input name="sr-code" value="ąćęłńóśżź" type="hidden" />
<input class="DISABLE" name="submit" value="spam" type="submit" />
<input name="submit" value="Wyślij" type="submit" />

 if (($_POST['submit']==='spam') || ($_POST['sr-code']!=='ąćęłńóśżź')) die();

VI. Funkcjonalność WordPress

Na końcu zwiększam funkcjonalność wbudowanego edytora tekstu:

  • TinyMCE Advanced,
  • Central Color Palette,
  • ustawienia TinyMCE:

{"settings":{"toolbar_1":"bold,italic,underline,strikethrough,alignleft,aligncenter,alignright,alignjustify,bullist,numlist,outdent,indent,superscript,subscript,link,unlink,anchor,hr,nonbreaking,table","toolbar_2":"formatselect,fontselect,fontsizeselect,forecolor,backcolor,removeformat,pastetext,wp_more,wp_page,blockquote,charmap,undo,redo","toolbar_3":"","toolbar_4":"","options":"advlist,menubar","plugins":"anchor,code,insertdatetime,nonbreaking,print,searchreplace,table,visualblocks,visualchars,advlist"},"admin_settings":{"options":"no_autop","disabled_plugins":""}}


Współpracowałem

  • rzeczpospolita
  • uniwersytet-warszawski
  • parkiet
  • plk
  • qualitysolicitors
  • espeo
  • slik
  • dupont-tyvek
  • ekiosk
  • sigma
  • emma
  • caselogic
  • gusmahome
  • oltravel
  • laszkiewicz
  • stilnovisti
  • digimania
  • bong
  • wdf
  • mgfinance
  • tam-pol
  • stage-vision
  • bestpharma
  • ipgo