<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Julian Meyer</title>
    <description>The latest articles on Forem by Julian Meyer (@meyer9).</description>
    <link>https://forem.com/meyer9</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F120224%2F362ca222-2c09-4b70-a4d5-64187e2c6851.jpg</url>
      <title>Forem: Julian Meyer</title>
      <link>https://forem.com/meyer9</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/meyer9"/>
    <language>en</language>
    <item>
      <title>Front-end Developers: What tools do you use to test performance?</title>
      <dc:creator>Julian Meyer</dc:creator>
      <pubDate>Wed, 03 Jun 2020 06:07:19 +0000</pubDate>
      <link>https://forem.com/meyer9/front-end-developers-what-tools-do-you-use-to-test-performance-5717</link>
      <guid>https://forem.com/meyer9/front-end-developers-what-tools-do-you-use-to-test-performance-5717</guid>
      <description>&lt;p&gt;Hi all!&lt;/p&gt;

&lt;p&gt;I'm curious what other front-end developers use to test page performance.&lt;/p&gt;

&lt;p&gt;Do you just use Chrome Developer Tools or do you have a more complicated system integrated into CI/CD processes?&lt;/p&gt;

&lt;p&gt;Also curious about testing... I usually just write unit tests, but not end-to-end testing of the UI. Do you have any quality assurance or testing tools you use for testing UI? (puppeteer?)&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>HTTP/2 Server Push Explained</title>
      <dc:creator>Julian Meyer</dc:creator>
      <pubDate>Wed, 12 Feb 2020 21:07:51 +0000</pubDate>
      <link>https://forem.com/meyer9/http-2-server-push-explained-4gh</link>
      <guid>https://forem.com/meyer9/http-2-server-push-explained-4gh</guid>
      <description>&lt;p&gt;HTTP/2 Server Push is a new feature released along with HTTP/2 that allows compatible servers to push resources to the client before the client requests the resources. Instead of having to wait for the client to download the document, parse it, and send more requests to the server, the server just sends the documents it knows the client will need.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;HTTP/2 allows a server to pre-emptively send (or "push") responses (along with corresponding "promised" requests) to a client in association with a previous client-initiated request. &lt;em&gt;&lt;a href="https://tools.ietf.org/html/rfc7540#section-8.2"&gt;RFC 7540&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This allows sites to load much faster since it saves one round-trip between the client and the server. This optimization is basically free in terms of development work because everything is implemented at the protocol level.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Server Push?
&lt;/h1&gt;

&lt;p&gt;Traditionally, HTTP clients like browsers connect to a server, request a page, receive the page, parse the page, then request any additional resources that the page requires. Any resources required to load the page require a separate request after loading the page even though they're sent any time the page is requested.&lt;/p&gt;

&lt;p&gt;Server Push improves this process by "pushing" resources to the browser before the browser even asks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DkbN6HDH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/k24or5sxlexkuwxvowwc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DkbN6HDH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/k24or5sxlexkuwxvowwc.png" alt="Server push explanation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, instead of requesting the document, receiving the document, then requesting the resources, the client just has to request the document and receives the document and resources in the response.&lt;/p&gt;

&lt;p&gt;In the example above, HTTP/2 Server Push increases page load time by 60 ms. This may not seem like much but Server Push improves load time by 25% by just enabling a simple configuration option.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does it work?
&lt;/h2&gt;

&lt;p&gt;This section will explain the technical details behind server push. If you don't care about that, just skip to the next section.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP/2 streams
&lt;/h3&gt;

&lt;p&gt;Unlike HTTP/1, HTTP/2 is a binary protocol. Where HTTP/1 sends the normal &lt;code&gt;GET /&lt;/code&gt; request in plain text, HTTP/2 uses binary encoding to save bytes. For example, HTTP/2 sends a &lt;code&gt;HEADERS&lt;/code&gt; frame encoded in binary similar to the &lt;code&gt;PUSH_PROMISE&lt;/code&gt; frame above and then it sends a &lt;code&gt;DATA&lt;/code&gt; frame to send site data to the client.&lt;/p&gt;

&lt;p&gt;HTTP/2 also comes with a new feature called &lt;em&gt;streams&lt;/em&gt;. Streams allow multiple streams of frames to be sent over a single connection. This allows multiple requests/responses to be sent and received over a single connection. Whereas HTTP/1 supports only a single request/response at a time, HTTP/2 allows many requests/responses as long as there is enough bandwidth to send them.&lt;/p&gt;

