Myapp memperpanjang liburan


Saya yakin bahwa akan ada orang-orang di antara hadirin yang dihormati yang akan mengerti saya. Faktanya adalah bahwa di semua banyaknya perpustakaan dan kerangka kerja populer untuk web frontend, saya pribadi tidak menyukai hampir semua alternatif. Dalam setiap opsi yang saya temukan sendiri kerugian yang signifikan yang mencegah saya menggunakannya dengan tenang. Semuanya selalu dimulai dengan cara yang indah: konsep yang menarik, suara, pada pandangan pertama, alasan dalam poin "untuk" ... Tapi kemudian, semuanya, lagi dan lagi, mulai mengalami ketergantungan yang berlebihan, entitas yang berlebihan dan upaya untuk menyelesaikan masalah yang dibuat oleh pengembang sendiri. Kami ditawari untuk mempelajari sintaks baru, menerima ide-ide baru, mempelajari banyak kata kunci, menginstal banyak paket "yang diperlukan". Oke, saya suka semua yang baru, dan saya suka kata-kata pintar. Tetapi saya sangat berkecil hati ketika apa yang bisa dilakukan secara sederhana, orang-orang mulai mengalami keruwetan. Anda mungkin sudah membaca pengakuan orang-orang yang, seperti saya, putus asa mencari akal sehat dalam semua ini dan memutuskan untuk pergi ke ekstrem yang lain - untuk menulis segala sesuatu "dalam vanila". Ini terjadi pada saya ketika saya kecewa dengan proyek Polymer , dibuat dengan partisipasi aktif dari pengembang dari Google. Pada awalnya saya sangat menyukai semuanya, moto gerakan ini adalah frase "Gunakan platform!", Yang berarti bagi saya: "Anda tidak boleh melakukan dalam kode apa browser itu sendiri akan melakukan lebih efisien". Tim Polymer telah melakukan banyak hal untuk memperkenalkan standar dan kemampuan baru di tingkat platform, dan banyak terima kasih kepada mereka untuk itu. Tetapi ketika tujuan ini tercapai , mereka sendiri mulai melanggar prinsip mereka sendiri. Dan sekarang perpustakaan baru mereka ( LitElement ) sudah menolak untuk bekerja secara langsung di browser tanpa menginstal lingkungan khusus, karena mereka tidak mengikuti standar ... Saya terus mengamati pengembangan LitElement, dan bahkan melihat tanda-tanda yang jelas bahwa orang-orang yang tersesat ini kembali ke jalan yang benar, tetapi saya sendiri sudah Saya tidak akan menggunakannya, karena sekarang saya memiliki sesuatu yang lebih baik.

Apa?


Holiday.js adalah perpustakaan untuk mereka yang membutuhkan semua yang mereka butuhkan dan tidak perlu tambahan apa pun. Liburan - karena bekerja dengannya untuk saya adalah hari libur. Dan juga karena saya menulisnya, terutama pada hari libur atau berlibur. Namun demikian, ini adalah proyek yang sangat serius, dengan bantuan serangkaian aplikasi kompleks sedang dikembangkan untuk "perusahaan berdarah" yang sangat disukai orang-orang untuk menakuti para pemula membangun sepeda. Saya juga menulis semua proyek pribadi saya di Holiday.js.

Semuanya didasarkan pada elemen standar dan Shadow DOM standar grup, seperti yang Anda duga, dan jika Anda sudah terbiasa dengan mereka, akan sangat mudah bagi Anda untuk mengetahuinya.

