Ostatnio: 04.07.2017

Darmowe galerie dla serwisów aukcyjnych

Dlaczego wykop tak zamula i jak można go przyspieszyć?

Witam Wykopowiczów i - mam nadzieję - Administrację!

Jak wszyscy wiemy, od kilku dni możemy cieszyć się oczekiwaną od dawna nową wersją wykopu. Okazało się, że wzbudziła raczej negatywne odczucia - mało kontrastowe kolory, rezygnacja z kilku funkcji, które były w poprzedniej wersji (jak choćby "pokaż wszystkie"), poważne bugi w samym silniku (możliwość edycji wszystkich znalezisk i komentarzy) itd... Mnie osobiście rozczarowało niezaimplementowanie kilku funkcji, które znalazły się w moim skrypcie, jak okienko do dodawania linków w składni Markdown czy "idź do następnej nieprzeczytanej". To wszystko jest jednak bez większego znaczenia, bo najpoważniejszym problemem jest to, że zamula. I to zamula na tyle, że jego używanie przestało być przyjemnością. Postanowiłem przyjrzeć się czemu tak jest i co można na to poradzić.

Na początku trochę technikaliów (tę sekcję można pominąć, jeśli nie jesteś zainteresowany): pierwszym problemem, z którym musiałem się zmierzyć to możliwość zastąpienia skryptów wykonywanych przez wykop, swoimi własnymi. Z pomocą przyszedł mi Mój Ulubiony Język Programowania Python, w którym zrobiłem prosty serwer HTTP, który w przypadku pewnych zapytań wysyła zmodyfikowane przeze mnie pliki, a normalnie jest to co oryginalnie na serwerze. Skrypt można znaleźć tutaj. Trzeba było też zmodyfikować plik /etc/hosts i dopisać tam:

127.0.0.1      s1.imgwykop.pl

dzięki czemu wszystkie zapytania zamiast na serwer wykopu, szły do mnie.

Trzeba było też przygotować skrypty wykopowe, żeby można je przyjemnie modyfikować, bowiem jeśli zajrzymy do wykopowego skryptu to zauważymy, że jest on pozbawiony białych znaków. Na szczęście z pomocą przychodzi JavaScript Beautifier i już mamy ładny kod z wcięciami :)

Po takich krokach przygotowawczych, mogłem już spokojnie edytować skrypty.

Zacząłem od sprawdzenia jak wykop radzi sobie na oryginalnych skryptach, korzystając z rozszerzenia z Firebug i opcji profilowania javascript. Test robiłem na znalezisku Wykop.pl - Nowa wersja serwisu .

Wynik mnie nie zachwycił:

358254

Nikt chyba nie ma wątpliwości, że 474632 odwołania (sic!!) do funkcji JS to zdecydowanie zbyt dużo i trzeba z tym coś zrobić.

Zajrzałem do źródeł skryptu i niestety nie wygląda to najlepiej. Administracji radzę uważnie przeczytać ten dokument, gdyż popełniają kardynalne błędy. Oto przykład:

$("li.replyForm").fadeOut(200).remove();
var c = $("form#add-comment-entry").html();
$(this).parent().parent().parent().parent().parent().parent().parent().parent().after('<li class="replyForm"><form id="add-re-comment-entry" method="post" action="' + $("form#add-comment-entry").attr("action") + '">' + c + "</form></li>");
$("li.replyForm").find("p.info a").text($(this).parent().parent().parent().parent().find("h5 a:last").text());
$("li.replyForm").find("p.info").show()

Jedna z podstawowych zasad głosi, że nie należy powtarzać tego samego selektora jQuery kilka razy z rzędu. Zamiast wykorzystywać znaleziony li.replyForm kilka razy, w krótkim czasie musi go szukać trzy razy. Wypadałoby to umieścić w jakąś zmienną i później odwoływać się do zmiennej. Przy okazji ujawnia się inny z dużych problemów w projektowaniu serwisu: nadmierne używanie klas. replyForm jest jeden na stronie, a skoro jest jeden to zdecydowanie powinien być identyfikowany po id. Dlaczego? Bo wybieranie elementów po id korzysta z natywnej metody javaskriptowej getElementById(), dzięki czemu jest bardzo szybkie. Poza tym, id zawsze znajduje dokładnie jeden element. A zatem $("li#replyForm") zakończy wyszukiwanie po znalezieniu pierwszego pasującego elementu; $("li.replyForm") zaś przeszukuje stronę do końca, bo mogą być kolejne wystąpienia klasy (a ich nie ma). Właściwie należałoby napisać $("#replyForm"), bo dodanie li w tym przypadku spowolni proces.

Kolejną "nowinką", której brakuje w skrypcie jest globalny cache, w którym przechowywano by znalezione już obiekty, co przyspieszyłoby ich wyszukiwanie w przyszłości. Niektóre powtarzają się bardzo często, więc to także mogłoby mieć decydujący wpływ na wydajność.