&lt;p&gt;This is a key feature for server push because server push involves sending multiple different resources at the same time.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP/2 Server Push
&lt;/h3&gt;

&lt;p&gt;First of all, the server and client must agree to support the feature. The client may disable server push by setting the &lt;code&gt;SETTINGS_ENABLE_PUSH&lt;/code&gt; setting to 0 included in the HTTP/2 settings frame. If the client does this, the server should not push any resources to the client through Server Push.&lt;/p&gt;

&lt;p&gt;After the client sends an HTTP/2 request to the server with &lt;code&gt;SETTINGS_ENABLE_PUSH&lt;/code&gt; set to 1, the server will first send back a &lt;code&gt;PUSH_PROMISE&lt;/code&gt; frame indicating to the client that it will be pushing some resources to the client. This includes a 31-bit stream ID and headers for the requested resource to provide context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+---------------+
|Pad Length? (8)|
+-+-------------+-----------------------------------------------+
|R|                  Promised Stream ID (31)                    |
+-+-----------------------------+-------------------------------+
|                   Header Block Fragment (*)                 ...
+---------------------------------------------------------------+
|                           Padding (*)                       ...
+---------------------------------------------------------------+
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The server sends these even before the page response so that the client doesn't request any of the resources the server plans to push.&lt;/p&gt;

&lt;p&gt;After sending the initial &lt;code&gt;PUSH_PROMISE&lt;/code&gt; frame, the server then begins sending push responses on the streams identified by the stream ID sent previously in the &lt;code&gt;PUSH_PROMISE&lt;/code&gt; frames. The client doesn't send any requests for resources that it knows the server is pushing.&lt;/p&gt;

&lt;p&gt;Clearly, HTTP/2 server push requires support by the server and the client, but the client can always fall back to HTTP/1. Next, I'll discuss HTTP/2 Server Push support.&lt;/p&gt;

&lt;h2&gt;
  
  
  What browsers support Server Push?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mwkKJoSS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/korqgi2k7up3th1kqbj4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mwkKJoSS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/korqgi2k7up3th1kqbj4.png" alt="Server push supported browsers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;HTTP/2 Server Push is supported on all major browsers (except for IE on Windows 7).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Firefox has supported HTTP/2 server push since February 2015.&lt;/li&gt;
&lt;li&gt;Chrome has supported HTTP/2 server push since March 2015.&lt;/li&gt;
&lt;li&gt;Safari as supported HTTP/2 server push since June 2015.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Clearly, HTTP/2 Server Push is very widely supported. It works on 95.5% of all users' devices.&lt;/p&gt;

&lt;h1&gt;
  
  
  How much does it improve load times?
&lt;/h1&gt;

&lt;p&gt;I ran a test on 500 of the top websites according to &lt;a href="https://moz.com/top500"&gt;moz.com&lt;/a&gt; and I calculated the time spent loading the longest-loading resource from the server. This isn't a perfect test since there are other factors that can marginally lower the benefit, but this should be a good estimate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dZ8GKVVX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/f34c40gxnt7hmama2agt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dZ8GKVVX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/f34c40gxnt7hmama2agt.png" alt="Server push speedup"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In some cases, over 1 second could be saved simply by enabling a configuration option in the web server. Generally, over 200 ms can be saved by enabling HTTP/2 server push.&lt;/p&gt;

&lt;p&gt;Especially in cases where request chains are long, server push can be a huge help. For example, if you have HTML that loads CSS that loads a font, server push can decrease the latency of loading the CSS and font to 0.&lt;/p&gt;

&lt;p&gt;You can use a tool like &lt;a href="https://pagecheck.app"&gt;pagecheck&lt;/a&gt; to check request chains within your site.&lt;/p&gt;

&lt;h1&gt;
  
  
  How do I implement it?
&lt;/h1&gt;

&lt;p&gt;HTTP/2 Server Push is implemented by most major web servers. Generally, you can add a reverse proxy in front of your site in order to still use your existing web framework, but also include some important features like Server Push or caching.&lt;/p&gt;

&lt;h2&gt;
  
  
  Apache
&lt;/h2&gt;

