
Beberapa waktu lalu, saya menjadi tertarik dengan kinerja situs web, pengunduhan unduhan, dan sejenisnya. Dan sekarang, sekali lagi pergi ke Habr, saya berpikir bahwa saya terbiasa melihat pemuatan sumber daya yang lebih cepat sebagai sesuatu yang diberikan, bahkan tanpa memikirkan bagaimana hal ini dicapai. Oleh karena itu, saya memutuskan untuk menggabungkan bisnis dengan kesenangan - untuk melihat bagaimana keadaan dengan kinerja Habr dan solusi teknis apa yang dibuat untuk mengoptimalkannya.
Bagi mereka yang tertarik mengetahui apa yang telah dilakukan sehingga kami menerima konten secepat mungkin dan bagaimana unduhan Habr dari Argentina terlihat seperti - tolong, di bawah kucing.
Persiapan
Kami membutuhkan versi baru Chrome / Canary yang bekerja dalam mode anonim (pastikan semua ekstensi dimatikan). Juga, di Developer Console (Developer Tools - F12), di tab jaringan, Anda harus mengatur flag cache yang dinonaktifkan, karena Kami hanya akan membuat profil boot pertama, sementara belum ada sumber di cache.
Tahap Satu - "Lantai Atas"
Tujuan utama dari bagian ini adalah untuk berkenalan dengan situs secara keseluruhan, untuk memahami strukturnya dan mencari tahu sumber daya spesifik apa yang dibutuhkan.
Kami membuka alat pengembang, buka tab jaringan, buka situs dan di bagian paling bawah tab kami melihat statistik penggunaan jaringan:

Seluruh situs dimuat dalam 2,02 detik, yang tampak hebat (mengingat beban Habr). Acara DomContentLoaded (selanjutnya hanya DCL) umumnya muncul dalam 1,01 detik yang terlihat lebih baik. Dengan semua ini, situs ini membuat 189 permintaan dan memuat 9,6MB sumber daya. Ini memberi tahu kita bahwa tim Habra jenius (mungkin juga), dan artikel tersebut harus diselesaikan di sini (dan minta mereka untuk minum kopi dan kue), atau ingat bahwa saya memiliki saluran 100 Mb / s dan Core I7 . Yaitu Anda perlu sedikit lebih dekat dengan kenyataan dan setidaknya membatasi lebar saluran.
Kami mengaktifkan mode Fast 3G dan melihat lagi:

DCL memburuk menjadi 3,48 detik, yang masih bisa diterima. Namun akhirnya situs tersebut dimuat dalam atheistik 54,76 detik. Sekarang semuanya logis - Anda tidak bisa hanya mengunduh dan mengunduh hampir 10 megabita ketika koneksi Anda lemah. Kemungkinan besar, orang-orang melakukan pekerjaan yang baik untuk menunjukkan kepada kami konten secepat mungkin (ini dibuktikan oleh fakta bahwa bahkan dalam mode fast3g DCL muncul cukup cepat), dan semua yang tidak kritis dibiarkan dimuat di latar belakang. Kami akan memeriksanya sedikit nanti, dan sekarang mari kita lihat mengapa kami memuat begitu lama. Urutkan semua permintaan berdasarkan waktu buka:

Diklik
Gambar (top-7) dimuat paling lama dan satu file JavaScript adalah prebid.js. Jika kita melihat ukurannya, kita dapat mengasumsikan bahwa ini adalah alasan tepatnya untuk loading yang lambat.
Tentang asumsiDengan asumsi Anda harus sangat berhati-hati. Misalnya, pemuatan sumber daya yang lama dapat disebabkan tidak hanya oleh ukuran file, tetapi juga, misalnya, masalah dengan DNS, beban penyimpanan puncak, atau cache server dingin. Oleh karena itu, asumsi yang tidak terverifikasi dapat menyebabkan Anda membuang waktu untuk menyelesaikan masalah yang bahkan tidak ada.
Melihat statistik ( TTFB : 0,610 ms, memuat: 40 000 ms), kita dapat menyimpulkan bahwa asumsi kami sangat mungkin. Mari kita kagumi TOP 1 kita (png, 1560X780, 24bit):