Następna sprawa to "bindowanie" (brakuje mi dobrego polskiego słowa...) zdarzeń. Jeśli na stronie jest bardzo dużo komentarzy to wiele obiektów powtarza się (jak przyciski plusów/minusów, "odpowiedz" itp.). W skrypcie zastosowano zwykłe bindowanie, przez co skrypt musi przelecieć wszystkie wystąpienia obiektów i zbindować z odpowiednim zdarzeniem. Ponieważ używane tutaj przeważnie zdarzenie "click", niczym bąbelki, idzie do góry w drzewie DOM, można zabindować zdarzenie w którymś rodzicu i sprawdzanie, który obiekt to zdarzenie wywołał. Ideę przedstawiono tutaj. Podobny efekt do tej metody można wykorzystać stosując zdarzenie live w jQuery (na wykopie też jest zastosowane), najlepiej z zastosowaniem tej sztuczki.

Podsumowując, co powinna zrobić administracja by przyspieszyć wykop?

- większą ilość obiektów identyfikować po id (np. replyForm, jvote, jbury itd.),

- korzystać z "bąbelków",

- nie powtarzać tych samych zapytań jQuery, tylko dodać je do zmiennych, a najlepiej zastosować cache,

- pozwolić programować skrypty komuś, kto się na tym zna ;-)

Zastosowałem u siebie kilka z podanych wyżej porad (wszystkich oczywiście nie mogłem, bo wymagają zmian w kodzie generowanej strony), co zajęło mi może 40 minut. Oto efekt:

358299

dla przypomnienia:

358254



A więc da się? Da się. Mam nadzieję, że administracja weźmie sobie te uwagi do serca i zoptymalizuje serwis.

Dla zainteresowanych, przerobiony przeze mnie core.js .

Komentarze

  • Kossorek Kossorek

    wykop spoko jest :)

  • Lipanett Lipanett

    u mnie działa ;P

  • Opaewela85 Opaewela85

    mi tam nic nie przeszkadza w wykopie...

  • Kunhella Kunhella

    Już chyba nie jest aż tak źle :)

  • Jonking86 Jonking86

    wszystko się zmienia, trzeba przywyknąć...

  • Ruby Ruby (*.centertel.pl)

    Ja tez to gdzies juz widzialam : http://pordubitz.org/1/wiadomosci.onet.pl

  • szkopinski szkopinski (*.chello.pl)

    prosimy o starą formę wykopu.

  • LapKom LapKom (*.neoplus.adsl.tpnet.pl)

    Dodatkowo, przy wielokrotnnym wywołaniu parent() w tym przypadku szybciej byloby wywołać parents('#jakies-id-parenta'). Jeszcze w przypadku inputów rzuca się w oczy selektor po atrybutach, który jest jeszcze wolniejszy od klas. :)

    W JS'ach na nowym wykopie jest jeszcze sporo takich kwiatków. Powinni wziąć sobie do serca te uwagi i wprowadzić troche zmian. Dla dobra serwisu i uzytkowników. :)

  • k k (*.sgyl.cable.virginmedia.com)

    Cytat: "śmierdzi phishingiem albo innym ustrojstwem."

    A jak mial sprawdzic dzialanie swoich nowych skryptow ? po prostu podmnienil w hosts ze kiedy strona pyta o pliki z serwera s1.imgwykop.pl to zamiast z wykopu pobiera z jego lokalnego.

    Jak sie nie rozumie kwestii technicznych to sie nie wypowiada.

  • m m (193.63.43.*)

    Tfu, nie wszystkie a raptem 3

  • misio misio (*.neoplus.adsl.tpnet.pl)

    Przyjmijcie tego Pana powyżej do pracy...

  • m m (193.63.43.*)

    @blablabla, tak, sam sobie zrobil phishing i podmienil az wszystkie pliki z s1.imgwykop.pl

  • lulz lulz (*.chello.pl)

    @blablabla: Jesteś cymbałem. 127.0.0.1 = localhost = twój własny komputer.

  • Tomasz Kowalczy Tomasz Kowalczy (*.nat.student.pw.edu.pl)

    nie zrozumiałeś - "do mnie" == "do mojego komputera", czyli jakbyś to wykonał u siebie to leciałoby do Twojego ;]

  • mhm mhm (*.chello.pl)

    @blablabla - "szły do mnie" = szły lokalnie, po localhoście (127.0.0.1 to IP lokalne komputera)

  • blablabla blablabla (*.adsl.inetia.pl)

    Cytuję:
    "wszystkie zapytania zamiast na serwer wykopu, szły do mnie"

    śmierdzi phishingiem albo innym ustrojstwem.

Dodaj komentarz

Dodajesz komentarz anonimowo. Zaloguj się.

Dodajesz komentarz anonimowo. Aby komentować pod własnym pseudonimem włącz profil publiczny w ustawieniach.

Autor:
Treść:

Aby przesłać formularz, musisz mieć włączony w przeglądarce Javascript. Jeżeli nie masz, przepisz wspak tekst 4kts8zzktc:

Wykop

Korzystanie z serwisu oznacza akceptację Regulaminu. Copyright – 1999-2017 INTERIA.PL , wszystkie prawa zastrzeżone.