Bagaimana kami memutuskan untuk mengoptimalkan gambar - dan dalam prosesnya kami mendesain ulang situs, panel admin, dan pendekatan antarmuka

Boris Goryachev, direktur teknis Meduza, melaporkan.



Produk utama kami - situs - terus-menerus ditumbuhi dengan fungsi-fungsi baru, tetapi karena itu secara bertahap menjadi lebih berat dan berat. Oleh karena itu, departemen teknis kami sibuk dari waktu ke waktu untuk membuatnya lebih mudah dan cepat.







Salah satu elemen utama yang mempengaruhi kecepatan memuat hampir semua situs, terutama situs media, adalah gambar. Ada banyak gambar di Meduza, dan ini adalah cara yang berharga bagi editor untuk bercerita. Persyaratan layanan foto kami dapat dirumuskan sebagai berikut:



  • gambar harus diupload ke CMS (kami menyebutnya "Monitor") secepat mungkin
  • gambar harus tetap cantik dan terlihat bagus di semua platform
  • pembaca tidak perlu menunggu gambar ini dimuat




Pendekatan pertama



Ketika kami meluncurkan pada tahun 2014, proses bekerja dengan gambar yang dimuat ke Monitor terlihat seperti ini: file dimuat ke dalam aplikasi Rails, menggunakan Paperclip dan Imagemagick, itu dibersihkan dari metadata, dikompresi dengan kualitas yang dipilih (untuk JPEG itu sekitar 75) dan dipotong menjadi tiga ukuran: kecil untuk ponsel, lebih besar untuk tablet dan ponsel dengan layar besar, dan sangat besar untuk komputer. File yang diiris ditempatkan di penyimpanan cloud AWS bersama dengan aslinya. Mereka diberikan (dan diberikan) tidak langsung dari AWS, tetapi melalui CDN kami, yang menyimpannya di server edge-nya.



API yang menghasilkan JSON untuk situs dan aplikasi, kemudian, selain atribut sederhana seperti judul materi, juga memberikan sejumlah besar kode HTML, yang dimasukkan ke bagian "konten" materi dan diberi bobot dengan gaya CSS. Dan API itu sendiri pada waktu itu sama untuk semua klien: situs, aplikasi, dan layanan pendukung seperti RSS dan pencarian.







Segera jelas bagi kami bahwa pendekatan ini tidak akan bertahan dalam ujian waktu, tetapi perlu untuk diluncurkan dengan cepat, menguji sejumlah besar hipotesis, bereksperimen, bertahan. Kami secara sadar - setidaknya kami mempercayainya - memilih "kruk", dan bukan keindahan kode dan solusinya. Waktu berlalu, audiens kami dan produk kami berkembang. Dan seiring dengan ini, selera dewan editorial tumbuh. Para editor menginginkan semakin banyak teknik dan "trik" dalam materi mereka. Di saat yang sama, tentu saja desainnya juga berubah.



Departemen teknis harus memikirkan gaya gambar, metode menampilkannya, ukuran - semua berubah seiring dengan perubahan desain dan elemen baru di situs. Kami menambahkan dan mendukung solusi yang lebih dan lebih aneh.



Ini salah satunya




Seiring waktu, Monitor membuat marah semua orang yang menemukannya lebih dan lebih: staf editorial menderita bug, karena perbaikan bug ini membutuhkan banyak waktu, pengembang marah, dan batasan arsitektur yang diciptakan tidak sesuai dengan bos - kami tidak dapat dengan cepat mengembangkan produk.



Kami mulai mendesain ulang Monitor. Kami menulis ulang bagian utama CMS yang bertanggung jawab untuk mengerjakan materi selama sekitar satu tahun, yang secara teratur terganggu oleh bug di versi lama. Kemudian meme internal muncul di "Meduza": "Ini akan ada di Monitor baru." Ini adalah cara kami menjawab sebagian besar permintaan editor, meskipun, tentu saja, kami melakukan beberapa hal secara bersamaan di CMS lama dan baru: versi buruk untuk saat ini dan versi bagus untuk nanti.