Bahkan, masalah dengan gambar terutama masalah lalu lintas kami dengan Anda. Gambar (tidak seperti gaya dan skrip) tidak memblokir perenderan halaman web, dan oleh karena itu, meskipun ada kelas berat seperti itu (bisa lebih buruk, mereka melihatnya), ini hampir tidak mempengaruhi kinerja. Meskipun, tentu saja, optimasi ke arah ini (misalnya, transcoding ke jpeg2000 atau webp, atau pemuatan progresif tidak akan berlebihan).
Tentang gambarSeperti yang saya tulis di atas, gambar tidak memblokir rendering halaman. Tetapi mereka menggunakan kumpulan koneksi kami, dan di http 1.x jumlah mereka terbatas, dan dengan http 2.x dan Chrome juga, tidak semuanya semulus yang saya dengar. Oleh karena itu, bahkan di sini ada kemungkinan bahwa beberapa gambar dapat memperlambat pemuatan skrip sinkron, dan pada gilirannya, sudah akan berhenti membuat halaman. Selain itu, memuat gambar juga dapat menyebabkan penghitungan ulang tata letak, sehingga memperlambat proses rendering. Jika kita melihat marka Habr, hampir semua tag img memiliki lebar dan tinggi. Ini menghilangkan kebutuhan untuk reflow untuk secara positif mempengaruhi kinerja unduhan. Anda dapat membaca lebih lanjut tentang ini di sini .
Mari kita lihat sumber daya apa yang menarik Habr - kita akan membahas jenis dan mengurutkannya berdasarkan waktu muat. Mari kita mulai dengan JavaScript
Javascript
Tentang javascriptJavaScript memiliki beberapa masalah dalam hal kinerja situs. Pertama (semua orang tahu tentang ini untuk waktu yang lama), js sinkron memblokir rendering halaman lebih lanjut. Yaitu sampai kami menerima dan menjalankan JavaScript kami, browser akan menunggu (sebenarnya tidak cukup, browser, terutama Chrome, dapat mengoptimalkan, tapi ini adalah cerita lain) dan tidak akan membuat konten lebih lanjut. Menggunakan skrip sinkron di kepala, kami menunda saat ketika pengguna melihat setidaknya sesuatu (bahkan teks). Oleh karena itu, semua orang mencoba untuk melempar Js di akhir halaman atau bahkan membuatnya tidak sinkron. Ini berfungsi, tetapi tidak menyelesaikan masalah kedua yang membawa kita fakta bahwa JavaScript masih merupakan bahasa scripting. Oleh karena itu, peramban tidak cukup hanya dengan mengunduhnya - browser juga harus "dipahami". Dan di sini, ternyata ini adalah masalah, karena prosesor yang lemah (misalnya, di ponsel atau netbook murah, atau bahkan laptop yang bagus dalam mode kinerja terbatas) melakukannya perlahan, menghalangi utas utama! Di bawah ini adalah contoh bagaimana skrip iklan asinkron memasuki bagian penting dari Habr render dan meskipun sedikit, tetapi masih merusak kinerjanya. Jika ada yang tertarik, ada artikel yang sangat (sangat, sangat) bagus tentang topik ini.
Script Habr memuat banyak - 1,1 MB (dan ini sudah dalam bentuk terjepit) untuk 40 permintaan. Ini sangat penting, masih kembali kepada kita dan kita perlu melakukan sesuatu. Urutkan skrip kami "dengan air terjun." Tugas kami adalah menemukan skrip yang dimuat SEBELUM garis biru, karena mereka (kemungkinan besar) yang mencegah kami membuat situs secepat mungkin.