Sedikit tentang diriku
Umur saya 40 tahun. Saat ini, saya adalah pengembang web dan insinyur R&D terkemuka di sebuah perusahaan Belanda yang berspesialisasi dalam solusi integrasi dari IBM. Pelanggan kami adalah perusahaan besar: minyak, gas, tanker, kereta api - itu saja. Inti dari pekerjaan saya adalah untuk memperluas kemampuan standar untuk sistem perusahaan besar dan lambat dan meningkatkan pengalaman pengguna ketika bekerja dengan mereka. Di satu sisi, saya memiliki paman dalam ikatan, di sisi lain - angin segar kebebasan pengembangan web modern. Ini adalah kombinasi yang menarik, memungkinkan Anda untuk melihat banyak hal dari sudut pandang baru. Dan saya menyukainya. Sebelumnya, saya mencoba peran sebagai startup, insinyur ux, art director dari studio desain kecil, dan banyak lainnya, sehingga "pengalaman" saya secara keseluruhan seperti selimut kain perca. Tapi ini tidak berarti bahwa saya berhubungan dengan semuanya secara dangkal, saya hanya menemukan dalam banyak jenis kegiatan prinsip-prinsip teknik serupa yang menarik minat saya pertama-tama.

Apa gunanya


Jika saya sendiri membaca artikel serupa agar tidak kehilangan minat lebih lanjut, saya ingin melihat contoh kode komponen. Ini dia:

import {HdElement} from '../../holiday/core/hd-element.js'; class MyComponent extends HdElement { constructor() { super(); this.state = { imageURL: 'images/photo.jpg', firstName: 'John', secondName: 'Snow', }; } } MyComponent.template = /*html*/ ` <style> :host { display: block; padding: 10px; background - color: #fff; color: #000; } </style> <img bind="src: imageURL" /> <div bind="textContent: firstName"></div> <div bind="textContent: secondName"></div> `; MyComponent.is = 'my-component'; 

Di sini kita melihat bahwa komponen memiliki keadaan dan templat tertentu dengan atribut aneh dari elemen " bind ". Atribut-atribut ini adalah keajaiban utama: mereka memungkinkan Anda untuk mem-parsing templat dan menyimpan salinan hasil dalam memori untuk digunakan lebih lanjut (kloning) TANPA pemrosesan tambahan dari string templat di runtime JS, yang memberikan kinerja tinggi selama rendering awal ketika setiap komponen dipakai. Tidak seperti banyak perpustakaan modern di mana bagian DOM yang menjadi tanggung jawab komponen ditentukan oleh fungsi negara, di Holiday.js templat adalah produk setengah jadi yang mendefinisikan struktur awal dan memungkinkan untuk mengikat data nanti, menggunakan DOM API biasa, dan ini bekerja sangat cepat. Kami akan kembali ke masalah kecepatan.

Saya akan mencantumkan keuntungan lainnya:

  • Kedekatan maksimum dengan API asli, abstraksi tambahan minimum
  • Sintaks templat asli: Anda tidak perlu mempelajari HTML dan CSS baru
  • Untuk memulai, Anda tidak perlu menginstal tambahan apa pun, proyek Anda mungkin tidak memiliki folder node_modules sama sekali
  • Kemudahan: Anda tidak akan memaksa pengguna untuk menunggu lama untuk mengunduh
  • Kit ini termasuk manajemen keadaan global, perutean, perpustakaan UI: Anda tidak akan merasa di gurun

Dokumentasi proyek utama: https://holiday-js.web.app/

Siklus hidup


