Anthony Ricaud - Mot-clé - mozilla2021-07-12T23:31:52+02:00urn:md5:bf61b2e51f5d21992f38e5e7172f6e92DotclearLast week W20urn:md5:b69b00fae1eb44a5099ce8b1c0844ef12021-05-24T12:50:00+02:002021-05-24T12:51:20+02:00Anthony Ricaud <p>I haven't used this blog in a few years. To get back in the groove, I'm starting with a weekly post.</p>
<h2>WebPageTest contributions</h2>
<p>I've done a few contributions to that project recently:</p>
<ul>
<li><a href="https://github.com/WPO-Foundation/webpagetest-docs/pull/25">Docs #27</a>: The table of contents shows more headings. This makes it easier to scan the content of a page and share anchor links. <a href="https://twitter.com/anthony_ricaud/status/1390313289880588294">Before/After screenshots</a>.</li>
<li><a href="https://github.com/WPO-Foundation/webpagetest-docs/pull/29">Docs #29</a>: WebPageTest supported a few variable substitutions for quite a while but they were undocumented. <a href="https://docs.webpagetest.org/scripting/#variable-substitutions">No more!</a></li>
<li><a href="https://github.com/WPO-Foundation/webpagetest/pull/1498">WebPageTest #1498</a>: Add labels to form inputs in Custom Waterfall. Bigger targets to customise faster than ever.</li>
</ul>
<h2><a href="https://frontstuff.io/no-utility-classes-arent-the-same-as-inline-styles">No, Utility Classes Aren't the Same As Inline Styles</a></h2>
<p>Utility-first is a trend in the front-end world. I think it's a powerful tool and I've seen positive outcomes in terms of maintenance and performance for the projects where I've used this approach. Many people dismiss this approach. One of the common criticism is that it's just like inline styles. Sarah explains why it is not.</p>
<p>My highlights:</p>
<ul>
<li>Utility can affect more than one element. Inline cannot (besides <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/inheritance">inheritance</a>).</li>
<li>Utility can use pseudo-classes, pseudo-elements and media queries. Inline styles cannot.</li>
<li>Utility can be processed by tools like <a href="https://postcss.org">PostCSS</a> or <a href="https://sass-lang.com">Sass</a>. Inline styles, so far, cannot.</li>
<li>Utility can be cached much longer than inline styles.</li>
<li>Utility can declare several properties with one declaration. Inline styles cannot.</li>
<li>Utility fits in a strategy and architecture. You can limit a project to a set of colours, spacings, font stacks, text sizes, etc. Inline styles have no such restrictions.</li>
<li>It's better to say "I have not dug into that topic yet" rather than make snap judgements.</li>
</ul>
<p>And if you want to go further, <a href="https://frontstuff.io/in-defense-of-utility-first-css">read</a> or <a href="https://www.youtube.com/watch?v=R50q4NES6Iw">watch</a> her advocate for this approach.</p>
<h2><a href="https://domevents.dev">Teaching DOM Events visually</a></h2>
<p>I've added this to my toolbox straight away. DOM Events have a lot of subtle parts and it can be tricky to explain them. With this tool, you can configure an event (What's the target? Does it bubble? Is it cancelable?) and some listeners. Then you can dispatch the event and see how it propagates. Maybe drop that in your next code design session or review?</p>
<p>Here's an exemple to showcase the difference between <a href="https://domevents.dev/?state=N4IgNglgzgLgpgOzgJyiAXAbVJWiUCSAJhiCADQgID2RcxpAxgBYRgmVwBmXcjMadKEYBDBIzhhSNALSjxkiiFjUADtOoyV6gL6U1MCNQSDQq5iKhwmI1TACuya5VWWoEAG7X0VYzNdQ7l5KxhIaMDKh1jp6ONDwSMgMPko0dMkgXBCoMAAEAObIYkQsbBwg3Lz8piDyElI+snWKlNqk2jIQALZdcEQQIvAgeiAGRiYYZhZWNnaOziABQd6+CP5ungtR4ZEKw7Hg8fhJJCmUafSntazsSpV8ApO1YvUaci8tyjBqb20jY8YauZLCtRHMnEolpsNGsocF9HtGtQItsYuQ4nhEhlUrRLqQsjkCkUECUbuV7tUns0Gr53gopK1vuokVomcN9HZxkDpisAEb2Xm8sALOErGiwjbw0aI3wovZojEJQhXHHpK4E2BE4qlW6cHgPGrUt5Gxk-Fl-DmGQFPYEzHxghwQlySsV+UUhGU0OVhBWHTHK0iqvE+DV5Qrasl3fWUoTPenGj4Mr5m2kW0ac62x22g2yOkUumHrQLQhFhJHe6I6AC6nC8CBgTzgdZgABURMh8nAYBlQ1qSTrytSRELvDBkPY4JR+YLhYIxxORl5UONSABGYZAA">stopImmediatePropagation</a> and <a href="https://domevents.dev/?state=N4IgNglgzgLgpgOzgJyiAXAbVJWiUCSAJhiCADQgID2RcxpAxgBYRgmVwBmXcjMadKEYBDBIzhhSNALSjxkiiFjUADtOoyV6gL6U1MCNQSDQq5iKhwmI1TACuya5VWWoEAG7X0VYzNdQ7l5KxhIaMDKh1jp6ONDwSMgMPko0dMkgXBCoMAAEAObIYkQsbBwg3Lz8piDyElI+snWKlNqkbXogBkYmGGYWVjZ2js4gAUHevgj+bp6jUeGRCiAx5HF4iRmptPQkPqXsSpV8An21YvUachctyjBqVx36dj015paTosNOSuNzGtM-sF9MtGtQIgtVusEoQ9mRKGldqQsjkCkUECVWIdODwTjVmg1fNcFFJWvd1GCtOSVs9DMY3gNJgAjexMplgUZAyY0QGzYFdUG+CHLKHgeL4JJw7bpOEo2Bo4oHcrHapnAlXdVkh6Up5dF70s7vQb7WwOH4uPncvxckKCmjCsKi3AwyWkaVInxyvKFRVY5W41VCc4kjU3Ul3bVE3XdA1Bo2fU0jX6WgEzQL-EFhMEO6I6AC6nC8CBgZzgRZgABURMh8nAYBkvQqMUqlASROzvDBkPY4JQWWyOYIuz3Ol5UD1SABGFZAA">stopPropagation</a>.</p>
<h2><a href="https://blog.chromium.org/2021/05/an-experiment-in-helping-users-and-web.html">Chrome is experimenting with RSS feeds</a></h2>
<p>A few years ago, you could subscribe to RSS feeds in any browser. Safari 2, released in 2005, was even <a href="https://www.apple.com/newsroom/2004/06/28Apple-Previews-Mac-OS-X-Tiger/">marketed</a> as <a href="https://www.anandtech.com/show/1671/9">"Safari RSS"</a>. But it went away (<a href="https://support.mozilla.org/en-US/kb/feed-reader-replacements-firefox">Firefox removed support in December 2018</a>)</p>
<p>As often in life, the pendulum is swinging back and we might see feeds make a come back. I'd welcome that since this is giving some control back to publishers and take it away from social networks. Notice the experiment is using the codes of social networks by calling this feature "Follow".</p>
<h2><a href="https://lukasz.langa.pl/1d1a43c4-9c8a-4c5f-a366-7f22ce6a49fc/">Why the sad face?</a></h2>
<p>I really like very opinionated code formatters. In this post, Łukasz Langa (creator of <a href="https://black.readthedocs.io">Black</a>) highlights how the formatting of closing parentheses is useful.</p>
<h2><a href="https://talk.macpowerusers.com/t/drastically-improve-macos-system-preferences-using-sort-and-customize/23379">Simplifying macOS System Preferences</a></h2>
<p>(via <a href="https://www.la-grange.net">Karl</a>)</p>
<p>I had no idea this was possible. I've disabled all panes for now and will re-enable as I go.</p>
<h2><a href="https://twitter.com/emrazz/status/1393399035155947522">A Twitter quote</a></h2>
<blockquote>
<p>Someone on tv just said, “when we want to incentivize rich people we give them money but when we want to incentivize poor people we take away money,” and holy fuck that’s so true.</p>
</blockquote>
Async/await, a more compelling exampleurn:md5:5a8f4c8d74e0d1ede600bfabebe35aba2017-10-05T17:24:00+02:002017-10-06T21:50:01+02:00Anthony Ricaud <p>Most of the introductions to async/await in JavaScript that I’ve read are very similar, something like this:</p>
<pre><code>// Promise version
function insertArticle(url, element) {
return fetch(url)
.then(response => response.json())
.then(data => {
const article = document.createTextNode(data.article)
element.appendChild(article)
})
.catch(reason => console.error(reason));
}
// Async/await version
async function insertArticle(url, element) {
try {
const response = await fetch(url)
const data = await response.json()
const article = document.createTextNode(data.article)
element.appendChild(article)
} catch (reason) {
console.error(reason)
}
}
</code></pre>
<p>Sure, the async version looks nicer but it’s not earth shattering. When deciding whether to use it or not, it’s a tiny argument in the pro column. In the cons, you have the reduced compatibility with browsers that do not support it yet or the extra code that a polyfill would bring along.</p>
<h2>A more compelling example</h2>
<p>A couple of weeks ago, <a href="https://twitter.com/bdc/status/903544854667567104">Benjamin De Cock shared</a> a <a href="https://gist.github.com/bendc/e78d671aad87185d83c16c3898d03e68">snippet to simulate realistic typing</a>. As I studied it, I felt that the code was not representing the underlying algorithm: for each character in the text, we wait a random time then write the character. Pretty simple to explain, right? Let’s use it as an exercise to get familiar with async/await’s potential.</p>
<h2>First version, callbacks</h2>
<p>I rewrote Benjamin’s original version a little bit. I’ve simplified the tracking of time, changed the function signature and removed the ability to chain calls. But the gist of the algorithm is the same.</p>
<pre><code>function delay(callback, duration) {
const startTime = performance.now()
const tick = () => {
if (performance.now() - startTime < duration) {
requestAnimationFrame(tick)
} else {
callback()
}
}
tick()
}
function random(min, max) {
return Math.random() * (max - min) + min
}
function simulateTyping(
text,
{
in: target,
callback,
min = 10,
max = 80,
iterator = text[Symbol.iterator](),
}
) {
const { value } = iterator.next()
if (!value) {
return callback && callback()
}
delay(() => {
target.insertAdjacentText('beforeend', value)
simulateTyping(text, { in: target, callback, min, max, iterator })
}, random(min, max))
}
simulateTyping('hello world', {
in: document.querySelector('.fake-input'),
callback: () => {
console.log('done')
},
})
</code></pre>
<p>When you read that, it is pretty difficult to follow along. The iteration on each character is done via recursions with an iterator. The delay between each character is also measured with callbacks. There’s a big disconnect between the way a human thinks and the translation of that thinking in code.</p>
<h2>Second version, promises</h2>
<p>Let’s see if using promises instead of callbacks simplifies the code.</p>
<pre><code>function nextFrame() {
return new Promise(resolve => {
requestAnimationFrame(resolve)
})
}
function randomDelay(min, max) {
const delay = Math.random() * (max - min) + min
const startTime = performance.now()
return nextFrame().then(() => {
if (performance.now() - startTime < delay) {
return nextFrame()
}
})
}
function simulateTyping(
text,
{ in: target, min = 10, max = 80, iterator = text[Symbol.iterator]() }
) {
const { value } = iterator.next()
if (!value) {
return Promise.resolve()
}
return randomDelay(min, max).then(() => {
target.insertAdjacentText('beforeend', value)
simulateTyping(text, { in: target, min, max, iterator })
})
}
simulateTyping('hello world', {
in: document.querySelector('.fake-input'),
}).then(() => {
console.log('done')
})
</code></pre>
<p>This has a bit less boilerplate. We don’t have to pass a callback around so we can simplify some calls. But overall, this is the same structure and still difficult.</p>
<h2>Third version, async/await</h2>
<pre><code>async function nextFrame() {
return new Promise(resolve => {
requestAnimationFrame(resolve)
})
}
async function randomDelay(min, max) {
const delay = Math.random() * (max - min) + min
const startTime = performance.now()
while (performance.now() - startTime < delay) {
await nextFrame()
}
}
async function simulateTyping(text, { in: target, min = 10, max = 80 }) {
for (const character of text) {
await randomDelay(min, max)
target.insertAdjacentText('beforeend', character)
}
}
simulateTyping('hello world', {
in: document.querySelector('.fake-input'),
}).then(() => {
console.log('done')
})
</code></pre>
<p>Now that is much clearer! Not very surprising since this is the whole point of this post. The code uses a for/of loop to write each character and a while loop to wait for each random delay.</p>
<p>Doing this little exercise has helped me appreciate async/await more than most things I’ve read so far. Have you seen other nice examples of async/await out there?</p>
Moving to London and looking for jobsurn:md5:fba45d2e925ec417932d0e7244bde3dc2017-07-03T14:40:00+02:002017-07-05T17:05:55+02:00Anthony Ricaud <p>My girlfriend and I decided to move to London<sup id="fnref:1"><a href="https://ricaud.me/blog/post/2017/07/Moving-to-London-and-looking-for-jobs#fn:1" rel="footnote">1</a></sup>. We’re both looking for jobs.</p>
<h2>Shannon</h2>
<p>Shannon is looking for an Office Management or Executive Assistant position. She has managed offices all over Europe, was the lead manager for a global travel program and has experience organising events. She knows that engineering teams are snowflakes (through work and dating me). Anyone who has met Shannon will know that she prides herself on being super organised and helpful. I think she is terrific, but if you need any more convincing you can find out more and contact her via <a href="https://www.linkedin.com/in/shannonaleenclayton/">her LinkedIn profile</a>.</p>
<h2 id="anthony">Anthony</h2>
<p>I’m a senior software engineer and have 10 years of experience in web products. What’s important in my next role:</p>
<ul>
<li>I like having a long term engagement in a problem.</li>
<li>Through iterations, I like improving and simplifying systems. Only crunching new features is not very satisfying for me. I like finding abstractions that click and making it easier to contribute features in the future.</li>
<li>Autonomous teams. When we have engineers, designers, product managers, and any other skill needed to ship that particular product, we can move quickly in the right direction and everyone feels empowered.</li>
<li>Being part of a diverse team.</li>
<li>Learning and teaching. I enjoy sharing my experiences and learning from others. That includes hard and soft skills.</li>
</ul>
<p>If you think your company could be a good match, <a href="https://ricaud.me/cv/">take a look at my CV</a> (or <a href="https://www.linkedin.com/in/anthonyricaud/">LinkedIn profile</a>) and <a href="mailto:anthony@ricaud.me">get in touch</a>.</p>
<div class="footnotes">
<hr />
<ol>
<li id="fn:1">
<p>Yes, we've heard of Brexit. <a href="https://ricaud.me/blog/post/2017/07/Moving-to-London-and-looking-for-jobs#fnref:1" rev="footnote">↩</a></p>
</li>
</ol>
</div>
On the utility of filing bugsurn:md5:4092d0c1131c241d7ddf5caca0f868f32017-04-24T10:30:00+02:002017-04-24T09:36:09+02:00Anthony Ricaud <p>During my five years working at Mozilla, I’ve been known to ask people to file bugs when they encountered an issue. Most of the time, the answer was that they didn’t have time to do so and it was useless. I think it is actually very valuable. You get to learn from that experience: how to file actionable bugs, getting deeper knowledge into a specification, maybe a workaround for the problem.</p>
<h2>A recent example</h2>
<p>Three weeks ago, <a href="https://www.alittlemarket.com">at work</a>, we launched a new design for the website header. We got some reports that the logo was missing in Firefox on some pages. After investigation, we discovered that Firefox (and also Edge) had a different behaviour with SVG’s <code><use xlink:href></code> on pages with a <code><base></code> element. We fixed it right away by using an absolute URL for our logo. But we also filed bugs against <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1352979">Gecko</a> and <a href="https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/11490803/">Edge</a>. As part of filing those bugs, I found the <a href="https://github.com/w3c/svgwg/commit/f378b15b95841cb1297eda7b1a6a2ca2d549ee71">change in the SVG specification</a> clarifying how it should be handled. Microsoft fixed the issue in less than two weeks. <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1357432">Mozilla fixed it</a> in less than three weeks.</p>
<p>In October this year<sup id="fnref:1"><a href="https://ricaud.me/blog/post/2017/04/On-the-utility-of-filing-bugs#fn:1" rel="footnote">1</a></sup>, all browsers should behave the same way in regard to that issue. And a <a href="https://gist.github.com/leonderijke/c5cf7c5b2e424c0061d2">four year old workaround</a> will be obsolete. We will be able to remove the code that we had to introduce. Less code, yeah!</p>
<p>I hope this will convince you that <a href="https://benfrain.com/reporting-browser-bugs-chrome-firefox-safari-teams-gets-fixed/">filing bugs has an impact</a>. You can learn more on <a href="https://www.smashingmagazine.com/2011/09/help-the-community-report-browser-bugs/">how to file actionable bugs</a>. If you’d like an easier venue to file bugs when browsers are incompatible, the <a href="https://webcompat.com">WebCompat project</a> is a nice place to start.</p>
<div class="footnotes">
<hr />
<ol>
<li id="fn:1">
<p>Firefox 55 should be released on August 8 and the next Edge should be released in September (maybe even earlier, I’m not clear on Edge’s release schedule) <a href="https://ricaud.me/blog/post/2017/04/On-the-utility-of-filing-bugs#fnref:1" rev="footnote">↩</a></p>
</li>
</ol>
</div>
Updating my code search toolsurn:md5:259a2fdfddb0c5ee0c25664b91d8b1882017-04-23T09:41:00+02:002018-03-18T15:42:52+01:00Anthony Ricaud <p>Finding an information in a codebase is a very common task performed by software engineers. The quicker you can do it, the more chance you have of not losing your momentum. With proper tools, you can find things 10 times faster<sup id="fnref:1"><a href="https://ricaud.me/blog/post/2017/04/Updating-my-code-search-tools#fn:1" rel="footnote">1</a></sup>.</p>
<p>In 2011, I’ve presented <a href="http://betterthangrep.com">ack</a> in a <a href="http://www.dailymotion.com/video/xpqxvq_lightning-talks-paris-web-2011_tech?start=725">lightning talk</a> at <a href="https://ricaud.me/blog/post/2017/04/[https://ricaud.me/blog/post/2011/10/Paris-Web-2011]">Paris Web</a>. That was my tool of choice for a while. It was very convenient because it didn’t report files stored in the VCS folders. A bit later, I switched to <a href="https://github.com/ggreer/the_silver_searcher">ag</a> that does the same thing and also tries to avoid files defined in <code>.gitignore</code>. Recently, I’ve often ran into <a href="https://github.com/ggreer/the_silver_searcher/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20label%3Aignore%20">its limitations</a> in <code>.gitignore</code> file support. So I’m switching to two tools.</p>
<h2><a href="https://github.com/BurntSushi/ripgrep"><code>ripgrep</code></a></h2>
<p>A recent player in the field. The <a href="http://blog.burntsushi.net/ripgrep/">introductory blog post</a> got me very interested with the detailed explanation of the code and the benchmarks. It has a way better support for <code>.gitignore</code>. And it’s pretty cool to be using a tool written in <a href="https://www.rust-lang.org">Rust</a>.</p>
<p><del>I’d love if it <a href="https://github.com/BurntSushi/ripgrep/issues/225">supported searching through compressed files</a> out of the box. In the mean time, this command will do the trick, although it can’t take advantage of parallelism:
<code>find . -name "*.gz" -exec gzcat "{}" + | rg "whatever"</code></del></p>
<p><strong>Update:</strong> <code>ripgrep</code> now supports searching in compressed files with the <code>-z/--search-zip</code> option.</p>
<h2><a href="https://git-scm.com/docs/git-grep"><code>git grep</code></a></h2>
<p>This will only work in git repositories of course. Because it is a git tool, it only inspects files in the repository. To make it more convenient, I’ve tweaked it to have the same output than ripgrep.</p>
<ul>
<li><code>--heading</code> prints the filename once before all matches in that file</li>
<li><code>--break</code> puts an empty line before a new file</li>
</ul>
<p>Here’s an extract of my global <code>.gitconfig</code>:</p>
<pre><code class="ini">[alias]
rg = "grep --heading --break -i"
[grep]
lineNumber = true
[color "grep"]
filename = "magenta"
linenumber = "green"
match = "red bold"
</code></pre>
<p>While looking into the documentation to tweak the output, I’ve noticed some interesting options. I don’t use them often but they are nice</p>
<ul>
<li><code>-p</code>: This will try to display the function that the matches are part of. Not very reliable but gives a bit more context sometimes.</li>
<li><code>-O</code>: This will open the matching files in the pager specified. If you set the pager to your code editor, it will open all matching files in your text editor.</li>
</ul>
<div class="footnotes">
<hr />
<ol>
<li id="fn:1">
<p>Yes, <a href="http://jlebar.com/2012/11/28/GNU_grep_is_10x_faster_than_Mac_grep.html">10 times</a> <a href="https://ricaud.me/blog/post/2017/04/Updating-my-code-search-tools#fnref:1" rev="footnote">↩</a></p>
</li>
</ol>
</div>
En recherche d'emploi - Looking for a joburn:md5:47ee327d217541dccc12faa81e8af65a2016-11-22T10:36:00+01:002016-11-22T15:01:02+01:00Anthony Ricaud <p><a href="https://ricaud.me/blog/post/2016/11/Job-search#english-version">English version</a></p>
<p>Je suis à la recherche d'un nouveau poste dans le développement web. Comme pour mes précédents jobs, je recherche une société éditrice de ses produits et non financée par la publicité. J'aimerais intégrer une équipe qui s'interroge régulièrement sur ses méthodes de travail. Idéalement, le télétravail est accepté dans cette entreprise.</p>
<p>Si vous êtes intéressés par mon profil, <a href="http://ricaud.me/cv/">mon CV</a> est disponible. Si vous avez une idée de société qui pourrait m'intéresser, n'hésitez pas à <a href="mailto:anthony@ricaud.me">me contacter</a>.</p>
<hr style="border: 0; border-top: 2px dashed;">
<div lang="en" id="english-version">
<p>I'm looking for a new job in web development. Like previous gigs, I'm looking for a company that works on its own products and with a business model that does not rely on ads. I'd like to be part of a team that regularly questions its methods of working. Ideally, remote work is accepted in that company (I'm staying in France).</p>
<p>If my profile seems interesting, take a look at <a href="http://ricaud.me/cv/">my resume</a>. If you have an idea of a company that might be suitable, please <a href="mailto:anthony@ricaud.me">leave me a note</a></p>
</div>
Code clarityurn:md5:fcf75915656922a6e14cddbf1382ba032016-11-16T11:24:00+01:002016-11-16T11:24:00+01:00Anthony Ricaud <p>Let me tell you a story about code clarity. If you’ve met me, I’ve probably told you this story before.</p>
<p>Back when I was in <a href="http://www.enseirb-matmeca.fr">engineering school</a>, I had some algorithmic courses. The teacher would often ask us how many lines a particular algorithm would take to solve. Some students would take guesses:
- 10?
- No.
- 16?
- No.
- 13?
- No. 3.</p>
<p>The first time we heard that answer, we thought we were in for some very clever solving that we haven’t heard about yet. And then the teacher would write down three function calls. Wait, that didn’t solve anything! They just tricked us. Those three lines don’t accomplish anything, we still need to write the bulk of the work in those functions. And in the end, we’re going to see fifteen to twenty lines so we weren’t far off.</p>
<p>The teacher asked us this question many more times. We were not expecting amazingly short algorithms anymore but we’d still think about solving the whole puzzle when guessing line numbers. And the teacher would never go above five lines for any algorithm.</p>
<p>At the time, we were mocking him. We couldn’t see the value of this way of thinking.</p>
<p>Fast forward now and it is one of the thing I do most when writing code. I’ll take a piece of paper and write the function names I’m going to implement. Or I’ll do it directly in my code editor, with real functions or comments. And I’ll also give that advice to any developer I meet.</p>
<p>It allows you to focus on one problem at a time. When you’re writing those function names, you are thinking about <strong>what</strong> the code should be doing. When you’re implementing the functions, you are thinking about <strong>how</strong> the code should do it. This clarity gives you the best chance to write code that is easy to understand for the next person reading it.</p>
<h2>Team effort, cheap iteration</h2>
<p>Your mind is focused on the problem to solve, on the different ways you could solve it. Once you’ve broken down the problem, you can discuss with your team which solution they’d like to implement. That iteration was pretty cheap because it didn’t take very long to imagine those different solutions. If you come with one solution fully implemented but the team would prefer another one, you might stick to your (less appreciated) implementation because it’s already done. Or the time you spent implementing is lost because now you have to start again.</p>
<p>Once the problem is broken down, you can even share the implementation work for a large task. Thanks to the plan you outlined, everyone is on the same page and will be alright working on their part.</p>
<h2>Not sidetracked until needed</h2>
<p>When you are thinking about the what, you don’t need to focus on the features of the language you are using. You’re barely using the language or maybe even using a pseudo-language. You’re less likely to get sidetracked looking up documentation or Stack Overflow, finding an arcane behaviour of the language, framework or library you’re using. You’re focused on the big picture.</p>
<p>When comes the time for the implementation, you can get stuck and confused. But that’s alright, that won’t distract you from the big picture, it has already been solved.</p>
<h2>Good naming</h2>
<p>As you create your plan to solve a problem, you’ll have to give names to the concepts you’re working with. Because you don’t have the full code to show your team, those names need to explain clearly what is happening if you want them to understand.</p>
<p>Those function or variable names can often replace the need for some comments<sup id="fnref:1"><a href="https://ricaud.me/blog/post/2016/11/Code-clarity#fn:1" rel="footnote">1</a></sup>. The team will think those names clearly express the intent because they’ve agreed to the plan. And when the code evolves, it is more likely for the names in the code to be updated. We’ve all seen comments being completely out-of-date with the code surrounding them.</p>
<h2>Take the time to do it, it’s worth it</h2>
<p>Something I thought was a joke as a student is now one of my favourite tools as a more experienced engineer. As a mentor to new developers on a team<sup id="fnref:2"><a href="https://ricaud.me/blog/post/2016/11/Code-clarity#fn:2" rel="footnote">2</a></sup>, I’ll often ask them to do that work and present it. That often leads to very interesting conversations on the architecture of the project, why we do things in a certain way. You can also easily discuss the benefits and drawbacks of each solution.</p>
<div class="footnotes">
<hr />
<ol>
<li id="fn:1">
<p>I said some comments, not all. <a href="https://ricaud.me/blog/post/2016/11/Code-clarity#fnref:1" rev="footnote">↩</a></p>
</li>
<li id="fn:2">
<p>Juniors or seniors <a href="https://ricaud.me/blog/post/2016/11/Code-clarity#fnref:2" rev="footnote">↩</a></p>
</li>
</ol>
</div>
Marks in Terminal.appurn:md5:6ca96431c409fceed1ec88bc6a3374082015-10-26T14:18:00+01:002016-11-16T19:13:45+01:00Anthony Ricaud <p>For a while after updating to El Capitan, I've seen those weird marks in front of every line. I thought it was an incompatibily with <a href="http://ohmyz.sh">oh-my-zsh</a>. Turns out it isn't and I've discovered that through <a href="https://twitter.com/siracusa/status/657207078600220672">John</a> <a href="https://twitter.com/siracusa/status/657209029794643969">Siracusa</a>.</p>
<p>He links to a <a href="http://apple.stackexchange.com/a/209907">wonderful stack exchange answer</a>. It explains in details what they are and how to change their behaviour, so I won't repeat it here. I just want to highlight the keyboard shortcuts to navigate through them:</p>
<ul>
<li><code>Cmd+Up/Down</code> lets you move up and down between those marks.</li>
<li><code>Cmd+Shift+Up/Down</code> lets you select the text between marks.</li>
</ul>
<p>I found this very convenient to copy/paste the output of a script. Will use a lot.</p>
Une nouvelle aventureurn:md5:5ff273e3ab6579e2ecdaa8aedf8495e52015-06-15T14:45:00+02:002015-06-15T14:45:00+02:00Anthony Ricaud <p>Après cinq ans chez Mozilla, j'ai décidé de partir pour une nouvelle aventure qui débutera le premier août. Je ne sais pas encore où elle sera et c'est pour cela que je publie ce billet.</p>
<p>Je cherche une société qui travaille sur ses propres produits (cela exclut donc les agences) et qui n'est pas financée par de la publicité. Je cherche aussi une équipe qui sait transcender les rôles attitrés, où tout le monde participe pour trouver la solution adéquate.</p>
<p>Si vous êtes intéressés par mon profil, <a href="http://ricaud.me/cv/">mon CV</a> est disponible. Si vous avez une idée de société qui pourrait m'intéresser, n'hésitez pas à <a href="mailto:anthony@ricaud.me">me contacter</a>.</p>
A little performance trick from Amazonurn:md5:85e82089b2477f6923c3e40e7546c1442015-04-28T18:30:00+02:002015-04-28T18:30:00+02:00Anthony Ricaud <p>Have you noticed that Amazon search results feel really really fast? I've noticed that they use a little trick to achieve that. They preload a few results from the next page (6 in my example). So when you click on "Next page", they can display those items immediately and start fetching the other results. On most screens, those preloaded items should be enough to fill the visible viewport. And hopefully, once the user has scanned the first items and is ready to scroll, the rest of the items are loaded.</p>
<iframe width="640" height="480" src="https://www.youtube-nocookie.com/embed/cB_PZ7Q605I?rel=0" frameborder="0" allowfullscreen style="display: block; margin: auto;"></iframe>
<p>I've zoomed out my browser to illustrate the effect in the video.</p>
Electrolysis without tabs underlinedurn:md5:f2f37e2f675a209311a14a4d880c761c2015-04-08T18:45:00+02:002015-04-08T17:59:20+02:00Anthony Ricaud <p>Electrolysis has been re-enabled in Nightly. It brings lots of end-user benefits but it also brings a new style for tabs. I guess this underlining is to help users easily notice the difference with a non-Electrolysis build.</p>
<p>But you can easily disable that:</p>
<ol>
<li><a href="https://support.mozilla.org/kb/profiles-where-firefox-stores-user-data">Locate your profile</a></li>
<li>Go into the chrome directory. You may need to create it if it doesn't exist.</li>
<li>Create a userChrome.css file with the following content:
<pre><code>.tabbrowser-tab[remote] {
text-decoration: none !important;
}</code></pre></li>
<li>Restart your Nightly</li>
<li>Enjoy!</li>
</ol>
<p>Thanks Jonathan Kew for the tip.</p>
Enlever le logo Fnac sur une liseuse Kobourn:md5:8f7c2c4b581fd4aa1984397dcda4fa732015-01-18T12:55:00+01:002015-01-18T13:00:15+01:00Anthony Ricaud <p>En parcourant des forums, je me suis aperçu que la liseuse Kobo pouvait afficher la couverture du livre en cours quand elle est en veille. Mais je ne retrouvais pas cette option dans les réglages. Il s'avère qu'elle est désactivée sur les liseuses vendues par la Fnac. Mais une petite manipulation permet de s'en sortir:</p>
<ol>
<li>Connecter votre liseuse à votre ordinateur</li>
<li>Éditer le fichier .kobo/affiliate.conf</li>
<li>Remplacer fnac par kobo</li>
<li>Sur votre liseuse, vous pourrez configurer Paramètres > Mode veille et alimentation > Économiseur d'écran</li>
</ol>
<p>Il se peut que cela change d'autres comportements de la liseuse mais je n'ai rien lu qui indiquait cela.</p>
Adopting Omnifocus and GTDurn:md5:fb7d322699c1e2d0a82cd6851dd619c12014-07-12T17:06:00+02:002014-07-12T16:07:19+02:00Anthony Ricaud <p>I've tried to adopt the <a href="https://en.wikipedia.org/wiki/Getting_Things_Done">Getting Things Done method</a> a few times already. Every time, it wasn't a success. I wasn't applying most principles and fell back to noting things down on a collection of small papers.
This time, I had a huge advantage: at work, I'm sitting next to <a href="http://sgz.fr/">Étienne</a>, a big proponent of GTD. He inspired me to try again and answered a lot of questions I had during my adoption.</p>
<p>This time, I chose <a href="https://www.omnigroup.com/omnifocus/">Omnifocus</a> for my GTD experimentation. It's a bit expensive to buy the three flavours but I was committed. I'll be talking about my experiences via Omnifocus but you should not focus too much on the software. You can adopt GTD with paper, with another software, whatever works for you.</p>
<h1>Capturing</h1>
<p>In january, I started the capture part. That's when you note down in your GTD system everything you'd like to do. You need to create that habit and do it every time something pops in your head. I use three main methods to collect:</p>
<ol>
<li>When I'm in front of my computer, I use the ^⌥Space shortcut to open the Quick Entry panel</li>
<li>When I'm not in front of my computer, I use the <a href="https://itunes.apple.com/fr/app/omnifocus-2-for-iphone/id690305341">iPod Touch app</a> </li>
<li>When an email requires some action, I send a message to the <a href="http://support.omnigroup.com/omnifocus-mail-drop">mail drop address</a></li>
</ol>
<p>I got a huge inbox but I was ok with it because I knew collecting was the first part to get right. There is a big relief in knowing that everything you need or want to do is explicitly written somewhere. You're not afraid of forgetting something anymore.</p>
<p>Capturing your thoughts like this also allows you to stay focused on the current task. You don't have to do that new task right now, you don't have to explore that idea yet. Just trust the system to remind it to you later.</p>
<p>To start this, you may also want to start by doing a mind sweep: sit down in front of a piece of paper, no distractions, half an hour and write down everything that comes to mind.</p>
<h1>Process</h1>
<p>Once you have this exhaustive list of things you want to do, you process it in contexts and projects. You also flag some items you deem important and put important dates for those tasks. I only started doing this mid january. The tricky part for me was creating the projects and contexts.</p>
<h2>Contexts</h2>
<p>In GTD, Contexts are things you need to achieve a task. It could be a location, a person or an object. I'm not really using the contexts because most of the time, I just need to be in front of my computer to accomplish work related tasks. I may need to tweak this again but for now, I don't feel the need to dive more in that area.</p>
<p>My contexts:</p>
<ul>
<li><strong>Errands</strong>: When I'm neither at home nor at work</li>
<li><strong>Home</strong>: I don't have an office context because I can work from anywhere. I have a few tasks that require me to be in an office (like printing) but not enough to warrant a full context.</li>
<li><strong>People</strong>: A nested list of some people and also a phone context</li>
<li><strong>Technology</strong>: This is where you'll find most of my tasks. I have a nested email folder.</li>
<li><strong>Waiting</strong>: When I'm waiting on something else to happen.</li>
</ul>
<h2>Projects</h2>
<p>Let me give you three example of real projects:</p>
<h3>Fixing a bug</h3>
<p>I try to do this a lot :) So I have a template project that I copy when I intend to work on a bug. This is a sequential project, meaning I need to achieve a task before the next one is available.</p>
<ol>
<li><strong>Find a fix</strong>: Well that sounds dumb but this is my first step</li>
<li><strong>Write tests</strong>: Even though I may write the tests as I fix the problem, I still keep this reminder to make sure I wrote enough tests</li>
<li><strong>Test on a phone</strong>: I will certainly have done this while developing but for small fixes that look obvious, I have been bitten by not testing on a real phone. Hence this reminder.</li>
<li><strong>Put in review</strong>: Uploading my patch and explaining my fix.</li>
<li><strong>Wait for review</strong>: This is in a waiting context so I can forget about this project until I receive an email about that review. If it's not good, I'll add a task for each comment to adress.</li>
<li><strong>Wait for green tests</strong>: In a waiting context too because you shouldn't land something if the tests are not green.</li>
<li><strong>Land patch and clean branches</strong>: When all is good, I can land my work. This is usually where I'll clean the branches I had to create.</li>
<li><strong>Close bug with link to commit</strong>: This is the last step so that people can track the work later.</li>
</ol>
<h3>Feedback on Openweb articles</h3>
<p>The crazy hard worker that <a href="http://www.nicolas-hoffmann.net">Nicolas Hoffmann</a> is <a href="http://openweb.eu.org/articles/les-principes-de-base-en-css">wrote a</a> <a href="http://openweb.eu.org/articles/l-orthogonalite-en-css">few articles</a> <a href="http://openweb.eu.org/articles/prendre-des-conventions-et-les-documenter">on modern</a> <a href="http://openweb.eu.org/articles/les-performances-vues-des-css">CSS practices</a> on the OpenWeb group. I told him I wanted to read them and provide some feedback but I have no idea when I'll come around doing that. So I created one task per article. It's out of my mind but I know I'll do it one day because I have this reminder.</p>
<h3>Birthday ideas</h3>
<p>This is not a project per se. But when someone talks about a topic they like, I try to take a note of it. Then during the review process, I mark it as due a few days before the actual birthday.</p>
<p>In addition to these kinds of projects, I have a few projects called "Work :: Miscelleanous" or "Personal :: Miscelleanous". That's just things I need to do and don't really fit in a project.</p>
<h2>Flags, deferred dates and due dates</h2>
<p>This is how I have things popping up for attention. I try to use due dates as little as possible because otherwise, one day you end up with 10 things urgent to do and you get stuck. So only tasks that have a hard deadline (like filing taxes) get a due date.</p>
<p>I use flags for the tasks that are important but without a real deadline. During my weekly review (see below), I'll flag things that I want to do next week.</p>
<p>The capture phase was really refreshing because I knew everything was stored somewhere. Via the process phase, it's even more relaxing because I know the system will remind me when I need to do something. That completely changed how I think about being overwhelmed. Before, I had this blurry collection of things to do in my head. They were all collapsing and I had no sense of what was important to do or if I was forgetting something that matters to me. Now, when I feel overwhelmed, I know it just means I need to spend a bit of time in front of Omnifocus to process my inbox.</p>
<h1>Review</h1>
<p>In february, I started doing reviews more often. First every two weeks and now every week. This is another step that gives me a great deal of comfort. This is when I'll decide what I want to do next week and put flags or due dates on things that I consider important for the coming week. I will also delete some items that I don't feel like doing anymore.</p>
<h1>Do!</h1>
<p>And this is the biggest part of GTD. Actually doing stuff. If you spend all that time in a tool to organise your tasks, it's not for the sake of it. That's why I did it gradually, to not spend too much time finding the perfect workflow.</p>
<p>I'm really happy with my adoption of the GTD method. It's not perfect, I'm still tweaking here and there.</p>
<p>I encourage you to try it. Reach out to me if you'd like to discuss it, I'd be happy to!</p>
Clinique des navigateurs, devoirs à la maisonurn:md5:b271a44b0be76c63a1e3e24c09edcb9e2012-10-09T16:24:00+02:002013-01-12T20:06:10+01:00Anthony Ricaud <p>Dans moins de deux semaines, j'animerais un atelier <a href="http://www.paris-web.fr/2012/ateliers/clinique-des-navigateurs.php">Clinique des navigateurs</a> à Paris-Web.</p>
<p>Le but de cet atelier est double :</p>
<ul>
<li>Montrer comment obtenir un changement de comportement d'un navigateur.</li>
<li>Récupérer vos retours afin d'améliorer les navigateurs.</li>
</ul>
<p>Chacun y gagne, c'est du win-win comme on dit dans les écoles de business.</p>
<p>Mais pour que cela fonctionne bien, vous allez devoir faire des devoirs à la maison avant de venir. Je vous demande donc de <strong>noter tout ce qui vous dérange dans les navigateurs</strong>. Soit dans un petit document de votre côté, soit dans les commentaires de cet article, soit dans <a href="http://lite.framapad.org/p/clinique-navigateurs">l'etherpad associé</a>, peu importe. Juste un petit gribouillis pour vous rappeler le problème.</p>
<p>Quels genres de problèmes devez-vous noter ? Tout :) Un menu qui n'est pas pratique à utiliser, une lenteur gênante, une fonctionnalité CSS qui ne marche pas, une chose impossible à faire avec les technologies web actuelles.</p>
<p>À samedi prochain !</p>
<p><strong>Update : </strong> J'ai idiotement oublié de préciser qui seront les tuteurs. Nous aurons donc :</p>
<ul>
<li>Karl Dubost : Web Opener chez Opera et ancien W3C <a href="https://twitter.com/karlpro">@karlpro</a></li>
<li>David Rousset : Windows 8 & HTML5 Microsoft Developer Evangelist <a href="https://twitter.com/davrous">@davrous</a></li>
<li>Jérémie Patonnier : Clever Age, contributeur Mozilla <a href="https://twitter.com/jeremiepat">@jeremiepat</a></li>
</ul>
<p>Merci à eux de m'accompagner.</p>My first patch in Geckourn:md5:5f14615a07fe55e2fda07ba17f510ee52012-10-09T15:56:00+02:002013-01-12T20:07:07+01:00Anthony Ricaud <p>A couple of weeks ago, I decided to try and fix a Gecko bug (Gecko is the rendering engine of Firefox). So I hoped onto <a href="http://www.joshmatthews.net/bugsahoy" hreflang="en">the list of mentored bugs</a> and found one that I thought would improve the Web Platform and looked easy enough for my skills. I found this one : <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=570326" hreflang="en">add support for background-size in background shorthand property</a>. Gecko already supports the background-size attribute. But defining it into the background shorthand was not possible. So that was nice: a bit of parsing to change but no layout changes. I can do that. Also, the bug had detailed instructions on which part of the code should be fixed.</p>
<p>So it's now in Nightlies and will go through the various Aurora and Beta releases. It should be available to everyone early 2013.</p>
<p>And with this patch, I've multiplied by ten the lines of C++ I've ever wrote in my life. The <a href="https://bugs.webkit.org/show_bug.cgi?id=18337" hreflang="en">other two lines are in WebKit</a>. Which inspired me this meme:
<img src="https://ricaud.me/images/c++-meme.jpg" alt="I don't always write C++ but when I do, it ships to half a billion users" style="display:block; margin:0 auto;" /></p>
<h2>Other Mozilla bugs</h2>
<p>Just as a reminder because I never blogged about those, here are the other bugs I've worked on in Firefox:</p>
<ul>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=589219" hreflang="en">Bug 589219 - [OS X] Update Close Buttons Appearance</a></li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=633847" hreflang="en">Bug 633847 - White-on-yellow close button is hard to see (missing-plugin infobar).</a></li>
<li><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=689924" hreflang="en">Bug 689924 - Change Inspect shortcut to Cmd+Opt+I</a></li>
</ul>La paralysie du tout parfaiturn:md5:7417870e53db8fad213e342b909a4d622012-01-23T00:52:00+01:002012-01-23T00:52:00+01:00Anthony Ricaud <p>Je souffre de cela. Depuis longtemps, je n'ose pas faire quelque chose si je n'ai pas un certain niveau de confiance. Par exemple, à l'école, je n'écrivais sur ma feuille que ce que je savais juste (ou tout du moins ce que je pensais juste). C'est aussi pour cela que je lisais les énoncés en entier une première fois avant de faire le moindre exercice.</p>
<p>Alors je compulse les avis, la théorie, les termes, etc. Il me faut un savoir quasi-encyclopédique sur le domaine pour me sentir à l'aise au moment de faire un choix. Vous avez pu le remarquer, j'ai déjà demandé l'avis des visiteurs de ce blog deux fois depuis le début de l'année. Je dois être l'un des acheteurs les moins compulsifs qui existe. Je ne peux pas "craquer" pour un produit parce que je ne sais pas si je fais le bon choix.</p>
<p>Je déménage bientôt et je me retrouve dans une situation horrible. J'étais en colocation donc je partage beaucoup de mobilier et d'électroménager. Il me faut faire beaucoup d'achats en peu de temps, le cauchemar. Je ne sais pas où chercher pour avoir au moins un connaissance superficielle de chaque domaine. Pourquoi n'y a-t-il pas des dizaines de sites de test et d'avis, de la même manière que pour le matériel high-tech ?</p>Free Mobile, mon expérienceurn:md5:35766dc46d85930f6dbc02a475521f892012-01-18T00:38:00+01:002012-01-18T00:41:35+01:00Anthony Ricaud <p>(je n'arrive pas à tenir le rythme quotidien, tant pis)</p>
<p>J'étais abonné chez Orange, je n'étais plus engagé, je possède un iPhone 4 et j'ai pris le forfait à 15€99.</p>
<ul>
<li>Inscrit mercredi 11 janvier aux alentours de 8h.</li>
<li>Carte SIM reçue samedi 14 matin.</li>
<li>Carte activée et fonctionnelle samedi 14 soir.</li>
<li>Portabilité effectuée via Orange lundi 16 à 17h, injoignable entre 15h et 17h.</li>
<li>Tous les services sont fonctionnels sauf :
<ul>
<li>Messagerie visuelle</li>
<li>Facetime via la 3G (cela ne marchait pas via Orange non plus)</li>
</ul></li>
<li>Configuration effectuée via http://www.marcvasseur.info/index.php/2012/01/15/configurer-son-iphone-et-freemobile-reglage-de-la-3g/</li>
<li>Le système de hotspot fonctionne très bien.</li>
<li>Les débits et la couverture sont bons sur Paris.</li>
</ul>
<p>Si vous avez des questions particulières, demandez via les commentaires et je mettrais à jour ce billet.</p>f.luxurn:md5:8b2f238ebf1101ea37d02a122c9a2eef2012-01-13T02:23:00+01:002012-01-13T02:23:00+01:00Anthony Ricaud <p>Vous avez déjà remarqué la teinte bleue qu'émet votre écran pendant la nuit ? C'est désagréable et agressif.</p>
<p>Jetez un œil sur <a href="http://stereopsis.com/flux/">f.lux</a>. En fonction de l'heure, il va adapter la teinte de l'écran. En journée, elle sera proche du soleil alors que le soir, elle s'approchera de la teinte d'un halogène ou d'une lampe classique (en fonction de vos réglages).</p>Relancer les soirées performances weburn:md5:0db7dd2ea8b2bd60832578835a977b322012-01-11T02:09:00+01:002012-01-11T02:09:00+01:00Anthony Ricaud <p>Depuis décembre, j'ai repris l'organisation des <a href="https://twitter.com/WebperfParis">soirées parisiennes concernant les performances des sites web</a>. Mon but premier est d'installer un rendez-vous mensuel afin de pérenniser l'événement. Grâce à <a href="https://twitter.com/jeuxweb">JF</a>, nous avons <a href="http://www.webperf-france.net/">un site un peu plus sympa</a> à manipuler que le précédent.</p>
<p>Et la <a href="http://www.webperf-france.net/2012/01/soiree-de-janvier-le-16/">deuxième soirée arrive bientôt</a>.</p>Radio-réveil pour iPhoneurn:md5:f8139933fcb4daf5e6933bf7c9ff12422012-01-10T14:07:00+01:002012-01-10T14:07:00+01:00Anthony Ricaud <p>Je suis en retard sur le billet d'hier, du coup c'est encore toi lecteur qui va travailler.</p>
<p>Je recherche un radio-réveil (donc qui capte la radio et sonne à une heure déterminée) qui fasse aussi dock pour iPhone et qui puisse jouer la musique de l'iPhone. À vous :)</p>