Diklik
Kami membuka html yang diberikan Habr (penting untuk melihat jawabannya, karena html terakhir akan terlihat berbeda) dan memeriksa daftarnya. Seperti yang Anda lihat - jQuery, raven.js, advertise.js dan adriver.js dimuat secara sinkron langsung dari tag kepala (mis. Mereka memblokir semuanya sama sekali). Gpt dan penerbit dimuat dari kepala tetapi sudah tidak sinkron (mis. Mereka tidak memblokir apa pun, peramban akan membuat laman lebih jauh saat memuat). Vendor, Main dan Math, checklogin dimuat di bagian akhir, tetapi secara sinkron (mis. Teks sudah ada di sana, kita bisa membacanya, tetapi DCL tidak akan muncul sampai mereka memuat). Sisanya tidak muncul dalam jawaban awal - mereka ditambahkan secara dinamis, tetapi ini adalah topik lain.
Jadi, kami menemukan skrip yang entah bagaimana memengaruhi seberapa cepat kami melihat teks pada halaman. Ini adalah kandidat pertama untuk optimasi. Idealnya, mereka harus dibuat tidak sinkron atau ditempatkan serendah mungkin untuk memungkinkan browser memberikan konten untuk kita. Namun, yang ideal tidak dapat dicapai, karena kemungkinan besar ada skrip lain di situs yang bergantung pada jQuery yang sama. Keinginan untuk mengunduh gagak sesegera mungkin - perpustakaan untuk melacak berbagai kesalahan yang terjadi pada klien, juga dapat dipahami. Tetapi advertise.js dan adriver.js sudah menjadi kandidat nyata untuk setidaknya pindah ke bawah halaman, dan sebagai maksimum juga dalam mode asinkron. Kisah serupa dengan gpt dan penerbit. Ya, mereka dimuat secara tidak sinkron, tetapi, bagaimanapun, mereka dapat (dan akan) mengganggu kita saat memuat. Karena itu, mereka juga dapat dikirim ke bagian paling bawah halaman. Selain itu, Anda dapat mencoba menggunakan atribut Resource Hints - preload / prefetch / dns-prefetch untuk memberi tahu browser apa yang harus dimuat terlebih dahulu. Ngomong-ngomong, saya menyarankan Anda untuk membaca tentang Petunjuk Sumber Daya - alat yang sangat menarik, meskipun dengan dukungan yang terbatas (sejauh ini).
Sekarang urutkan daftar berdasarkan ukuran file:

https://github.com/Drag13/articles/blob/habrformance/habrformance/scripts.PNG
Kami melihat skrip yang memuat dua kali (pubads). Kami juga memperhatikan bahwa prebid.js diambil dari folder not-for-prod

Untuk menghapus nurani kami, kami memeriksa bahwa semua skrip diperkecil. Tiba-tiba, skrip check-login.js dan adriver.js tidak dikecilkan. Terutama senang dengan konten yang terakhir:

Dan dengan skrip Anda dapat mengakhiri sementara.
Gaya
Tentang gayaDengan gaya, semuanya juga tidak begitu sederhana. Pertama, memuat gaya secara sinkron juga memblokir utas utama (meskipun mereka diuraikan dengan cepat, lebih cepat dari JavaScript). Dan kedua, semuanya sedikit lebih rumit. Mengapa browser membutuhkan CSS? Untuk membangun CSSOM . Apa yang bisa dilakukan JavaScript dengan CSS? Itu benar - ubah. Dan apa yang akan terjadi jika CSSOM belum dibangun, dan js sudah mencoba mengubah sesuatu di sana? Jawabannya adalah siapa yang tahu. Karena itu, browser menunda eksekusi JavaScript hingga CSSOM dihitung. Seperti yang ditulis dengan benar di artikel lain yang sangat bermanfaat - tanpa CSS = tanpa JavaScript. Oleh karena itu, memuat CSS memblokir eksekusi JS.
Berikut adalah gaya yang dimuat Habr:

