2017-11-28 226 views
8

Mamy API, które losowo zajmuje wysoki czas content download w chrome, działa dobrze zawsze w firefox i zajmuje tylko kilka ms. Rozmiar odpowiedzi jest nieskompresowany po 20 kb i skompresowany 4 kb. To samo żądanie działa również dobrze przy użyciu curl.Losowy czas pobierania wysokiej zawartości w chrome?

Rzeczy, które próbowaliśmy:

  1. Wyłączenie If-None-Match nagłówek wyłączyć odpowiedź cache z przeglądarki.
  2. Próbowanie różnych uciśnięć (gzip, deflate, br).
  3. Wyłączanie kompresji.
  4. Wyłączanie wszystkich rozszerzeń do Chrome.

To samo żądanie działa dobrze czasami na chromie, ale losowo zwraca bardzo wysoki czas pobierania treści.

Nie możemy zrozumieć podstawowej przyczyny tego problemu. Jakie są inne rzeczy, które możemy spróbować zminimalizować tym razem?

Chrome Network Tab

Zrobiłem trzy wnioski tutaj i 3rd jeden wziął najwięcej czasu (przed ostatnim kolec). Procesor nie wydaje się maksymalizować przez dłuższy czas. Zazwyczaj jest to czas bezczynności.

performance graph chrome

Również podczas odtwarzania połączenia przy użyciu Replay XHR menu Content okres pobierania spada z 2s do 200 ms.

Odpowiedz

11

Czy przypadkiem próbujesz zaimplementować nieskończone przewijanie?Jeśli tak, spróbuj przeciągnąć pasek przewijania zamiast kółka myszy. Z jakiegoś powodu Chrome wydaje się mieć problemy z przewijaniem myszy. Jeśli pasek przewijania działał poprawnie, czytaj dalej.

Ten post zawiera szczegółowy opis przejścia ktoś przeżywa coś podobnego - https://github.com/TryGhost/Ghost/issues/7934

miałem załączeniu obserwatora na razie scroll które mogłyby wywołać żądania AJAX. Zablokowałem tę prośbę i mogłem zobaczyć, że tylko 1 został wysłany. Obserwowałem, jak mój serwer dev odsyła odpowiedź w ciągu kilku ms, ale w chromie będzie 2-sekundowe opóźnienie. Bez renderowania, bez wywołań api, bez wykonywania skryptów. Ale "Pobieranie treści" zajęłoby 3 sekundy dla 14kb. Żadna inna przeglądarka nie miała tego problemu.

Natknąłem się na sugestie, że użycie requestAnimationFrame zamiast setTimeout rozwiąże problem. Takie podejście wydaje się, że podejście działa, gdy "Oczekiwanie" lub zielony jest znaczący, nie tyle dla "pobierania treści", czy niebieskiego.

Po wielu godzinach próbowałem warunkowo zadzwonić pod numer e.preventDefault() na wydarzenie mousewheel i ku mojemu zdumieniu zadziałało.

Kilka rzeczy do uwaga:

1) nie użyć zdarzenia mousewheel aby nawiązać połączenie API. Użyłem zdarzenia scroll wraz z dławieniem.

2) Zdarzenie mousewheel jest niestandardowe i nie powinno być używane. Patrz: https://developer.mozilla.org/en-US/docs/Web/Events/mousewheel

3) ALE w tym przypadku musisz oglądać i obsługiwać wydarzenie mousewheel ze względu na chrome. Inne przeglądarki ignorują zdarzenie, jeśli go nie obsługują, a jeszcze go nie widzę, powodując problem w innej przeglądarce.

4) Nie chcesz dzwonić pod numer preventDefault() za każdym razem, ponieważ wyłącza przewijanie za pomocą myszy :) Jeśli chcesz korzystać z przewijania w pionie, chcesz go wywołać tylko wtedy, gdy deltaY ma wartość 1. Na załączonym obrazie widać, że deltaY to 1, gdy zasadniczo nie można przewijać. Zdarzenie mousewheel jest uruchamiane, nawet jeśli strona nie może przewinąć. Na marginesie, deltaX to -0, gdy przewijasz w pionie, a deltaY jest -0 podczas przewijania w poziomie.

Moje rozwiązanie:

window.addEventListener("mousewheel", (e) => { 
    if (e.deltaY === 1) { 
     e.preventDefault(); 
    } 
}) 

To było jedyne rozwiązanie, które widziałem pracę i nie widziałem go wymienić lub omówione w innym miejscu. Mam nadzieję że to pomogło.

console log of mousewheel event

+1

Wierzę, że to jest związane z Chrome wyposażone https://www.chromestatus.com/feature/5745543795965952 (pasywne detektory zdarzeń) mające na celu uniknięcie pracę kiedy telefony wydarzenia jak touchmove są słuchał - dodawanie każdy detektor zdarzeń "mousewheel" naprawił to dla mnie (nawet jeśli callback był pustą funkcją) – NDavis

-1

Myślę, że możesz zrobić to źle. ™

Zasadniczo, jeśli tak naprawdę dzieje się tylko z Chrome, to prawdopodobnie kod po stronie klienta jest winien, z którego nie ujawniają żadnych szczegółów.

przeciwnym razie próbujesz debugować co obecny jako warunek backend (na podstawie wyboru na metce nginx) z narzędziami Czołowy:

  • próbowałeś wykorzystaniem tcpdump(8), aby rozwiązać problem ? Jakie pakiety są wymieniane i kiedy?

  • Czy próbowałeś rejestrować czasy otrzymania i przetworzenia żądania przez nginx? Np., $request_time?

  • Gdzie znajduje się serwer? Być może doświadczasz utraty pakietów, które może wymagać przekroczenia czasu i retransmisji niektórych pakietów TCP, co niezmiennie wprowadzi losowe opóźnienie?

Wreszcie ostatnia możliwość jest taka, że ​​pole nie znaczy, co myślisz to robi - to brzmi jak może upłynąć trafienie od obciążenia procesora, jak to wynika z XMLHTTPRequest (XHR) przetwarzanie - być może uruchamiasz niektóre reklamy ze śledzeniem użytkowników, które losowo zużywają znaczną część procesora, spowalniając wyniki?