Saya akan segera menulis posting terpisah di blog kami secara detail tentang perubahan "Monitor" .



Mengulang kembali



Setelah memulai ulang dan membangun kembali seluruh Meduza, format API tetap sama, tetapi tidak lagi dibentuk oleh CMS itu sendiri, tetapi diproses oleh layanan terpisah. Dan kami akhirnya memutuskan untuk membagi API menjadi beberapa - untuk klien yang berbeda.



Kami memutuskan untuk memulai dengan aplikasi seluler. Pada saat itu, mereka sudah memiliki pertanyaan tentang desain, UX, dan kecepatan, jadi kami membersihkan aplikasi dan membuat API sesuai keinginan pengembang iOS dan Android kami.



Sebelum pemisahan API, kami menunjukkan bagian konten dari materi melalui WebView, jadi kami tidak dapat menampilkan sesuatu secara eksklusif di aplikasi atau secara eksklusif di situs - semuanya ditampilkan di mana-mana. Sekarang kami memiliki kesempatan untuk mengelola konten dengan lebih fleksibel: untuk memberikan hanya apa yang diperlukan untuk aplikasi seluler, untuk menampilkan elemen berat dengan cara yang berbeda (seperti sisipan video YouTube), dan terakhir untuk membuat Lazy Load, yang memungkinkan Anda untuk secara bertahap memuat elemen berat ke dalam materi - gambar dan sematan.



Setelah memisahkan aplikasi, kami fokus pada situs. Pada titik ini, sudah diputuskan bahwa kami tidak akan membuat perubahan pada kode situs yang ada, tetapi menulis semuanya dari awal (ya, kami terlibat dalam proyek yang berlangsung lebih dari setahun lagi). Pada saat yang sama, direktur teknis kami diganti, dan dalam posisi baru saya, saya harus mengaudit proyek, memutuskan apa yang bisa ditutup, dan mengoordinasikannya dengan atasan saya. Terlepas dari semua kesulitan, tim memutuskan untuk menyelesaikan situs baru. Tetapi sebelum itu, saya memutuskan bahwa kami membutuhkan proyek lain.



Ini adalah bagaimana UI-kit dari Medusa muncul.



Agar fleksibel dalam menyampaikan konten, konten harus dalam bentuk yang paling sesuai untuk transformasi. Batasan semantik unit konten - gambar, paragraf teks, judul - harus selaras. Sebuah konten tidak boleh terlalu sederhana atau terlalu rumit. Jika rumit, kemungkinan besar memiliki lebih dari satu makna. Jika terlalu sederhana, kemungkinan besar, saat menggunakannya, itu harus diberi bobot dengan logika yang rumit, dan ketika Anda perlu menggunakan kembali unit seperti itu, Anda harus menyalinnya di berbagai bagian kode proyek.



Ambil contoh game Medusa.... Mereka memungkinkan Anda menceritakan sejumlah besar cerita dengan cara yang menyenangkan. Mereka dapat dibuat khusus untuk agenda atau atas permintaan pengiklan. Atau permainan dapat dibuat berdasarkan apa yang disebut mekanik - format yang digunakan berulang kali (misalnya, ini adalah tes).



Game di Meduza: Cara Kami Mendesain, Membuat, dan Menggunakan Kembali

Kode game ini tidak terletak pada kode situs. Masing-masing dibuat sebagai layanan mikro terpisah, disematkan ke situs melalui iframe dan berkomunikasi dengan situs itu sendiri melalui postMessage. Dan situs tersebut tidak terlalu peduli apa yang akan ditampilkan di tempat di mana game tersebut akan berada. Selain itu, permainan itu sendiri secara visual tidak dapat dipisahkan dari situs: tipografi dan elemen antarmuka harus sama.







Ketika kami pertama kali mulai membuat game, kami menyalin gaya, tombol, dan hal-hal lain, dan tentu saja itu cepat dan kelihatannya baik-baik saja di luar, tetapi mengerikan di dalam.



