<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>J. Pedro Ribeiro</title>
	<atom:link href="http://jpedroribeiro.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://jpedroribeiro.com</link>
	<description>Brazilian web designer writing about design, photography, illustrations and his projects.</description>
	<lastBuildDate>Wed, 09 May 2018 16:03:13 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.9.2</generator>
<site xmlns="com-wordpress:feed-additions:1">9030101</site>	<item>
		<title>Fun with Browser APIs: Speech Synthesis</title>
		<link>http://jpedroribeiro.com/2018/05/fun-with-browser-apis-speech-synthesis/</link>
		<pubDate>Wed, 09 May 2018 16:03:13 +0000</pubDate>
		<dc:creator><![CDATA[J. Pedro Ribeiro]]></dc:creator>
				<category><![CDATA[Front-End Development]]></category>
		<category><![CDATA[APIs]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[speech]]></category>
		<category><![CDATA[voices]]></category>

		<guid isPermaLink="false">http://jpedroribeiro.com/?p=324</guid>
		<description><![CDATA[In this article I'll show you how to use the Speech Synthesis API, that enables the browser to "speak" plain text. <a href="http://jpedroribeiro.com/2018/05/fun-with-browser-apis-speech-synthesis/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>On the previous post, I showed how you can use the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API" rel="noopener" target="_blank">Web Speech API</a> to translate <em>speech to text</em> using Speech Recognition. Today, I&#8217;m going to talk about the the API&#8217;s other interface: <a href="https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesis" rel="noopener" target="_blank">Speech Synthesis</a>.</p>
<h2>What is it about?</h2>
<p>This interface enables synthetic voices to read plain text. The list of synthetic voices depends on which device you&#8217;re using and you can get a list of the available ones by running the <code>getVoices</code> method.</p>
<p>A simple example of this API goes like this:</p>
<pre>
const utter = new SpeechSynthesisUtterance(myTextField.value);
utter.voice = window.speechSynthesis.getVoices()[0]]; // Picked the 1st available voice, which is also default
window.speechSynthesis.speak(utter);
</pre>
<p>You can also set other properties of your <code>SpeechSynthesisUtterance</code> instance, like pitch, volume, rate, volume <a href="https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance" rel="noopener" target="_blank">and more</a>.</p>
<h2>Conclusion</h2>
<p>On this <a href="https://github.com/jpedroribeiro/FunWithBrowserAPIs/tree/master/speechsynthesis" rel="noopener" target="_blank">GitHub repo</a> you can see the full implementation of the example above including a selector for all synthetic voices available on your device.</p>
]]></content:encoded>
		<post-id xmlns="com-wordpress:feed-additions:1">324</post-id>	</item>
		<item>
		<title>Fun with Browser APIs: Speech Recognition</title>
		<link>http://jpedroribeiro.com/2018/03/fun-with-browser-apis-speech-recognition/</link>
		<pubDate>Sun, 04 Mar 2018 16:48:38 +0000</pubDate>
		<dc:creator><![CDATA[J. Pedro Ribeiro]]></dc:creator>
				<category><![CDATA[Front-End Development]]></category>
		<category><![CDATA[APIs]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[recognition]]></category>
		<category><![CDATA[speech]]></category>
		<category><![CDATA[translation]]></category>
		<category><![CDATA[voice]]></category>

		<guid isPermaLink="false">http://jpedroribeiro.com/?p=321</guid>
		<description><![CDATA[With just a few lines we can write an app that translates speech into text, all thanks to the Speech Recognition API. <a href="http://jpedroribeiro.com/2018/03/fun-with-browser-apis-speech-recognition/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>On this third post about <a href="http://jpedroribeiro.com/tag/apis/" rel="noopener" target="_blank">browser APIs</a> we&#8217;re gonna talk about audio, or more specifically, speech. The <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API" rel="noopener" target="_blank">Web Speech API</a> is compromised of two interfaces, and today we&#8217;re going to talk about one of them: <a href="https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition" rel="noopener" target="_blank">Speech Recognition</a>.</p>
<h2>What is it about?</h2>
<p>The <strong>Speech Recognition API</strong> takes a speech input (via microfone) and outputs a list of results, which including the transcript and the confidence level of that translation. It is customisable, letting you define what <strong>language</strong> you&#8217;re using and what words (<strong>Grammar</strong>) you are interested in.</p>
<p>The <em>confidence level</em> (0-1) changes over time, meaning that as you speak, new results are output replacing the initial <em>guess</em>. When the system is happy with the results, a boolean flag <code>isFinal</code> comes true and it moves on to following parts of the speech.</p>
<h2>Using the API to type as you speak</h2>
<p>A simple speech to text application could be done with the following code:</p>
<pre>
const speech = new SpeechRecognition();
speech.lang = ‘en-US’;
speech.onresult = (event) => {
    console.log(event.results[0][0].transcript
}
speech.start();
</pre>
<h2>Grammar</h2>
<p>On that example, more options could be applied to the <code>speech</code> variable, like <code>grammar</code>. Grammar must be written using the JSpeech Grammar Format, you can ream about it in the <a href="https://www.w3.org/TR/jsgf/" rel="noopener" target="_blank">spec document</a>.</p>
<h2>Conclusion</h2>
<p>With just a few lines we managed to translate speech into text, which then can be used by your application to do as you please. You could, for example, create a voice activated app by limiting the grammar and taking actions depending on which word was said.</p>
<p>A more complete example is available on <a href="https://github.com/jpedroribeiro/FunWithBrowserAPIs/tree/master/speechrecognition" rel="noopener" target="_blank">this GitHub repo</a>, where apart from a simple dictation, I&#8217;ve added a voice functionality to search for merchants on a website.</p>
]]></content:encoded>
		<post-id xmlns="com-wordpress:feed-additions:1">321</post-id>	</item>
		<item>
		<title>Fun with Browser APIs: Shape Detection</title>
		<link>http://jpedroribeiro.com/2018/02/fun-with-browser-apis-shape-detection/</link>
		<pubDate>Sat, 03 Feb 2018 13:38:01 +0000</pubDate>
		<dc:creator><![CDATA[J. Pedro Ribeiro]]></dc:creator>
				<category><![CDATA[Front-End Development]]></category>
		<category><![CDATA[APIs]]></category>
		<category><![CDATA[barcode]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[camera]]></category>
		<category><![CDATA[face detection]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[photo]]></category>
		<category><![CDATA[shape detection]]></category>

		<guid isPermaLink="false">http://jpedroribeiro.com/?p=319</guid>
		<description><![CDATA[In this article I am going to talk about Shape Detection API,  a feature enables detection of faces, barcodes and text. <a href="http://jpedroribeiro.com/2018/02/fun-with-browser-apis-shape-detection/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>This is the second instalment of <a href="http://jpedroribeiro.com/tag/apis/" rel="noopener" target="_blank">Fun with Browser APIs</a>, and today I&#8217;m going to talk about <a href="https://wicg.github.io/shape-detection-api/#api" rel="noopener" target="_blank">Shape Detection</a>.</p>
<h2>Spec in draft stage</h2>
<p>This is a very <em>experimental</em> API, meaning, there is not a lot of documentation available. The <a href="https://www.w3.org/community/wicg/" rel="noopener" target="_blank">WICG</a> (<em>Web Incubator Community Group</em>) spec is very new. At the time of writing this post, the last update was January 3rd 2018. This is just a <strong>warning</strong> that it is possible that some of the methods and features described in this article might be out of date if you&#8217;re reading it later in the year.</p>
<h2>What is it about?</h2>
<p>The <strong>Shape Detection API</strong> does what it says on the tin: detect shapes. This is a feature that has been available on a <strong>hardware</strong> level for a while, but now it surfaced to software.</p>
<p>This means that not only the browser you&#8217;re using has to support the API, but the device you&#8217;re using must have this capability.</p>
<p>When we talk about shapes, we&#8217;re including:</p>
<ul>
<li>Faces</li>
<li>Barcode</li>
<li>Text</li>
</ul>
<h2>Face Detector</h2>
<p>In this article I&#8217;m focusing on detecting faces. The <code>FaceDetector</code> constructor accepts an <em>options</em> param where you can set maximum number of faces to detect and whether you want it done using <em>fast mode</em> (prioritise speed over accuracy).</p>
<h2>Using the API to detect faces in a picture</h2>
<p>This can be achieved by doing the following:</p>
<pre>
var faceDetector = new FaceDetector();
  faceDetector
    .detect(myImageElement)
    .then(faces => {
       console.log(faces);
    });
</pre>
<p>In this example, <code>faces</code> is a list of recognized faces. Each face comes with dimensions, coordinates and landmarks. According to the spec, landmarks can be either eyes or mouth, and each landmark object comes with its own coordinates.</p>
<p>A working example can be found in <a href="https://github.com/jpedroribeiro/FunWithBrowserAPIs/tree/master/shapedetection/trek" rel="noopener" target="_blank">this GitHub repo</a>.</p>
<h2>Using the API to detect faces on a live feed</h2>
<p>We saw on the <a href="http://jpedroribeiro.com/2018/01/fun-with-browser-apis-media-stream-image-capture/">previous article</a> that we can easily use MediaStream to capture a camera feed into a <code>video</code> element. Could we use detect shapes of this stream?</p>
<p>Luckily for us, yes! In fact, you can use FaceDetector in any <a href="https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#imagebitmapsource" rel="noopener" target="_blank">ImageBitmapSource</a>, such as:</p>
<ul>
<li>image</li>
<li>video</li>
<li>canvas</li>
</ul>
<p>Here is how:</p>
<pre>
// #1 Start live feed
navigator
  .mediaDevices
  .getUserMedia({ video: true, audio: false })
  .then(mediaStream => {
    window.myVideoElement.srcObject = mediaStream;
  });

// #2 Captures faces and display them in the browser console
function faceDetectorLoop() {
  faceDetector
    .detect(window.myVideoElement)
    .then((faces) => {
      console.log(faces);
      window.requestAnimationFrame(faceDetectorLoop); // Loops detection
    });
}

// #3 Run
faceDetectorLoop();
</pre>
<p>We start (1) by opening up the camera feed with <code>video</code> only, then we define a function (2) that will detect faces in an infinite loop using <a href="https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame" rel="noopener" target="_blank">requestAnimationFrame</a>, and finally we start (3) the detection script.</p>
<p>I&#8217;ve create a <strong>more complete</strong> implementation of this idea in <a href="https://github.com/jpedroribeiro/FunWithBrowserAPIs/tree/master/shapedetection/live" rel="noopener" target="_blank">this GitHub repo</a>, just click on the main box to start the application.</p>
<h2>Conclusion</h2>
<p>Shape detection is a very <strong>powerful</strong> feature that not many people is aware of. Faces, barcodes and text can be detected and used as your application needs.</p>
]]></content:encoded>
		<post-id xmlns="com-wordpress:feed-additions:1">319</post-id>	</item>
		<item>
		<title>Fun with Browser APIs: Media Stream Image Capture</title>
		<link>http://jpedroribeiro.com/2018/01/fun-with-browser-apis-media-stream-image-capture/</link>
		<pubDate>Fri, 26 Jan 2018 15:24:37 +0000</pubDate>
		<dc:creator><![CDATA[J. Pedro Ribeiro]]></dc:creator>
				<category><![CDATA[Front-End Development]]></category>
		<category><![CDATA[APIs]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[camera]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[photo]]></category>
		<category><![CDATA[stream]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://jpedroribeiro.com/?p=314</guid>
		<description><![CDATA[MediaStream combined with Image Capture gives you full control of the camera feeds of a device, with very little code. <a href="http://jpedroribeiro.com/2018/01/fun-with-browser-apis-media-stream-image-capture/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><strong>Fun with Browser APIs</strong> is a series of <a href="http://jpedroribeiro.com/Blog/">posts</a> in which I introduce one or more APIs that you might not heard about or used. </p>
<p>This first one on the list is: <a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaStream_Image_Capture_API" rel="noopener" target="_blank">MediaStream Image Capture</a>.</p>
<h2>What is it about?</h2>
<p>The <strong>MediaStream Image Capture APi</strong> is an API for capturing <strong>images</strong> or <strong>videos</strong> from devices.<br />
It allows <strong>multiple camera</strong> configuration, so you could control the front and back cameras of your mobile phone, for example.<br />
The API also enables you to configure <em>flash</em>, <em>red-eye reduction</em>, <em>image size </em>(resolution) and more.<br />
Support is currently minimal, to use it with all these feature you&#8217;re gonna need <strong>Chrome</strong> 59+.</p>
<h2>Using the API to capture a camera feed</h2>
<p>With very little code you can capture a device&#8217;s camera feed and use it as a source for a <code>video</code> element. For example:</p>
<pre>
navigator
  .mediaDevices.getUserMedia({ audio: true, video: true })
  .then(mediaStream => {
    myVideoElement.srcObject = mediaStream;
  });
</pre>
<p>As you can see, <code>getUserMedia</code> accepts a <strong>configuration object</strong> with <code>audio</code> and <code>video</code>. They can either have <em>boolean</em> values, telling the API whether you want audio and video, or, an <em>object</em>, if you need to specify more details of how you want the <strong>stream</strong> to be, for example: <code>video: {width 600, height: 480}</code>.</p>
<p>It&#8217;s worth to note that these options will be taken into account depending on the <strong>device capabilities</strong>. It also defaults to max resolution.</p>
<h2>Using the API to take photos</h2>
<p>Expanding the example above, you can use the mediaStream track to create an instance of ImageCapture, which will then let you:</p>
<ul>
<li>Grab a frame of the video feed, using <code>grapFrame</code>
<li>Take a photo using the camera&#8217;s full capabilities, using <code>takePhoto</code>
</ul>
<p>And the code would be something like this:</p>
<pre>
navigator
  .mediaDevices.getUserMedia({ audio: true, video: true })
  .then(mediaStream => {
    const track = mediaStream.getVideoTracks()[0];
    const imageCapture = new ImageCapture(track);
    imageCapture.grabFrame()
      .then(frame => {
        myImageElement.src = frame;
      });
  });
</pre>
<p>In this example, I&#8217;ve used <code>frame</code> as a source for an <code>image</code> tag, but you could also use it to populate a <code>canvas</code> element.</p>
<h2>Conclusion</h2>
<p>MediaStream combined with Image Capture gives you full control of the camera feeds of a device, with very little code.</p>
<p>I&#8217;ve create a more complete example on this GitHub repo <a href="https://github.com/jpedroribeiro/FunWithBrowserAPIs/tree/master/imagecapture" rel="noopener" target="_blank">https://github.com/jpedroribeiro/FunWithBrowserAPIs/tree/master/imagecapture</a> where I combined these APIs with <code>canvas</code> to create a very basic image manipulation app. </p>
]]></content:encoded>
		<post-id xmlns="com-wordpress:feed-additions:1">314</post-id>	</item>
		<item>
		<title>Accessibility Tests with Pa11y &#038; Node</title>
		<link>http://jpedroribeiro.com/2018/01/accessibility-tests-with-pa11y-node/</link>
		<pubDate>Wed, 10 Jan 2018 20:42:48 +0000</pubDate>
		<dc:creator><![CDATA[J. Pedro Ribeiro]]></dc:creator>
				<category><![CDATA[Front-End Development]]></category>
		<category><![CDATA[a11y]]></category>
		<category><![CDATA[accessibility]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[node.js]]></category>

		<guid isPermaLink="false">http://jpedroribeiro.com/?p=309</guid>
		<description><![CDATA[In this article I'm going to show you how to automate your accessibility testing with just a little amount of JavaScript and a great library called Pa11y. <a href="http://jpedroribeiro.com/2018/01/accessibility-tests-with-pa11y-node/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>In this article I&#8217;m going to show you how to automate your accessibility testing with just a little amount of JavaScript and a great library.</p>
<h2>A little background</h2>
<p>A while ago I was under the task of review the <strong>accessibility</strong> standards of the website we were working on. We were used to do this, roughly, twice a year. One engineer would get this <strong>ticket</strong>, run through the code base for obvious <strong>a11y</strong> (accessibility) issues, and would submit a <strong>pull request</strong> with the fixes.</p>
<p>It was a <strong>manual job</strong> and the requirements would be very loose. An <code>alt</code> tag here, a <code>label</code> there. Nothing more than a few file changes.</p>
<p>It&#8217;s valid to point out that, keeping a commercial site up to accessibility standards is not just a nice thing to do to your users but also it is the <a href="https://www.gov.uk/service-manual/helping-people-to-use-your-service/making-your-service-accessible-an-introduction" target="_blank">law</a>.</p>
<p>When you combine repetitive tasks with lack of time you get&#8230; <strong>automation</strong>. We engineers are <em>&#8220;lazy&#8221;</em> by nature and the idea of automating a tedious task is what makes our job exciting.</p>
<h2>Accessibility tests automation = pa11y</h2>
<p>When researching about tools I could use for this task I came across <a href="http://pa11y.org/" target="_blank">Pa11y</a>, which includes not only the command line interface but also a dashboard, webservice and a CI.</p>
<p>In this article I&#8217;m focusing on the JavaScript interface that Pa11y provides, letting us write node modules to achieve our automation. I&#8217;m also using the version 5.0 beta, in which makes use of headless Chrome in place of PhantomJS.</p>
<h2>Installation and first steps</h2>
<p>Go to your terminal and make sure your node version is at least 8:<br />
<code>$ node -v<br />
v8.9.4</code></p>
<p>All good. Now we install pa11y@beta (version 5 will soon leave beta and become the master branch, but in the meantime we need to tag its beta branch):<br />
<code>$ npm install -g pa11y@beta</code></p>
<p>The <code>-g</code> is optional, it means it&#8217;s a <em>global</em> install and makes it available throughout the system. If you need this just for one specific project, feel free to skip it.</p>
<p>With the installation done, you can start using it&#8217;s command line interface straightaway:<br />
<code>$ pa11y http://www.google.com</code></p>
<p>The output will be a list of accessibility issues found on that specific URL.<br />
Now let&#8217;s see how we can test multiple pages at the same time and generate reports.</p>
<h2>Node.js to the rescue</h2>
<p>Pa11y provides a <strong>JavaScript interface</strong> that lets us write node scripts to create automation. In its most basic form, you can replicate the example above this way:</p>
<p>&#8211; In a file named a11y.js, type the following code:</p>
<pre>
const pa11y = require('pa11y');
pa11y('http://www.google.com/')
  .then((results) => { 
    console.log(results);
  });
</pre>
<p>&#8211; Now run it on your terminal<br />
<code>$ node a11y.js</code></p>
<p>You will notice that, now, the output is in <strong>JSON</strong> format. You can change it to CSV, HTML, and other types by passing a <strong>configuration object</strong> which will see more details later on. </p>
<p>Now let&#8217;s try testing multiple pages.</p>
<h2>Testing multiple pages</h2>
<pre>
const pa11y = require('pa11y');
const urls = [
    pa11y('http://www.google.com'),
    pa11y('http://www.bbc.co.uk'),
    // Add more pages here as needed
];

Promise.all(urls)
  .then(results => {
    console.log(results[0]); // Results for Google
    console.log(results[1]); // Results for BBC
  });
</pre>
<p>You can cater for each page individually, or you could just <strong>loop through</strong> the <code>results</code> array.</p>
<p>The console <strong>output</strong> can become overwhelming on some sites, so let&#8217;s output this results into a readable HTML with the help of <strong>reporters</strong>.</p>
<h2>Reporters</h2>
<p>As default, Pa11y comes with <strong>JSON</strong>, CSV and CLI reporters, but you can add <strong>HTML</strong> and TSV via additional packages. To enable HTML reporting you need to install another node module:</p>
<p><code>$ npm install -g pa11y-reporter-html</code></p>
<p>As before, the <code>-g</code> is optional.<br />
With that done, we need to change our code to the following:</p>
<pre>
const pa11y = require('pa11y');
const html = require('pa11y-reporter-html');
const urls = [
  pa11y('http://www.google.com'),
  pa11y('http://www.bbc.co.uk')
];

Promise.all(urls)
  .then(results => {
    const googleResults = html.results(results[0]);
    const bbcResults = html.results(results[1]);

    googleResults
      .then(output => {
        console.log(output)
      });

    bbcResults
      .then(output => {
        console.log(output)
      });
  });
</pre>
<p>If you run that, <code>$ node a11y.js</code> you will get the output of each test in HTML format. With that content in hands, you can always use it to save into a file using <code>fs.createWriteStream</code>.</p>
<h2>Conclusion</h2>
<p>With a very small script and the help of a great library like Pa11y, accessibility tests can easily be automated.</p>
<p>You can always take a step further and try out their <a href="https://github.com/pa11y/pa11y-dashboard">dashboard repository</a> if you like to have a more graphical interface, or use <a href="https://github.com/pa11y/pa11y-ci" target="_blank">pa11y-ci</a>, for continuous integration.</p>
]]></content:encoded>
		<post-id xmlns="com-wordpress:feed-additions:1">309</post-id>	</item>
		<item>
		<title>Book Review: Web Performance In Action</title>
		<link>http://jpedroribeiro.com/2017/08/book-review-web-performance-in-action/</link>
		<pubDate>Sun, 20 Aug 2017 11:19:34 +0000</pubDate>
		<dc:creator><![CDATA[J. Pedro Ribeiro]]></dc:creator>
				<category><![CDATA[Book Reviews]]></category>
		<category><![CDATA[books]]></category>
		<category><![CDATA[http/2]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[service workers]]></category>

		<guid isPermaLink="false">http://jpedroribeiro.com/?p=303</guid>
		<description><![CDATA[My thoughts on Web Performance in Action, by Jeremy l. Wagner. <a href="http://jpedroribeiro.com/2017/08/book-review-web-performance-in-action/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>For the past 2 years, my work has had a focus on delivering <strong>fast experiences</strong> on the web. I&#8217;ve also kept an eye on any article, tweet or <a href="https://www.meetup.com/London-Web-Performance-Group/" target="_blank">Meetup</a> that would mention performance. It was a job requirement back then, now it&#8217;s something I&#8217;m quite passionate about.</p>
<h2>The Book</h2>
<p>Which brings me to this <a href="http://jpedroribeiro.com/category/book-reviews/">book</a>, <a href="https://www.manning.com/books/web-performance-in-action" target="_blank">Web Performance In Action</a>, by <a href="https://twitter.com/malchata" target="_blank">Jeremy L. Wagner</a>. It&#8217;s a very thorough collection of information on how to develop fast websites, from the best way to load <strong>fonts</strong> to techniques that cater for <strong>HTTP/2</strong>.</p>
<p>With my years of experience in this area I can honestly say that this book is more suitable for intermediate developers. If you are a beginner, you will still find plenty of tutorials to follow and implement without much effort &#8211; there are enough links to ready made solutions that will suit most scenarios and use cases. For an advanced user, it might be more of the same.</p>
<h2>Some Highlights</h2>
<p>Right in the first chapters of the book, the author explain how to use <strong>Chrome Dev Tools</strong> to properly investigate <strong>performance issues</strong>. To me this was one of the highlights of the book. It&#8217;s very well explained and give the readers a good set of tools to use throughout the book.</p>
<p>Another highlight was the chapter on <a href="https://developers.google.com/web/fundamentals/getting-started/primers/service-workers" target="_blank">Service Workers</a>. With <a href="https://twitter.com/webmaxru/status/893027996659060738" target="_blank">the news that Safari is intending to implement this technology</a>, it&#8217;s good to see the effort in educating more developers about it.</p>
<p>But most of all, the <strong>best chapter</strong> in my opinion was the one regarding <a href="https://http2.github.io/" target="_blank">HTTP/2</a>. It manages to summarize a lot of information in a very easy to read manner. If you never heard of <em>header compression</em>, <em>head-of-line-blocking</em>, or <em>SSL</em>, then this is when you will become familiarized with these terms and understand the improvements this new version of the protocol is bringing the to web.</p>
]]></content:encoded>
		<post-id xmlns="com-wordpress:feed-additions:1">303</post-id>	</item>
		<item>
		<title>Progressive Web Apps</title>
		<link>http://jpedroribeiro.com/2016/12/progressive-web-apps/</link>
		<pubDate>Thu, 29 Dec 2016 14:39:28 +0000</pubDate>
		<dc:creator><![CDATA[J. Pedro Ribeiro]]></dc:creator>
				<category><![CDATA[Front-End Development]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[progressivewebapps]]></category>
		<category><![CDATA[pwa]]></category>
		<category><![CDATA[serviceworker]]></category>

		<guid isPermaLink="false">http://jpedroribeiro.com/?p=301</guid>
		<description><![CDATA[In the past couple of months I've been reading quite a lot about Progressive Web Apps . The term is getting very popular especially due to Google's effort and investment in this concept. In this article I give a brief description and point out where to start. <a href="http://jpedroribeiro.com/2016/12/progressive-web-apps/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>In the past couple of months I&#8217;ve been reading quite a lot about Progressive Web Apps. The term is getting very popular especially due to Google&#8217;s effort and investment in the concept.</p>
<h2>What is a Progressive Web App?</h2>
<p>I kind of like <a href="https://twitter.com/lady_ada_king" target="_blank">Ada Rose Edwards</a> definition: <a href="https://www.youtube.com/watch?v=5ylZbXelPMA" target="_blank">&#8220;A website so good you want to save it on your home screen&#8221;</a>.</p>
<p>According to Google, a Progressive Web App is &#8220;<em>a website or web application that is reliable, fast and engaging</em>&#8220;. Lets break down those 3 pillars:</p>
<p><b>Reliable</b>: this is mostly about using <a href="https://developer.mozilla.org/en/docs/Web/API/Service_Worker_API" target="_blank">Service Workers</a> and enabling <strong>offline</strong> with the use of cache control and managing requests when connection is unstable.</p>
<p><b>Fast</b>: we all know thats users leave websites if they take too long to load. Google is putting a lot of emphasis on <strong>performance</strong> these days and I wouldn&#8217;t be surprised if it becomes part of its indexing algorithm.</p>
<p>Engaging</b>: basically, the features that make a website look more like a <strong>native</strong> app &#8211; being installable, work on full screen, make use of <a href="https://developer.mozilla.org/en/docs/Web/API/Push_API" target="_blank">push notifications</a>.</p>
<h2>Being Progressive</h2>
<p>There is a focus on the <strong>new technologies</strong> like Service Workers and the Push API, but being progressive means catering for legacy browsers too. This is the basic idea of <a href="https://www.gov.uk/service-manual/technology/using-progressive-enhancement" target="_blank">progressive enhancement</a> which we know and have been using for ages.</p>
<h2>Where to start?</h2>
<p>The Google Developer Team has been putting a lot of effort in this field, especially since their <a href="https://www.youtube.com/playlist?list=PLNYkxOF6rcIAWWNR_Q6eLPhsyx6VvYjVb" target="_blank">Summit</a> last September.</p>
<p>They also have a very deep and beginner friendly portal with loads of articles and tutorials on the subject: <a href="https://developers.google.com/web/progressive-web-apps/">https://developers.google.com/web/progressive-web-apps/</a></p>
<p>Smashing Magazine, as always, has done the same and came up with a great article written by Kevin Farrugia on building PWAs: <a href="https://www.smashingmagazine.com/2016/08/a-beginners-guide-to-progressive-web-apps/">https://www.smashingmagazine.com/2016/08/a-beginners-guide-to-progressive-web-apps/</a></p>
<h2>My PWA on github</h2>
<p>I&#8217;ve also being playing around with these concepts and build a very simple page to practise. You can have a look at the source code on github: <a href="https://github.com/jpedroribeiro/VoucherWallet">https://github.com/jpedroribeiro/VoucherWallet</a></p>
]]></content:encoded>
		<post-id xmlns="com-wordpress:feed-additions:1">301</post-id>	</item>
		<item>
		<title>Book Review: Using WebPageTest</title>
		<link>http://jpedroribeiro.com/2016/08/book-review-using-webpagetest/</link>
		<pubDate>Mon, 29 Aug 2016 15:56:18 +0000</pubDate>
		<dc:creator><![CDATA[J. Pedro Ribeiro]]></dc:creator>
				<category><![CDATA[Book Reviews]]></category>
		<category><![CDATA[books]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://jpedroribeiro.com/?p=296</guid>
		<description><![CDATA[You can&#8217;t start talking about performance without hearing about WebPageTest. It&#8217;s by far the most complex and useful synthetic tool available these days. I&#8217;ve been using it for quite some time and decided to brush up my knowledge by reading &#8230; <a href="http://jpedroribeiro.com/2016/08/book-review-using-webpagetest/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>You can&#8217;t start talking about <strong>performance</strong> without hearing about <a href="https://www.webpagetest.org/" target="_blank">WebPageTest</a>. It&#8217;s by far the most complex and useful synthetic tool available these days. I&#8217;ve been using it for quite some time and decided to brush up my knowledge by <a href="http://jpedroribeiro.com/category/book-reviews/">reading</a> <a href="http://shop.oreilly.com/product/0636920033592.do" target="_blank">Using WebPageTest</a>, by O&#8217;Reily Media.</p>
<h2>Back to basics</h2>
<p>The book says clearly on the cover: &#8220;&#8230;for novices and power users&#8221; so you&#8217;ve been warned. I&#8217;ve been using WebPageTest, on and off, for years. If you are in the same situation, you might find that 70% of the book is too obvious or just common sense, after all, WebPageTest is a pretty self explanatory tool.</p>
<h2>Hidden complexity</h2>
<p>With that in mind, the advanced parts of the books are quite good. I was not fully aware of the <strong>script</strong> capabilities of WPT. The fact that you can give instructions to it and <strong>simulate</strong> a navigation flow is very powerful. You can simulate a login scenario by doing the following:<br />
<code><br />
navigate http://www.example.com/login<br />
setValue id=u username<br />
setValue ud=p password<br />
submitForm id=login-form<br />
navigate http://www.example.com/profile/username<br />
</code></p>
<p>Other highlights include a full chapter on Continuous Integration, with plenty of examples on how to setup WPT and Jenkins or Travis, or how to setup a private instance of WPT &#8211; which I <a href="https://twitter.com/jpedroribeiro/status/766623046471942144" target="_blank">struggled to achieve</a> a couple weeks ago!</p>
<blockquote class="twitter-tweet" data-lang="en">
<p lang="en" dir="ltr">Took me a day and a half but I finally managed to get WebPageTest working on AWS <img src="https://s.w.org/images/core/emoji/2.3/72x72/1f605.png" alt="😅" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>&mdash; João Pedro Ribeiro (@jpedroribeiro) <a href="https://twitter.com/jpedroribeiro/status/766623046471942144">August 19, 2016</a></p></blockquote>
<p><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></p>
<h2>Conclusion</h2>
<p>I <strong>definitely recommend</strong> reading this book. WPT is such a complex tool that I can guarantee you will find something new about it that you didn&#8217;t know before.</p>
<p>Having said that, bear in mind that <strong>WebPageTest</strong>, like any other <strong>open source project</strong>, is constantly being updated and you mind find some topics presented on the book are slightly outdated.</p>
]]></content:encoded>
		<post-id xmlns="com-wordpress:feed-additions:1">296</post-id>	</item>
		<item>
		<title>What&#8217;s the deal with renaming files in Git?</title>
		<link>http://jpedroribeiro.com/2016/06/whats-the-deal-with-renaming-files-in-git/</link>
		<pubDate>Sat, 11 Jun 2016 14:06:39 +0000</pubDate>
		<dc:creator><![CDATA[J. Pedro Ribeiro]]></dc:creator>
				<category><![CDATA[Front-End Development]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[version control]]></category>

		<guid isPermaLink="false">http://jpedroribeiro.com/?p=278</guid>
		<description><![CDATA[If you try renaming a file in your project, you might notice a weird behaviour when checking its status. Find out why and how to avoid it. <a href="http://jpedroribeiro.com/2016/06/whats-the-deal-with-renaming-files-in-git/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>If you try <strong>renaming</strong> a file in your project, you might notice this weird behaviour when checking its <strong>status</strong>:<br />
<code><br />
$ git status<br />
On branch master<br />
Your branch is up-to-date with 'origin/master'.</p>
<p>Changes not staged for commit:<br />
  (use "git add/rm <file>..." to update what will be committed)<br />
  (use "git checkout -- <file>..." to discard changes in working directory)</p>
<p>	deleted:    README.md</p>
<p>Untracked files:<br />
  (use "git add <file>..." to include in what will be committed)</p>
<p>	README-NEW.md</p>
<p>no changes added to commit (use "git add" and/or "git commit -a")<br />
</code></p>
<h2>Why is this happening?</h2>
<p>The short answer is: <strong>Git</strong> relies on <strong>names</strong> to know if whether a file is <strong>tracked</strong> or not.<br />
When you rename a file, <a href="http://jpedroribeiro.com/tag/git/">Git</a> believes the original file got deleted and suddenly there&#8217;s a new file in which it knows nothing about. Hence the <em>untracked</em> status.</p>
<h2>Alternative: rename with Git</h2>
<p>If you want to avoid this behaviour, you could simply use the native <a href="http://jpedroribeiro.com/tag/git/">Git</a> command: <em>git mv</em><br />
<code><br />
$ git mv README.md README-NEW.md<br />
$ git status<br />
On branch master<br />
Your branch is up-to-date with 'origin/master'.</p>
<p>Changes to be committed:<br />
  (use "git reset HEAD <file>..." to unstage)</p>
<p>	renamed:    README.md -> README-NEW.md<br />
</code></p>
<p>Nice and easy.</p>
]]></content:encoded>
		<post-id xmlns="com-wordpress:feed-additions:1">278</post-id>	</item>
		<item>
		<title>Understanding Bandwidth vs Latency Through An Analogy</title>
		<link>http://jpedroribeiro.com/2016/05/understanding-bandwidth-vs-latency-through-an-analogy/</link>
		<pubDate>Sat, 14 May 2016 15:53:38 +0000</pubDate>
		<dc:creator><![CDATA[J. Pedro Ribeiro]]></dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://jpedroribeiro.com/?p=288</guid>
		<description><![CDATA[I'm going to explain the difference between latency and bandwidth, two important concepts in browser performance, using an analogy. <a href="http://jpedroribeiro.com/2016/05/understanding-bandwidth-vs-latency-through-an-analogy/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><img src="http://jpedroribeiro.com/wp-content/uploads/2016/04/road-1024x683.jpg" alt="road" width="640" height="427" class="size-large wp-image-291" srcset="http://jpedroribeiro.com/wp-content/uploads/2016/04/road-1024x683.jpg 1024w, http://jpedroribeiro.com/wp-content/uploads/2016/04/road-300x200.jpg 300w, http://jpedroribeiro.com/wp-content/uploads/2016/04/road-768x512.jpg 768w" sizes="(max-width: 640px) 100vw, 640px" /></p>
<p>To understand how <a href="http://jpedroribeiro.com/tag/performance/">performance</a> can affect your website, it&#8217;s important to understand common terms and which part they play in a <strong>network</strong> connection. I&#8217;m going to try to explain the differences between <strong>bandwidth</strong> and <strong>latency</strong> by using an analogy*. Bear with me.</p>
<h2>Road to performance</h2>
<p>Picture <strong>bandwidth</strong> as being the amount of luggage you can fit  inside the boot of a car.</p>
<p>Now imagine <strong>latency</strong> as being the distance between you and your destination, let&#8217;s say Brighton.</p>
<p>You can fit (<em>bandwidth</em>) as much as you want as long as it fits the boot of your car. And for this exercise, let&#8217;s ignore the differences between cars.</p>
<h2>Time for upgrade</h2>
<p>You feel it&#8217;s time to <strong>upgrade</strong> your vehicle as you have too many things to carry. You upgrade it to a 5mb/s connection, I mean, a <strong>big truck</strong> with lots of space to fill (bandwidth). </p>
<p>Everything is great and you can carry all the items you want. But you still need to go to Brighton, and it&#8217;s quite far away (<em>latency</em>).</p>
<p>The distance (<em>latency</em>) is still the same, no matter how much you can carry (<strong>bandwidth</strong>) in one go.</p>
<h2>Summing up</h2>
<p>This is why <em>streaming</em> movies requires good bandwidth, as you need to carry a lot of data in one go. Websites, on the other hand, perform better when  latency is reduced, lots of small files requires lots of roundtrips.</p>
<p>* This is not an original idea. I&#8217;ve read similar analogies several times. This is <strong>my take</strong> on it.</p>
]]></content:encoded>
		<post-id xmlns="com-wordpress:feed-additions:1">288</post-id>	</item>
	</channel>
</rss>