Mari kita lihat tahapan siklus hidup komponen:

 import {HdElement} from '../../holiday/core/hd-element.js'; class LifecycleExample extends HdElement { constructor() { super(); //   : this.state = { name: '', bigName: '', }; /*   ,      DOM  "   ",       .    ,      "defineAccessor": */ this.defineAccessor('name', (name) => { // Some accessor code: this.setStateProperty('name', name); }); /*    ,      DOM               . */ } connectedCallback() { super.connectedCallback(); /*  .    DOM.               . */ } stateUpdated(path) { /*        : */ if (path === 'name') { this.setStateProperty('bigName', this.state.name.toUpperCase()); } } attributeChangedCallback(attributeName, oldValue, newValue) { /*  .      . */ super.attributeChangedCallback(attributeName, oldValue, newValue); } disconnectedCallback() { /*  .    DOM.              */ } } LifecycleExample.template = /*html*/ ` <div bind="textContent: name"></div> <div bind="textContent: bigName"></div> `; /*  HTML-,     : */ LifecycleExample.logicAttributes = [ //   ,         'name', ]; /*     CustomElements: */ LifecycleExample.is = 'lifecycle-example'; 

Pola


Karena templat di Holiday.js hanyalah literal templat standar, Anda memiliki kebebasan penuh dalam cara menempatkannya dalam proyek dan cara membentuk kontennya. Anda dapat menempatkannya dalam modul terpisah, Anda dapat mendefinisikannya bersama-sama dengan kode komponen, atau Anda dapat membuatnya dengan cepat dari data. Anda dapat menggunakan ekspresi dan hasil fungsi dalam template. Semua ini memberi peluang besar dan kebebasan berekspresi. Misalnya, Anda dapat mengimpor gaya umum ke templat, menggunakan variabel dan menghitung nilai dalam CSS tanpa menggunakan preprosesor dan dengan sangat mudah, merakit templat dari potongan yang sudah jadi.

Bagian penting dari templat komponen web adalah slot . Slot memungkinkan Anda untuk menunjuk tempat-tempat khusus di "bayangan" DOM ​​komponen Anda, di mana turunan langsungnya akan ditampilkan di pohon DOM umum. Contoh:

 <header> <slot name="header"></slot> </header> <div class="toolbar"> <slot name="toolbar"></slot> </div> <div class="content"> <slot></slot> </div> <footer> <slot name="footer"></slot> </footer> 

Penempatan dalam slot:

 <my-component> <div slot="header">Header content</div> <toolbar-component slot="toolbar"></toolbar-component> <div>Content of the default slot...</div> <div slot="footer">Footer content...</div> </my-component> 

Seperti yang sudah Anda tebak, ini memungkinkan Anda untuk membuat tata letak komponen, di mana modul yang diinginkan dapat dengan mudah diurutkan ke dalam sel.

Seperti disebutkan di atas, untuk mengikat data dan penangan secara dinamis, atribut "bind" digunakan:

 <div bind="textContent: content; onclick: on.clicked"></div> 

Untuk mengikat nilai atribut, gunakan simbol "@" di awal nama properti:

 <div bind="@style: style">Content...</div> 

Anda dapat menemukan detail lebih lanjut di bagian yang sesuai dari dokumentasi: https://holiday-js.web.app/?templates

Manajemen negara


Di dalam komponen:

 class MyComponent extends HdElement { constructor() { super(); //        : this.state = { content: 'Initial Content', style: 'color: #f00', on: { clicked: () => { console.log('Clicked!'); }, }, }; //       "setStateProperty": window.setTimeout(() => { //   : this.setStateProperty('content', 'Updated Content'); //   : this.setStateProperty({ 'content': 'Updated Content', 'style': 'color: #00f', }); }, 1000); } } 

Untuk mengontrol keadaan di level seluruh aplikasi, modul HdState digunakan.
Contoh penggunaan:

 import {HdState} from '../../holiday/core/hd-state.js'; //   : HdState.subscribe('ui.loading', (val) => { console.log(val); }); //   : HdState.publish('ui.loading', true); // : HdState.publish({ 'ui.loading': true, 'ui.sidePanelActive': true, }); 

Untuk bekerja dengan negara global, pertama-tama Anda perlu menentukan skema umumnya:

 HdState.applyScheme({ ui: { loading: { /*      ,       : */ type: Boolean, //    : value: false, }, sidePanelActive: { type: Boolean, value: false, }, }, user: { authorized: { type: Boolean, value: false, }, name: { type: String, value: null, //          : cache: true, }, }, }); 

Rangkaian juga dapat dengan mudah dibagi menjadi blok logis yang terpisah.

Untuk menghindari kebocoran memori, langganan yang tidak relevan harus dibuang:

 let subscription = HdState.subscribe('ui.loading', (val) => { console.log(val); }); window.setTimeout(() => { // Unsubscribe: subscription.remove(); }, 10000); 

Dokumentasi negara: https://holiday-js.web.app/?state

Alat pengembangan


Set terkecil untuk memulai adalah editor teks dan browser. Ya, itu sudah cukup untuk mencoba. Perlu dicatat bahwa dalam konfigurasi ini, browser harus persis Firefox. Itu dapat memuat modul ES tanpa menggunakan server lokal.

Untuk pekerjaan yang lebih lengkap, Anda perlu git dan server web apa pun yang Anda sukai (untuk bekerja dengan modul-ES di browser lain).

Untuk menyoroti sintaks HTML dan pelengkapan otomatis dalam literal templat, saya menggunakan ekstensi untuk Kode VS, yang awalnya dirancang untuk bekerja dengan html-lit: https://github.com/pushqrdx/vscode-inline-html

Untuk membuat kode sebelum diterbitkan, Anda dapat menggunakan kompiler populer apa saja, seperti webpack atau rollup .

Performa


Tolok ukur untuk kerangka kerja tidak mudah untuk ditulis. Untuk perbandingan yang representatif, Anda harus memastikan bahwa Anda membandingkan hal-hal yang sebanding dan, sejauh mungkin, meminimalkan efek efek samping. Jadi, mereka harus memiliki gagasan yang jelas tentang apa yang terjadi "di bawah tenda" dalam setiap kasus. Pertama, Anda perlu memutuskan parameter mana yang akan kami ukur. Untuk kasus kami, penting bagi kami:

  1. Saatnya memulai eksekusi program utama (unduh)
  2. Waktu rendering awal komponen
  3. Saatnya memperbarui komponen-komponen ini dan menggambarnya kembali

Sayangnya, kami tidak memiliki cara yang andal untuk mencari tahu saat ketika browser menjalankan program dan sepenuhnya selesai merender. Pada tingkat browser, ada banyak optimasi kami sendiri, yang bagi kami adalah sesuatu seperti "kotak hitam" dan mungkin berbeda di mesin yang berbeda. Apa yang bisa kita gunakan: API Kinerja , requestAnimationFrame , dan metode requestIdleCallback non-standar, yang hanya berfungsi di Chrome dan Firefox. Cukup untuk pertama kalinya.

Dengan apa kita akan membandingkan Holiday.js? Saya mulai dengan dua perpustakaan: Bereaksi (di mana tanpanya) dan LitElement (teknologi serupa pada intinya). Anda dapat menemukan kode tolok ukur dalam repositori berikut:

https://github.com/foxeyes/holiday-benchmark
https://github.com/foxeyes/lit-benchmark
https://github.com/foxeyes/react-benchmark

Sayangnya, saya belum menyelesaikan pengujian otomatisasi sejauh ini, dan ini juga tidak mudah, karena otomatisasi seharusnya tidak menciptakan efek samping dengan sendirinya. Saat ini, saya terus bekerja pada masalah ini dan saya sedang mempersiapkan alat yang tepat menggunakan Puppeteer (hal yang sangat berguna, saya sarankan). Sementara itu, Anda dapat mencoba tes dalam mode manual (Chrome / Firefox) dan memeriksa hasilnya di konsol browser. Anda akan melihat bahwa Holiday.js adalah pemimpin yang percaya diri dalam semua kasus .

Anda mungkin memperhatikan bahwa dalam kasus React, wadah div tambahan dibuat ketika komponen ditampilkan, yang berfungsi untuk meratakan jumlah elemen DOM yang dibuat. Saya memutuskan bahwa ini akan benar, karena komponen web selalu merupakan elemen DOM dan wadah, dan korespondensi struktur pohon DOM dalam pengujian yang berbeda sangat penting. Selain itu, dimungkinkan untuk menyingkirkan sarang yang tidak perlu di Holiday.js dan menampilkan data dengan cara yang sama seperti di React. Namun, jika masalah ini tampaknya dapat diperdebatkan bagi Anda, perhatikan terlebih dahulu kecepatan pembaruan.

Dukungan browser


Tidak, Internet Explorer tidak didukung. Ini bisa dicapai dengan upaya tertentu (untuk versi ke-11), tetapi penolakan terhadap dukungan adalah posisi yang berprinsip. Pertama, saya percaya bahwa IE harus mati untuk waktu yang lama, dan dalam kekuatan kita untuk berkontribusi dalam hal ini. Kedua, orang yang menganjurkan dukungan untuk IE sering membuat kesalahan logis yang serius: pangsa IE dalam lalu lintas total, menurut data caniuse saat ini, adalah ~ 1,6% untuk semua versi yang ditemukan. Dan browser yang paling populer, yang berada di depan sisanya dengan margin lebar, adalah mobile Chrome (~ 35%). Jadi, mendukung IE, Anda secara sadar menolak untuk menggunakan sejumlah besar teknologi yang hanya diperlukan untuk mengimplementasikan kemampuan beradaptasi penuh dan mobilitas dalam aplikasi Anda, yaitu, demi minoritas kecil, mempersulit kehidupan sebagian besar penggunanya. Atau secara signifikan meningkatkan biaya pengembangan dan pemeliharaan produk Anda. Ketiga, Microsoft, dalam beberapa waktu terakhir, telah secara aktif memaksa pengguna untuk meninggalkan Windows 7, sehingga proporsi lalu lintas IE dalam waktu dekat akan berkurang lebih cepat. Saya akui bahwa ada kasus-kasus ketika dukungan IE tidak dapat dilewati, tetapi kasus-kasus seperti itu jauh lebih jarang daripada yang kita pikirkan sebelumnya.

15 Januari tahun ini, Microsoft merilis versi rilis Edge baru, di mesin Chromium. Mulai saat ini, kita dapat mengasumsikan bahwa Holiday.js didukung secara native di semua versi browser populer saat ini. Untuk Edge yang lebih lama, polyfill diperlukan. Kemampuan untuk bekerja dengan polyfill diimplementasikan di Holiday.js, tetapi skrip itu sendiri perlu dihubungkan secara terpisah.

Minimalisme


Konsep Holiday.js didasarkan pada kesederhanaan dan minimalis. Salah satu tahap penting dalam pekerjaan pada proyek ini bagi saya adalah penghapusan fungsi , yang saya buru-buru terapkan, tetapi kemudian menyadari bahwa saya dapat melakukannya tanpa itu. Karena itu, jika Anda merasa ada sesuatu yang hilang, tanyakan pada diri sendiri, apakah ini benar-benar begitu? Saya menjawabnya untuk diri saya sendiri seperti ini: jika ada hal lain yang sangat dibutuhkan, lebih baik membuat kelas tambahan secara terpisah, dengan warisan dari yang utama. Sejauh ini pendekatan ini tidak mengecewakan saya. Holiday.js, dalam kondisi saat ini, telah diuji dalam pertempuran dan telah menunjukkan dirinya sangat positif di tempat kerja.

Paket


Jika Anda membaca ke tempat ini, maka usaha saya sudah dihabiskan tidak sia-sia. Bahkan jika Anda tidak ingin menggunakan Holiday.js, Anda setidaknya bisa mendapatkan sesuatu yang menarik untuk diri sendiri ketika bekerja dengan komponen web. Saya akan sangat senang jika materi ini menandai awal pembangunan komunitas. Saya akan sangat senang memiliki diskusi yang konstruktif, kritik, laporan bug, pullrequests dan, tentu saja, bintang di GitHub. Tentu saja, saya tidak bisa menyentuh semua aspek, dan saya akan dengan senang hati menjawab pertanyaan Anda. Harap perhatikan bahwa sampai sekarang, saya mengerjakan perpustakaan ini sendirian , dan melakukan semuanya sendiri, termasuk dokumentasi, tes, dan alat terkait, bersamaan dengan pekerjaan utama dan proyek kesayangan, sulit.

Namun, dalam waktu dekat:

  • Lebih banyak perbandingan dengan perpustakaan dan kerangka kerja populer lainnya.
  • Alat pengujian PingPong yang minimalis dan fleksibel berdasarkan Puppeteer
  • Generator proyek dasar dengan contoh (Starter Kit)
  • Pengembangan dokumentasi lebih lanjut

Saya menyilangkan jari saya, tekan "Terbitkan" ...

Source: https://habr.com/ru/post/id485688/


All Articles