Tim memutuskan bahwa ini harus diubah. Kami menghentikan korespondensi situs dan mulai membuat UI-kit kami sendiri - pustaka yang menyertakan semua elemen dan gaya berulang. Kami mencoba untuk tidak melewatkan perspektif panjang: situs, dan game, dan mekanik - semuanya harus mulai menggunakan pustaka yang sama.



Semua proyek Meduza di web ditulis dalam React, dan UI-kit adalah modul npm yang sekarang terhubung ke hampir semua yang kami kembangkan. Dan pengembang, ketika dia perlu merender sesuatu, menulis sesuatu seperti ini: membuat blok.







Apa fungsinya?



  1. Pengembang front-end tidak benar-benar memikirkan cara merender sesuatu.
  2. Semuanya sudah ditinjau oleh departemen desain.
  3. : UI-kit, , , . , ยซยป, .
  4. โ€” - UI-kit ( ) .


UI-kit



Ada dua kelompok komponen: konten dan front-end. Yang terakhir adalah komponen React yang sangat sederhana seperti tombol dan ikon.











Komponen Konten sedikit lebih kompleks, tetapi masih sangat sederhana komponen React dengan gaya yang mewakili satu unit konten. Misalnya, seperti inilah tampilan komponen paragraf:







Komponen yang "menangkap" blok sederhana







Dan ini adalah komponen yang menampilkan gambar:







API tempat situs mengambil data, di dalam setiap materi berisi larik komponen yang akhirnya "dirender" melalui UI-kit ... Dengan game, semuanya bekerja sama, mereka hanya menggunakan datanya ke versi API mereka.



Hore, kami telah memulai kembali!



Di bawah ini adalah grafik yang menunjukkan waktu buka halaman rata-rata. Ini adalah indikator yang sangat tidak tepat - semua halaman di semua perangkat diperhitungkan - tetapi bahkan memberikan gambaran tentang tren.







Grafik tersebut menunjukkan bagaimana kecepatan situs telah berubah selama seluruh keberadaan Meduza. Saat kami pertama kali meluncurkan dengan situs yang sangat sederhana pada tahun 2014, itu sangat cepat. Tetapi ketika kami mulai menambahkan fitur baru, kecepatan unduh menurun.



Dan ini adalah jadwal yang sama, tetapi untuk dua tahun terakhir. Ini menunjukkan bagaimana waktu buka halaman turun setelah situs dimulai ulang.







Kemudian waktu untuk berfoto akhirnya tiba.



Gambar-gambar



Skema bekerja dengan gambar dulu. Gambar itu datang melalui API, yang memiliki alamat seperti /images/attachments/.../random.jpg . File itu sendiri disajikan dari penyimpanan cloud AWS melalui CDN kami.







Kami merumuskan persyaratan untuk sistem baru sebagai berikut:



  • solusinya memungkinkan kami untuk dengan cepat mengubah ukuran dan kualitas gambar yang dikirim
  • tidak harus mahal
  • itu harus menahan banyak lalu lintas


Skema yang kami perjuangkan ternyata seperti ini. Backend akan menghasilkan URL yang akan diambil oleh klien - browser atau aplikasi. URL akan berisi informasi tentang gambar apa yang dibutuhkan, dalam kualitas apa dan ukuran apa yang seharusnya.



Jika gambar di URL ini sudah ada di server Edge, itu akan segera disajikan ke klien. Jika tidak, server Edge akan "mengetuk" di server berikutnya, yang sudah meneruskan permintaan ke layanan. Layanan ini, setelah menerima URL gambar, akan mendekodekannya dan menentukan alamat gambar asli dan daftar operasi di dalamnya. Setelah itu, layanan akan menyajikan gambar yang telah diubah sehingga akan disimpan di CDN dan disajikan atas permintaan.







Meduza sudah punya solusi serupa. Misalnya, kami juga membuat gambar untuk cuplikan materi dan game kami di jejaring sosial - dalam layanan ini kami membuat tangkapan layar halaman HTML melalui Headless Chrome.