Diklik
Seperti yang Anda lihat, hanya ada tiga, dengan yang kedua dan ketiga dimuat dalam bingkai yang terpisah, jadi kami abaikan. Tetapi set gaya pertama sangat penting untuk seluruh situs. Dan kami mengunduhnya untuk waktu yang sangat lama. Mengapa Pertama, mereka menunggu lama untuk tanggapan dari server (TTFB 570 ms, kami akan kembali ke sana di bagian ketiga), dan kedua, 713 ms dimuat untuk waktu yang lama. Apa yang bisa dilakukan di sini. Yang pertama dan paling sederhana adalah mencoba menambahkan atribut preload. Ini akan meminta browser untuk mulai memuat CSS sedini mungkin. Opsi kedua adalah untuk menyoroti CSS kritis dan menanamkannya langsung ke halaman web, dan memuat sisanya secara sinkron (atau bahkan tidak sinkron). Ini akan menyebabkan peningkatan ukuran halaman (tapi itu tidak kecil dan + 5kb tidak akan merusak apa pun) dan kemungkinan redraw dari tata letak (kehilangan waktu), tetapi Anda dapat mencoba.
Saya bahkan tidak akan menampilkan font. Itu ada di sana sendiri, meskipun untuk beberapa alasan itu dimuat langsung dari server Habr bukan CDN (dan kemungkinan besar karena suatu alasan). Tapi saya akan mengucapkan terima kasih untuk kenyataan bahwa hanya ada satu font.
Pada ini, bagian ikhtisar analisis situs dapat dianggap selesai. Saatnya masuk lebih dalam.
Tahap Dua - "Mode Manual"
Pada tahap terakhir kami melihat bahwa Habr memuat. Sekarang kita akan melihat bagaimana ini diterjemahkan.
Buka tab profiling. Kami memeriksa apa perlambatan fast3g (kemudian jalankan lagi tanpa batasan) dan jalankan. Pertama-tama, kami tertarik pada semua yang terjadi sebelum acara First contentful paint (FCP) , dan, untuk berjaga-jaga, DCL. Kami memilih area dari awal pemuatan ke FCP dan melihat diagram terakhir.

Semuanya terjadi cukup cepat - 2,161 detik sebelum FCP (lebih cepat, tetapi tampaknya ada sesuatu yang berubah), tetapi seperti yang Anda lihat, sebagian besar waktu browser tidak digunakan. Muatan hanya memakan waktu 14% dari waktu (sekitar 310 ms). Idealnya, utas peramban utama berjalan terus menerus - parsing html, CSS, mengeksekusi JS. Dan di sini - tidak ada. Mengapa Karena browser tidak ada hubungannya. Ingat kami mengurangi lalu lintas? Peramban telah mengirim permintaan dan sekarang tinggal menunggu sampai selesai. Jika kita membuka diagram proses jaringan (yang paling atas) semuanya akan segera menjadi jelas.

Diklik
Pada 2029, browser melihat main.bundle.css, mengirim permintaan untuk menerimanya dan mulai menunggu. Pada saat ini, prescanner (smart chrome, dapat berjalan di depan) menemukan bahwa ada skrip sinkron di bawah ini dan tanpa menunggu css tiba, ia mengirim permintaan untuk skrip. Kemudian beriklan dan adriver dimuat (tetapi kami ingat bahwa sementara CSSOM tidak dibuat, Anda tidak dapat menyentuh JS), sehingga browser mengabaikannya. Setelah itu, gpt dan gagak dimuat, tetapi CSS masih memuat, jadi mereka juga diabaikan. Akhirnya, CSS dimuat, yang diurai browser dalam 12 ms dan segera pergi untuk mem-parsing JS yang tertanam di halaman. Kemudian browser kembali "tertidur" di hampir 150 ms menunggu jQuery.min.js. Dan setelah itu saya sudah mulai bekerja dengan serius - Saya menemukan jQuery yang dimuat (20 ms), mem-parsing raven.js (4 ms), mem-parsing hampir seluruh halaman (36 ms), menceritakan gaya (28 ms), menghitung tata letak (78 ms + 8 ms) dan, akhirnya, selama ~ 6 ms, kami mengecat halamannya. Di sini kami mendapat FCP. Selanjutnya, kita parsing halaman, parsing skrip - halo kepada siapa pun (publishertag.js, gpt.js yang masuk ke utas utama sebelum DCL), bermain-main dengan gaya sedikit (yang menyebabkan sedikit kehilangan waktu karena perhitungan ulang tata letak) dan mulai menunggu vendor. bundle.js. Untuk menunggu vendor, kami hampir menghabiskan 1100 ms lagi. Benar, secara paralel dengan itu, kami juga memuat main.bundle.js (yang, kebetulan, boot lebih cepat), jadi tidak semuanya buruk. Kemudian semuanya berjalan dengan baik lagi. Kami parsing vendor, parsing bundel utama, parsing Math.Jax, dan akhirnya parsing halaman dan mendapat DCL. Benar, beberapa jenis handler bekerja di sana yang pada I7 saya menghentikan utas utama pada 80 ms (yaitu situs tersebut tampaknya membeku pada 80 ms). Sekarang kita hampir tidak melihat ini, tetapi pada prosesor yang lemah, secara teoritis, itu bisa terlihat. Jika Anda melihat ini setelah konten diberikan, ini adalah kesempatan untuk memeriksa JS.
Apa yang bisa saya katakan. Lagi-lagi, terlepas dari kenyataan bahwa itu terlihat cukup bagus. Masalah utama disampaikan kepada kami:
- Peramban sederhana yang besar (termasuk karena ketidakseimbangan buatan antara daya komputasi komputer dan lebar saluran, tetapi ini juga merupakan skenario yang cukup valid)
- Pemuatan CSS lama yang menunda kerja dengan js kritis
- Pemuatan sinkron jQuery, vendor, dan bundel utama yang menghentikan tampilan konten.
Apa yang bisa kita lakukan dengan ini sudah kita bahas:
- Coba tambahkan atribut preload untuk CSS dan mungkin beberapa JS
- Kurangi atau sebaris CSS
- Cobalah untuk membuang skrip secara umum dari pemuatan sinkron (setidaknya beberapa)
Sekarang mari kita ulangi hal yang sama tanpa batasan pada lebar saluran. Gambar sudah jauh lebih baik: 0,452 detik untuk FMP, yang paling sederhana! 13 md. DCL - 953 ms, sederhana 15 ms. Seperti inilah unduhan impian saya. Itulah yang terjadi karena saya membuka tab baru dan tidak menghapus caching. Mari kita coba hal yang sama, tetapi tanpa cache:

Semuanya juga cukup baik, FCP / FMP - 1689, payload 45%. Omong-omong, menyesuaikan beban hingga 100% juga buruk, karena mesin yang lebih lemah akan kelebihan beban. Jadi lebih baik memiliki cadangan untuk waktu henti. Tapi, di sini secara tak terduga banyak waktu dihabiskan untuk Rendering - 400 ms untuk FMP. Dari jumlah tersebut, 200 ms masuk ke perhitungan ulang gaya dan perhitungan kembali tata letak.
Ngomong-ngomong, poin menarik lainnya. Ingat skrip iklan - gpt.js dan publishertag.js yang disebutkan di bagian pertama? Sekarang Anda dapat melihat bahwa meskipun tidak sinkron, mereka mampu (walaupun sedikit) merusak statistik kami. Ini terjadi karena eksekusi skrip asinkron dilakukan sesuai dengan kesiapan skrip itu sendiri. Yaitu ini dapat terjadi kapan saja, termasuk sebelum FCP / DCL, yang terjadi pada 3309.
Jadi, kami melakukan pembongkaran manual. Sudah waktunya untuk mengungkap otomatisasi.
Tahap Tiga - βKami harus mulai dari iniβ
Tentang pertanian kolektifSaya pikir semua orang mengerti bahwa penelitian ini sangat sewenang-wenang. Setidaknya, karena sepanjang waktu ketika saya menguji artikel baru muncul, beban di server dan beban di tulang punggung jaringan berubah. Dengan cara yang baik, Anda perlu menggunakan server khusus di mana tidak ada yang akan menulis apa pun, meniru beban yang relevan dengan penundaan yang relevan, dan hanya kemudian membuat profil sesuatu. Jika tidak, Anda dapat membuat beberapa asumsi, (misalnya, tentang perlunya menambahkan atribut preload pada CSS), menambahkannya, menyebarkannya ke produksi, dan kemudian ternyata beban selama pengujian meningkat tajam dan server memberi kami gaya yang sama 500 ms nanti. Dan ternyata preload itu buruk - itu hanya membuat segalanya lebih buruk. Dan penulisnya adalah lobak terakhir. Selain itu, pembuatan profil secara manual (seperti pada bagian kedua), hingga Anda menjalankan semua alat otomatis dan menyelesaikan masalah yang ditemukan di sana, juga tidak masuk akal, karena setelah perubahan pertama Anda gambar akan berubah.
Karena itu, sebelum melakukan percobaan, kita memerlukan lingkungan yang paling stabil. Kali ini Yang kedua - Anda seharusnya tidak masuk terlalu dalam (misalnya, membuat profil) sejak awal. Mulai alat otomatis pertama, biarkan mereka bekerja untuk Anda. Kumpulkan laporan, lihat apa yang bisa dilakukan sebaik mungkin dalam waktu minimal. Coba lakukan itu. Jika memungkinkan, Anda mungkin sudah cukup. Sebagai contoh, css.bundle Anda memiliki berat 100kb, tetapi pada kenyataannya Anda membutuhkan 45kb (omong-omong, situasi sebenarnya: mereka mengambil seluruh bootstrap, tetapi hanya grid yang diperlukan). Mereka mengurangi ukuran gaya dan memenangkan setengah detik praktis tanpa biaya. Ini dua. Selalu periksa ulang. Tampak bahwa gaya disatukan, semuanya harus menjadi lebih baik, tetapi akan menjadi lebih buruk. Mengapa Dan karena dalam gaya gambar base64 50kb, dan halaman kami hanya memuat 200kb sumber daya. Ingatlah bahwa tidak ada peluru perak dan skrip universal. Ini tiga. Dan yang terakhir, bahkan jika itu bertentangan dengan kalimat sebelumnya. Jika Anda tidak memiliki situs yang rumit, cukup pantau TTFB (masalah server), ukuran sumber daya yang diunduh (halo ke logo sebesar 2MB) dan jangan berikan akses ke Google Pengelola Tag, siapa pun. Kemungkinan besar ini sudah cukup.
Kami tidak akan melangkah jauh, di Alat Pengembang yang sama, membuka tab audit dan meluncurkan LightHouse (LH) dengan pengaturan berikut: desktop, hanya kinerja, tidak ada pembatasan, penyimpanan yang jelas. Setelah menunggu sedikit (jangan meninggalkan halaman di mana audit sedang dilakukan dan tidak melakukan hal yang lebih baik) kami mendapatkan angka fantastis (bahkan dengan cache dinonaktifkan)