&lt;p&gt;Apache supports HTTP/2 server push through a module called &lt;code&gt;mod_http2&lt;/code&gt;. In order to enable this module, add this to your &lt;code&gt;httpd.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;LoadModule&lt;/span&gt; &lt;span class="n"&gt;http2_module&lt;/span&gt; &lt;span class="n"&gt;modules&lt;/span&gt;/&lt;span class="n"&gt;mod_http2&lt;/span&gt;.&lt;span class="n"&gt;so&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then, you can enable HTTP/2 as a supported protocol from Apache by adding this line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;Protocols&lt;/span&gt; &lt;span class="n"&gt;h2&lt;/span&gt; &lt;span class="n"&gt;h2c&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;/&lt;span class="m"&gt;1&lt;/span&gt;.&lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Make sure that &lt;code&gt;SSLCipherSuite&lt;/code&gt; is configured with an HTTP/2 compatible cipher. You can also just leave it as a default value and it will be configured properly as long as you have an up-to-date version of OpenSSL. Don't use any ciphers from &lt;a href="https://httpwg.org/specs/rfc7540.html#BadCipherSuites"&gt;this list&lt;/a&gt; as they are not supported by HTTP/2.&lt;/p&gt;

&lt;p&gt;With Apache, you can push responses in one of two ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add &lt;code&gt;Link&lt;/code&gt; headers to your application so the application notifies Apache of which resources need to be pushed. &lt;code&gt;Link&lt;/code&gt; headers look like this:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Link &amp;lt;/xxx.css&amp;gt;;rel=preload, &amp;lt;/xxx.js&amp;gt;; rel=preload
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add &lt;code&gt;Link&lt;/code&gt; headers manually in your Apache server config:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Location /xxx.html&amp;gt;
  Header add Link "&amp;lt;/xxx.css&amp;gt;;rel=preload"
  Header add Link "&amp;lt;/xxx.js&amp;gt;;rel=preload"
&amp;lt;/Location&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;All of the information from this section comes from the &lt;a href="https://httpd.apache.org/docs/2.4/howto/http2.html#push"&gt;apache docs&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  NGINX
&lt;/h2&gt;

&lt;p&gt;NGINX supports HTTP/2 server push similarly to Apache.&lt;/p&gt;

