Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Case study: Optimalizace výkonu dApp

Case study: Optimalizace výkonu dApp

Aleš Roubíček

June 06, 2019
Tweet

More Decks by Aleš Roubíček

Other Decks in Programming

Transcript

  1. 1. analýza • Hlavní úzké hrdlo - Drizzle • Kód

    v žalostném stavu • nedodržování pravidel zanesených do linteru • nedodržování návrhových vzorů • tuna mrtvého a zakomentovaného kódu • absence smysluplných testů • Spousta chyb a upozornění v konzoli
  2. –Aleš Roubíček “The state for rendering of the game should

    be separated from the actual state of the contracts, this will allow more asynchronous state propagation to rendering pipeline and improved timing when actual data will be shown.”
  3. Architektonické nedostatky • Render blocking operace v hlavním vlákně •

    Nedodržování vzorů vyžadovaných knihovnami • Stav managující komponenty ve view stromu • Inicializace stavových komponent s každým view • Blockchain state & view state coupling • Generátor zbytečného boilerplate
  4. Aplikační stav • React, Redux, Web3.js, Drizzle, Pixi.js • function

    view(data) {} • Single Atom Application State
  5. Redux & Sagas • Úplná extrace komunikace s web3 z

    lifecycle metod komponent do redux-saga • Maximální snaha o PureComponents • Kompletní eliminace Drizzle stavu a komponent z React stromu čistě do Redux Store • Reakce na změny v blockchainu pouze přes akce/sagas • Masivní očista kódu dle ESlint pravidel a pomocí Prettier
  6. 2. analýza • Příliš velké moduly kódu • Přibalování přirozeně

    statických assetů • Přibalování zbytečných závislostí • Render blocking resources v HTML (fonty, scripty) • Absence pre-renderu a preloading
  7. /* Local */ // import SomeToken from '../../../ontracts/build/contracts/SomeToken.json'; // import

    OtherToken from '../../../contracts/build/contracts/OtherToken.json'; // import FooToken from '../../../contracts/build/contracts/FooToken.json'; // import BarToken from '../../../contracts/build/contracts/BarToken.json'; /* Ropsten */ import SomeToken from './contracts/SomeToken.json'; import OtherToken from './contracts/OtherToken.json'; import FooToken from './contracts/FooToken.json'; import BarToken from './contracts/BarToken.json'; const contracts = { SomeToken, OtherToken, FooToken, BarToken, }; export function getContract() { return contracts; }
  8. function contractUrl(contract) { const network = process.env['NETWORK']; const version =

    process.env['CONTRACTS_VERSION']; const isDev = process.env['NODE_ENV'] !== 'production'; const prefix = isDev ? `/${network}/contracts/` : `https://prod.test.com/${network}/contracts/${version}/`; return [prefix, contract, '.json'].join(''); } const fetchContract = c \> fetch(contractUrl(c)).then(r \> r.json()); const contracts = ['SomeToken', 'OtherToken', 'FooToken', 'BarToken']; export function getContract() { return Promise.all(contracts.map(fetchContract)).then( ([SomeToken, OtherToken, FooToken, BarToken]) \> ({ SomeToken, OtherToken, FooToken, BarToken, }), ); }
  9. Přednačítání assetů <link rel="preconnect" href="https://ajax.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect"

    href="https://fonts.gstatic.com"> <link rel="preload" as="script" crossorigin href="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"> <link rel="preload" as="font" crossorigin href="https://fonts.gstatic.com/s/vt323/v10/pxiKyp0ihIEF2isfFJXUdVNF.woff2">
  10. Asychronní fonty <script> WebFontConfig = { google: { families: [

    'Space Mono:400,700', 'Work Sans:400,600', 'VT323', ], }, }; </script> <script async crossorigin src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"> </script>
  11. CDN cache boosting 'use strict'; exports.handler = (event, context, callback)

    ;> { const response = event.Records[0].cf.response; const headers = response.headers; headers['Cache-Control'.toLowerCase()] = [{ key: 'Cache-Control', value: "public, max-age=31536000, immutable" }]; callback(null, response); };