Layanan baru ini diharapkan dapat bekerja dengan gambar, menerapkan efek sederhana, cepat dan tangguh. Karena kami suka menulis semuanya sendiri, awalnya direncanakan untuk menulis layanan seperti itu dalam bahasa Elixir. Tetapi tidak ada seorang pun di tim yang memiliki cukup waktu, dan tentunya tidak ada yang memiliki keinginan untuk terjun ke dunia jpg, png dan gif yang indah.



Kami masih perlu menemukan pustaka yang akan menangani kompresi gambar. Imagemagick, yang sudah kami alami, bukanlah solusi tercepat, tapi setidaknya kami tahu cara memasaknya. Segala sesuatu yang lain masih baru, dan akan ada banyak hal yang harus diperiksa.



Kami juga membutuhkan dukungan untuk format gambar webp.



Waktu berlalu, mental kami mempersiapkan diri untuk membenamkan diri dalam proyek ini. Tapi kemudian salah satu programmer kami membaca tentang pustaka imgproxy, yang diunggah oleh orang - orang dari Evil Martians ke Open Source .



Menurut deskripsi, itu adalah hit yang sempurna: Go, Libvps, image Docker siap pakai, konfigurasi melalui Env. Pada hari yang sama, kami menerapkan perpustakaan di laptop kami dan meminta DevOps kami untuk memainkannya juga. Tugasnya adalah memunculkan layanan dan mencoba mematikannya - jadi kami akan memahami beban apa yang akan ditahannya di server kami. Selama waktu ini, tim backend terus bermain dengan proyek di komputer mereka: kami menulis skrip Ruby dan menguasai fungsi yang tersedia.



Saat DevOps kembali dengan keputusan bahwa perpustakaan dapat digunakan dalam produksi, kami mengumpulkan sejumlah besar gambar yang melewati imgproxy - kami terutama tertarik pada webp - dan mengambil foto mereka untuk mengarahkan. Karyawan departemen teknis tidak dapat memutuskan sendiri apakah kualitas ini cocok untuk kami atau tidak. Editor foto mengirimi kami komentar mereka, kami mengubah sesuatu, memastikan bahwa gambar tidak terlalu berat, dan pergi untuk menulis kode backend.



Di sini semuanya ternyata sangat sederhana: karena dalam versi API untuk situs, gambar sudah dipisahkan oleh komponen dari yang lainnya, kami cukup memperluas JSON mereka dan menambahkan alamat tambahan dalam berbagai ukuran dan format.











Yang diperbarui segera masuk ke produksi, karena kami tidak mengubah apa pun, tetapi hanya menambahkan - orang-orang di frontend dapat mengembangkan fungsi semua dalam versi API yang sama. Mereka memperluas komponen gambar dalam hal fungsi, menambahkan kumpulan gambar untuk ukuran berbeda dan "penopang" khusus untuk Safari. Kami mengubah tabel ukuran beberapa kali dan memeriksa hasilnya melalui sudut pandang kantor editorial - untuk ini kami memberinya versi situs saat ini dan duplikat dengan gambar baru untuk ditinjau.



Saat komentar berhenti masuk, kami akhirnya menerapkan, menghapus cache, dan meluncurkan produksi.



Keluaran



Inti dari perubahan kami dapat diringkas sebagai berikut: kami telah menggeser tempat pengambilan keputusan yang gambarnya harus diberikan dalam bentuk apa ke tempat di mana konteksnya lebih dipertimbangkan dan implementasi serta dukungan lebih mudah diimplementasikan.



Sekarang hampir semua gambar yang Anda lihat di Meduza adalah hasil karya imgproxy, dan dalam setiap kasus gambar tersebut memiliki ukuran berbeda dan terkadang kualitas berbeda. Hal ini ditentukan oleh konteks - apakah konten tersebut terbuka di web, aplikasi seluler, atau AMP - yang diketahui oleh layanan API yang menghasilkan respons.



All Articles