&lt;p&gt;First, enable HTTP/2 support on your server by adding &lt;code&gt;http2&lt;/code&gt; to the &lt;code&gt;listen&lt;/code&gt; directive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;listen 443 ssl http2;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then, again you can either add &lt;code&gt;http2_push&lt;/code&gt; directives to your application similar to above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;location&lt;/span&gt; = /&lt;span class="n"&gt;demo&lt;/span&gt;.&lt;span class="n"&gt;html&lt;/span&gt; {
  &lt;span class="n"&gt;http2_push&lt;/span&gt; /&lt;span class="n"&gt;style&lt;/span&gt;.&lt;span class="n"&gt;css&lt;/span&gt;;
  &lt;span class="n"&gt;http2_push&lt;/span&gt; /&lt;span class="n"&gt;image1&lt;/span&gt;.&lt;span class="n"&gt;jpg&lt;/span&gt;;
  &lt;span class="n"&gt;http2_push&lt;/span&gt; /&lt;span class="n"&gt;image2&lt;/span&gt;.&lt;span class="n"&gt;jpg&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Or, you can add a &lt;code&gt;http_push_preload on&lt;/code&gt; directive to your server configuration which will respect headers sent from the application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;location&lt;/span&gt; = /&lt;span class="n"&gt;app&lt;/span&gt; {
  &lt;span class="n"&gt;proxy_pass&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;://&lt;span class="n"&gt;upstream&lt;/span&gt;;
  &lt;span class="n"&gt;http2_push_preload&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;All of this information and more can be found on &lt;a href="https://www.nginx.com/blog/nginx-1-13-9-http2-server-push/"&gt;NGINX's blog post for server push&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;HTTP/2 Server Push allows developers to decrease load times for free. Literally just enable a configuration option and set your application up to send &lt;code&gt;Link&lt;/code&gt; headers and your application will load 25-50% faster.&lt;/p&gt;

&lt;p&gt;HTTP/2 Server Push is supported by 95% of users' browsers, so it should be a no-brainer for any site.&lt;/p&gt;

&lt;p&gt;Shameless plug: &lt;a href="https://pagecheck.app"&gt;pagecheck&lt;/a&gt; allows you to track your load times across websites including front-end statistics which HTTP/2 would affect. If you're interested or you have a use case we haven't thought of yet, you can also send me an email &lt;a href="//mailto:julian@pagecheck.app"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>performance</category>
      <category>http2</category>
      <category>serverpush</category>
      <category>webdev</category>
    </item>
    <item>
      <title>5 optimizations to make your page run faster</title>
      <dc:creator>Julian Meyer</dc:creator>
      <pubDate>Wed, 29 Jan 2020 15:55:56 +0000</pubDate>
      <link>https://forem.com/meyer9/5-optimizations-to-make-your-page-run-faster-4o3m</link>
      <guid>https://forem.com/meyer9/5-optimizations-to-make-your-page-run-faster-4o3m</guid>
      <description>&lt;p&gt;We all know the modern web has become extremely bloated. Everything takes too long to load and downloads a huge amount of data over the network which can be a big problem for user-experience.&lt;/p&gt;

&lt;p&gt;In fact, the median page size in 2020 is 2 MB and steadily increasing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--baFhYgtA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/5jdadakyqe5tq9errk6f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--baFhYgtA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/5jdadakyqe5tq9errk6f.png" alt="Pages are getting bigger"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even worse, Time To Interactive, or the time it takes for a user to be able to interact with websites is at &lt;strong&gt;10 seconds&lt;/strong&gt; and growing higher over time. Imagine how much easier sites would be to use if that metric decreased by half.&lt;/p&gt;

&lt;p&gt;This article will teach you how to use front-end performance metrics to evaluate how to optimize your page loading time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimization 1: Load your content first
&lt;/h2&gt;

&lt;p&gt;Many "progressive web-apps" or PWAs first load the HTML, which loads the Javascript, which loads the content (from an API). Obviously, if your site is designed like this, the time it will take for users to be able to use your site will be much higher than necessary.&lt;/p&gt;

&lt;p&gt;A better system is to &lt;strong&gt;send the content of the page along with the HTML&lt;/strong&gt;. This might sounds obvious, but it makes the site much more usable. Users aren't really going to care if Javascript is loaded when the load a page, but they will care if the content isn't loaded within a few seconds.&lt;/p&gt;

&lt;p&gt;This can be done in a variety of ways, but the two simplest ways are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;a href="https://reactjs.org/docs/react-dom-server.html"&gt;server-side rendering&lt;/a&gt; to render your page initially.&lt;/li&gt;
&lt;li&gt;Add something like this to your template for each page:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then, when your page loads, users just have to wait for the Javascript to load which will already have the content for the page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimization 2: Optimize images
&lt;/h2&gt;

&lt;p&gt;Most sites that load slow usually have huge images that take a long time to fully load. There are a few optimizations you can make with respect to images, but the main ones are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use an efficient container like &lt;a href="https://web.dev/uses-webp-images/"&gt;webp&lt;/a&gt; to store your images&lt;/li&gt;
&lt;li&gt;Size images efficiently (don't load a giant image if you only need a small one)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/react-image"&gt;Load images lazily&lt;/a&gt; (instead of loading them on page load, load them after page load)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also use a service like (disclaimer: my service) &lt;a href="https://pagecheck.app"&gt;PageCheck&lt;/a&gt; or &lt;a href="https://developers.google.com/speed/pagespeed/insights/"&gt;Lighthouse&lt;/a&gt; to check for images that need optimizing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimization 3: Don't run any Javascript before &lt;code&gt;window.onload&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The browser runs all scripts before allowing page interaction, so if you have scripts that are run directly in a script tag, instead you probably should run them after the page loads.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// simulates a resource intensive script&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;can be done much more efficiently as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// simulates a resource intensive script&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This ensures the page loads before you do some resource-intensive task.&lt;/p&gt;

&lt;p&gt;You can also load scripts asynchronously which does basically the same thing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;'/js/jquery.min.js'&lt;/span&gt; &lt;span class="na"&gt;async&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!--- or --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;'/js/main.js'&lt;/span&gt; &lt;span class="na"&gt;defer&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In short, wait until the page loads to do (almost) any scripting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimization 4: Inline critical resources
&lt;/h2&gt;

&lt;p&gt;It definitely does not make sense to inline all styles and scripts, but critical scripts and styles that are needed before the page is displayed should be inside &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags in the HTML document.&lt;/p&gt;

&lt;p&gt;Of course, keep these as small as possible, only loading the critical parts as needed, but if your page is unusable or looks bad before certain CSS or Javascript is loaded, definitely send those resources along with the HTML document.&lt;/p&gt;

&lt;p&gt;Chrome Dev Tools has a feature called Coverage that helps you identify which parts of your code are critical and which are not.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o-XFqYq2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://web.dev/images/includes/coverage.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o-XFqYq2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://web.dev/images/includes/coverage.png" alt="Chrome devtools coverage tab"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimization 5: Support HTTP/2
&lt;/h2&gt;

&lt;p&gt;HTTP/2 is a huge help in front-end performance. Instead of waiting for the browser to request resources after loading the HTML document, HTTP Server Push allows the server to send the browser resources while the HTML page is still being loaded.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tQC8v0eN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.nginx.com/wp-content/uploads/2018/02/http2-server-push-test-configurations.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tQC8v0eN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.nginx.com/wp-content/uploads/2018/02/http2-server-push-test-configurations.png" alt="Server push"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;HTTP/2 is supported by most modern browsers and is extremely easy to setup if you have an Nginx or Apache reverse-proxy in front of your application.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nginx&lt;/strong&gt; provides a guide to setting up server push &lt;a href="https://www.nginx.com/blog/nginx-1-13-9-http2-server-push/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apache&lt;/strong&gt; provides a guide for setting it up &lt;a href="https://httpd.apache.org/docs/2.4/howto/http2.html"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Despite the web getting more and more bloated, new technologies make speed-ups possible without eliminating code or changing much at all.&lt;/p&gt;

&lt;p&gt;By focusing on getting the most important information to the web browser first, user experience can be improved for free.&lt;/p&gt;

&lt;p&gt;Shameless plug: To track front-end performance, get recommendations on speed-ups, and audit your site for common security problems, you can check out my tool, &lt;a href="https://pagecheck.app"&gt;PageCheck&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have feedback or a specific use-case I might be interested in, tweet at me or drop me an email and I'll give you a free trial in exchange for feedback.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>html</category>
      <category>css</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Waves Technical Review</title>
      <dc:creator>Julian Meyer</dc:creator>
      <pubDate>Fri, 05 Apr 2019 16:58:51 +0000</pubDate>
      <link>https://forem.com/meyer9/waves-technical-review-3596</link>
      <guid>https://forem.com/meyer9/waves-technical-review-3596</guid>
      <description>&lt;p&gt;This is just a quick introduction to my blog. I'll be posting here technical articles once per week (every friday) about certain cryptocurrencies usually in the top 100.&lt;/p&gt;

&lt;p&gt;You can subscribe to my newsletter &lt;a href="https://buttondown.email/meyer9" rel="noopener noreferrer"&gt;here&lt;/a&gt; where I'll be sending out exclusive content along with &lt;a href="https://juliancrypto.com/2019/04/04/Top-100-Reviews-Waves.html" rel="noopener noreferrer"&gt;new blog posts on my website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I decided to start with Waves because I haven't used the platform before, I only barely know what it's used for, and I don't know the tech behind it at all. I'll review the tech, security and trust implications, the coding standards, etc. This post is meant as a comprehensive technical review of the Waves platform.&lt;/p&gt;

&lt;p&gt;At first glance, Waves' website is flashy and seems like something out of a design-focused product. The site seems stylistically glitchy and definitely not the best for conveying information. The two big products I see as I scroll down the homepage are: Vostok, a universal blockchain solution... designed for large enterprises, and Waves, the open-source public blockchain.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F96knpads46m8cbpa3g9l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F96knpads46m8cbpa3g9l.png" alt="Waves Homepage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Their site focuses mainly on Web 3.0, which is a crypto buzzword meaning their blockchain runs dApps. Waves is proof-of-stake meaning that miners bet their coins on the next block instead of betting mining power. The types of proof-of-stake vary wildly between different platforms, so I'll definitely be looking into this first.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Flkz1vo16su2zg97qd72k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Flkz1vo16su2zg97qd72k.png" alt="Waves Features"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Waves Proof-of-Stake (LPoS)
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Terminology and Conceptual Problems
&lt;/h2&gt;

&lt;p&gt;Waves uses a system called "Leased Proof-of-Stake". One important claim they make that really stands out to me as I read this is the statement below:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Usually, in the PoS system, there is no block reward, so, the miners take the transaction fees. That's why miners are often called block forgers or generators, instead, Figure 1.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is a misconception of Proof-of-Stake. There is no reason that stakers can't receive a block reward. In almost every proof-of-stake system, block proposers are rewarded with coins. Waves had an ICO of $16 million, so the developers and leaders are incentivized to keep inflation low to keep their share high. This could be a security problem if transaction fees are too small.&lt;/p&gt;

&lt;p&gt;Later, on the same page, they make this statement:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The proof of stake avoids this ‘tragedy’ by making it disadvantageous for a miner with a 51% stake in a cryptocurrency to attack the network.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While this is true generally, the same applies to proof-of-work. Bitcoin miners don't want to attack the network because it will devalue the currency they mine and their equipment. With no "external" disincentive for miners to attack the network, a bribing attack is as simple as bribing miners more to attack the network than they would lose from the network being attacked.&lt;/p&gt;

&lt;p&gt;Again, they state the same thing in different terms:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;a miner with 51% stake in the coin would not have it in his best interest to attack a network which he holds a majority share&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, they are not considering the possibility that the attacker doesn't need to own coins and could attack the network simply by bribing stakers and offering them extra income.&lt;/p&gt;

&lt;h2&gt;
  
  
  LPoS is worse than PoS
&lt;/h2&gt;

&lt;p&gt;Because of this fundamental misunderstanding of attacking models, Waves goes on to explain the real problem with their staking system:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;the user will have the ability to Lease Waves form the wallet to different contractors which can pay a percentage as a reward&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;This is a BIG red flag.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let me illustrate why this is a bad idea with an example.&lt;/p&gt;

&lt;p&gt;Let's say Alice and Bob are stakers in the Waves network. They each hold &lt;code&gt;25%&lt;/code&gt; of Waves. Alice runs a full-node because he really supports the mission, but Bob is just trying to make a quick buck. Eve wants to attack the network. Alice stakes her coins and Bob also pays Alice &lt;code&gt;5%&lt;/code&gt; to stake his coins using LPoS.&lt;/p&gt;

&lt;p&gt;Bob and Alice know that if Eve attacks the network, their coins will devalue by &lt;code&gt;30%&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The cost for Eve to attack the network is: &lt;code&gt;C = B/0.7 = 1.42B&lt;/code&gt; where B is the value Bob's coins. This means that Eve needs to pay Bob only about &lt;code&gt;40%&lt;/code&gt; more than Bob's stake in the network (&lt;code&gt;25% * 140% = 35%&lt;/code&gt;) to gain control of &lt;code&gt;50%&lt;/code&gt; of the network power.&lt;/p&gt;

&lt;p&gt;Bob is happy because he's getting paid more than he would have by just staking his coins. Alice is happy because Bob is staking her coins and she doesn't have to run a full node. And Eve is happy because she can attack the network for less of a cost than 50%.&lt;/p&gt;

&lt;p&gt;Delegating stake in proof-of-stake systems always lowers security.&lt;/p&gt;

&lt;h2&gt;
  
  
  Encouraging users to decrease network security is really bad
&lt;/h2&gt;

&lt;p&gt;Their system even strongly encourages users to do this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The balance of the node can be empty until there are enough people wishing to lease to it by reaching together the generating balance of 1000 Waves and create together a pool.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Small stake holders can't stake blocks. Only large pools can. This not only leads to a severe security decrease, but also strong centralization as bigger pools are more trusted and grow faster than smaller pools.&lt;/p&gt;

&lt;p&gt;This is seen very clearly in their &lt;a href="https://dev.pywaves.org/generators-monthly/" rel="noopener noreferrer"&gt;block explorer&lt;/a&gt; where the top 6 miners control 57% (as of writing) of the staking power.&lt;/p&gt;

&lt;h1&gt;
  
  
  Waves Source Code
&lt;/h1&gt;

&lt;p&gt;Waves source code is clean and uses good practices. The code is well-commented and easy-to-read. They use strong crypto libraries and functions. When in doubt, they stick to proven Bitcoin features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scala is a good choice
&lt;/h2&gt;

&lt;p&gt;Waves is written in a programming language called Scala which is a functional language built on top of the JVM (Java Virtual Machine). This lets them deploy versions of Waves on many platforms with very similar code. The JVM is highly optimized, but not great for low-level operations like cryptography.&lt;/p&gt;

&lt;p&gt;Internally, Waves uses the &lt;a href="https://github.com/input-output-hk/scrypto" rel="noopener noreferrer"&gt;Scrypto&lt;/a&gt; library for Ed25519 curve. Waves uses the Blake2b256 hash function for fast hashing and &lt;code&gt;Keccak(Blake2b256(m))&lt;/code&gt; for secure hashing. Ed25519 is a strong choice due to its speed, security, and provable lack of backdoors. The parameters are carefully chosen to make inserting a backdoor tricky.&lt;/p&gt;

&lt;p&gt;The code uses similar structures to Bitcoin.&lt;/p&gt;

&lt;p&gt;Waves uses LevelDB as their block database which is the same as is used in Bitcoin.&lt;/p&gt;

&lt;p&gt;The code overall seems very well-organized. They include over 800 tests, all passing on my computer which check RPC commands, DEX system, transfer tests, stake leasing, transactions, script, blockchain, activation code for new features, and state transition tests. All of these improve security of the network and the protocol.&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentation
&lt;/h2&gt;

&lt;p&gt;Waves also includes a signficant amount of developer documentation providing information about the consensus sytem, RPC, smart contract development, oracles, etc. This is a really great sign because it means that developers will be encouraged to use Waves to develop dApps.&lt;/p&gt;

&lt;p&gt;Each change to the Waves architecture is also documented within their developer docs. It gives specific information about how the change will work including a detailed specification.&lt;/p&gt;

&lt;p&gt;Waves includes, in their proposals, information about an interesting feature called Sponsored Transactions which let users transact with the network without using Waves tokens and instead using an asset hosted on the Waves blockchain. This is a huge feature for ICOs who don't want to add extra friction in allowing users to transfer tokens and use their dApps.&lt;/p&gt;

&lt;h2&gt;
  
  
  DEX
&lt;/h2&gt;

&lt;p&gt;They launched a decentralized exchange for trading Waves/_TC pairs. This improves their ecosystem in two ways.&lt;/p&gt;

&lt;p&gt;First, it gives miners an extra source of revenue from the trading fees. This is important because the security of the network is highly dependent on miner revenue and without a block reward, miners need transaction fees to secure the network.&lt;/p&gt;

&lt;p&gt;Second, it increases adoption of Waves to transfer assets and use their asset management platform similar to ERC. More users of tokens built on Waves means a higher network value.&lt;/p&gt;

&lt;p&gt;The interface looks nice and everything happens on-chain, so this is definitely a huge plus for Waves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Web 3
&lt;/h2&gt;

&lt;p&gt;Waves fiercely advertises their Web 3 features focusing mostly on dApps.&lt;/p&gt;

&lt;p&gt;Waves definitely excels in this area, providing a browser extension for accessing dApps and managing private keys through your browser. This is important as it gives users a smoother onboarding process.&lt;/p&gt;

&lt;p&gt;They wrote their own smart contract language called "RIDE". RIDE is strongly-typed, "lazy", and expression-based. RIDE includes some functional features like pattern-matching. The final contracts, however strongly resembly Bitcoin script with a few extra features. Loops, function calls, and jumps are not supported so the language is &lt;strong&gt;not Turing-complete&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The language seems to be the only piece of the puzzle missing for real dApps to exist on Waves. Many complicated dApps will not be able to be built on Waves due to the restrictions by the smart contract language. The language seems focused on simplicity and correctness, but is insufficient for most "Web 3" applications as they advertise.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Overall, Waves is a strong cryptocurrency with developers and a team who know what they're talking about. The small security problems don't overshadow their larger goals. The smart contract language, while basic, will be more secure and less error-prone than something like solidity. The DEX is a great way to increase adoption and miner fees. It's implemented well and not centralized (everything is on-chain).&lt;/p&gt;

&lt;p&gt;Waves is an interesting cryptocurrency, coded from scratch, and built on solid foundations. They make generally reasonable technical choices and focus on useful tech.&lt;/p&gt;

</description>
      <category>waves</category>
      <category>cryptocurrency</category>
      <category>security</category>
      <category>cryptography</category>
    </item>
  </channel>
</rss>