Bahkan bagi saya tampaknya mereka secara khusus disesuaikan dengan angka-angka ini.
Namun, LH masih mengeluhkan:
- Format gambar yang ketinggalan jaman (disarankan menggunakan webp, jpeg2000, dll)
- DOM node β : 2533, 1500.
- β 23
- document.write
. (), DOM β node (-), ( ), document.write- writer ( - )
( ) . , , , . , , . CSS, β , , JavaScript. , , . .
, fast3g , , ( I7, celeron):

( FCP 3500 ms, FMP 5.7):
- , . LH next-gen , , , 11
- . adriver.js advertise.js 50 , .
- CSS , 5kb 45kb.
- main thread. JavaScript β (8.5 script evaluation 2186 ms raven.js). ?
? . - . :
, , (, raven.js).
, , β webpagetest.org
β , , . β , . , . , , . , , , β -.
https://habr.com ( ru/en ).

( , )
. ( ) DNS (500 ms ), , ssl . , 1150 ms c ( ). , ( habrastorage).
main.bundle.css. , dr.habracdn.net , dns lookup β 36 ms ( 400 ms). SSL negotiation 606 ms, TTFB 601 ms, . . DCL β 4100 ms , .
image analysis , , . - PNG 1.4, webp + downscaling ( , ) β 17.7 KB. , , png 154. . , :
- ( , , .. ).
- . , .
- TTFB (webpagetest F ) β
- , ( )
Kesimpulan
. :
:
- TTFB 500 ms ( dns, ssl initial connection)
- habrastorage
:
, , . , , . , SPA, , JS β . . //,
PS.Saya minta maaf untuk sejumlah besar Anglicisms (terutama untuk tata letak) dan untuk Longrid. Tapi tanpa mereka, ini sangat sulit, dan semua bagian ini 1, 2, 3, saya sudah bosan dengan pesanan.