dev, low key rss evangelist, ghost without knowing, komencanto, technically a cyborg, generic currency symbol ¤ fangirl, she/her
59 stories

Million, Billion, Trillion

1 Comment and 3 Shares
You can tell most people don’t really assign an absolute meaning to these numbers because in some places and time periods, “billion” has meant 1,000x what it's meant in others, and a lot of us never even noticed.
Read the whole story
1319 days ago
Portland, OR
Share this story
1 public comment
1322 days ago
You can tell most people don’t really assign an absolute meaning to these numbers because in some places and time periods, “billion” has meant 1,000x what it's meant in others, and a lot of us never even noticed.

Faint Signal

1 Share

P2270158 (2)

It’s been a little over a decade since I first saw Clay Shirky lay out his argument about what he called the “cognitive surplus”, but it’s been on my mind recently as I start to see more and more people curtail or sever their investments in always-on social media, and turn their attentions to… something.

Something Else.

I was recently reminded of some reading I did in college, way back in the last century, by a British historian arguing that the critical technology, for the early phase of the industrial revolution, was gin.

The transformation from rural to urban life was so sudden, and so wrenching, that the only thing society could do to manage was to drink itself into a stupor for a generation. The stories from that era are amazing– there were gin pushcarts working their way through the streets of London.

And it wasn’t until society woke up from that collective bender that we actually started to get the institutional structures that we associate with the industrial revolution today. Things like public libraries and museums, increasingly broad education for children, elected leaders–a lot of things we like–didn’t happen until having all of those people together stopped seeming like a crisis and started seeming like an asset.

It wasn’t until people started thinking of this as a vast civic surplus, one they could design for rather than just dissipate, that we started to get what we think of now as an industrial society.

– Clay Shirky, “Gin, Television and the Cognitive Surplus“, 2008.


I couldn’t figure out what it was at first – people I’d thought were far enough ahead of the curve to bend its arc popping up less often or getting harder to find; I’m not going to say who, of course, because who it is for me won’t be who it is for you. But you feel it too, don’t you? That quiet, empty space that’s left as people start dropping away from hyperconnected. The sense of getting gently reacquainted with loneliness and boredom as you step away from the full-court vanity press and stop synchronizing your panic attacks with the rest of the network. The moment of clarity, maybe, as you wake up from that engagement bender and remember the better parts of your relationship with absence and distance.

How, on a good day, the loneliness set your foot on the path, how the boredom could push you to push yourself.

I was reading the excellent book MARS BY 1980 in bed last night and this term just popped into my head as I was circling sleep. I had to do that thing where you repeat it in your head twenty times so that I’d remember it in the morning. I have no idea what refuture or refuturing really means, except that “refuturing” connects it in my mind with “rewilding.” The sense of creating new immediate futures and repopulating the futures space with something entirely divorced from the previous consensus futures.

Refuture. Refuturing. I don’t know. I wanted to write it down before it went away.

Which I guess is what we do with ideas about the future anyway.

Warren Ellis, August 21, 2018.

Maybe it’s just me. I can’t quite see the shape of it yet, but I can hear it in the distance, like a radio tuned to a distant station; signal in the static, a song I can’t quite hear but I can tell you can dance to. We still have a shot, despite everything; whatever’s next is coming.

I think it’s going to be interesting.

Read the whole story
1349 days ago
Portland, OR
Share this story

Lesson #3548 - Class Dismissed

1 Comment

Thank you, first and foremost, to theSwede. When I told you I wanted and needed to do some creative work, over a decade ago, you simply said "Okay" and were nothing but supportive. None of this would exist without you. Thank you as well to both Cannonball and Torpedo. Someday you'll be old enough to read these, and I hope you find them all as enjoyable, meaningful, and as embarrassing as they are/were intended to be.

Thank you to Mom, Dad, Hanna, Emma, my grandparents, all extended family, for giving me the experiences, insight, and humor that crafted STW. Thank you Mitch, Donna, and all for their support as well. Thank you to so many friends, innumerable to name. Your support has meant everything.

Thank you to classmates, advisors, and colleagues from the past 10 years at Cornell, NIST, and Northeastern, particularly to those who never found out about STW when it needed to remain a professional secret, and just as particularly to those who were in full support and encouragement when the secret came out. Thank you to so many students, but especially everyone from the NU ChemE class of 2015, who I am ever indebted to.

Thank you to so many in the comics/creative community, especially Danielle Corsetto, Jon Rosenberg, Joan Cooke, Christopher Moore, Jessica Hagy, Holly and Jeffrey Rowland, Sara McHenry, Gary Tyrrell, Zach and Kelly Weinersmith, Matt Lubchansky, Monica Keszler, Ryan Walsh, every artist I have collaborated with, so so so many others. Thank you for all that you have done to bring me into your world, and for all that you have done for my career.

It's been a very long time since I worked there, but thank you as well to Three Point for all those experiences at creative writing that almost certainly led to the creation of STW.

Thank you to Westley, Sprite, Wakefield, Shiv, and Bitey, too. Why not.

And finally, thank you to all of you kind readers. For however long you have read STW, thank you. I am so incredibly humbled by your support and kindness and so incredibly grateful for all that you have given to STW as well. I wish all of you whatever joy and happiness that you deserve.

STW ran for 10+ years and 3500+ comics. It's as much yours as it is mine, now.

Thank you all, so harking much.

Read the whole story
1503 days ago
What a beautiful run. Thank you.
Portland, OR
Share this story

Inside a super fast CSS engine: Quantum CSS (aka Stylo)

1 Comment

You may have heard of Project Quantum… it’s a major rewrite of Firefox’s internals to make Firefox fast. We’re swapping in parts from our experimental browser, Servo, and making massive improvements to other parts of the engine.

The project has been compared to replacing a jet engine while the jet is still in flight. We’re making the changes in place, component by component, so that you can see the effects in Firefox as soon as each component is ready.

And the first major component from Servo—a new CSS engine called Quantum CSS (previously known as Stylo)—is now available for testing in our Nightly version. You can make sure that it’s turned on for you by going to about:config and setting layout.css.servo.enabled to true.

This new engine brings together state-of-the-art innovations from four different browsers to create a new super CSS engine.

4 browser engines feeding in to Quantum CSS

It takes advantage of modern hardware, parallelizing the work across all of the cores in your machine. This means it can run up to 2 or 4 or even 18 times faster.

On top of that, it combines existing state-of-the-art optimizations from other browsers. So even if it weren’t running in parallel, it would still be one fast CSS engine.

Racing jets

But what does the CSS engine do? First let’s look at the CSS engine and how it fits into the rest of the browser. Then we can look at how Quantum CSS makes it all faster.

What does the CSS engine do?

The CSS engine is part of the browser’s rendering engine. The rendering engine takes the website’s HTML and CSS files and turns them into pixels on the screen.

Files to pixels

Each browser has a rendering engine. In Chrome, it’s called Blink. In Edge, it’s called EdgeHTML. In Safari, it’s called WebKit. And in Firefox, it’s called Gecko.

To get from files to pixels, all of these rendering engines basically do the same things:

  1. Parse the files into objects the browser can understand, including the DOM. At this point, the DOM knows about the structure of the page. It knows about parent/child relationships between elements. It doesn’t know what those elements should look like, though.Parsing the HTML into a DOM tree
  2. Figure out what the elements should look like. For each DOM node, the CSS engine figures out which CSS rules apply. Then it figures out values for each CSS property for that DOM node.Styling each DOM node in the tree by attaching computed styles
  3. Figure out dimensions for each node and where it goes on the screen. Boxes are created for each thing that will show up on the screen. The boxes don’t just represent DOM nodes… you will also have boxes for things inside the DOM nodes, like lines of text.Measuring all of the boxes to create a frame tree
  4. Paint the different boxes. This can happen on multiple layers. I think of this like old-time hand drawn animation, with onionskin layers of paper. That makes it possible to just change one layer without having to repaint things on other layers.Painting layers
  5. Take those different painted layers, apply any compositor-only properties like transforms, and turn them into one image. This is basically like taking a picture of the layers stacked together. This image will then be rendered on the screen.Assembling the layers together and taking a picture

This means when it starts calculating the styles, the CSS engine has two things:

  • a DOM tree
  • a list of style rules

It goes through each DOM node, one by one, and figures out the styles for that DOM node. As part of this, it gives the DOM node a value for each and every CSS property, even if the stylesheets don’t declare a value for that property.

I think of it kind of like somebody going through and filling out a form. They need to fill out one of these forms for each DOM node. And for each form field, they need to have an answer.

Blank form with CSS properties

To do this, the CSS engine needs to do two things:

  • figure out which rules apply to the node — aka selector matching
  • fill in any missing values with values from the parent or a default value—aka the cascade

Selector matching

For this step, we’ll add any rule that matches the DOM node to a list. Because multiple rules can match, there may be multiple declarations for the same property.

Person putting check marks next to matching CSS rules

Plus, the browser itself adds some default CSS (called user agent style sheets). How does the CSS engine know which value to pick?

This is where specificity rules come in. The CSS engine basically creates a spreadsheet. Then it sorts the declarations based on different columns.

Declarations in a spreadsheet

The rule that has the highest specificity wins. So based on this spreadsheet, the CSS engine fills out the values that it can.

Form with some CSS properties filled in

For the rest, we’ll use the cascade.

The cascade

The cascade makes CSS easier to write and maintain. Because of the cascade, you can set the color property on the body and know that text in p, and span, and li elements will all use that color (unless you have a more specific override).

To do this, the CSS engine looks at the blank boxes on its form. If the property inherits by default, then the CSS engine walks up the tree to see if one of the ancestors has a value. If none of the ancestors have a value, or if the property does not inherit, it will get a default value.

Form will all CSS properties filled in

So now all of the styles have been computed for this DOM node.

A sidenote: style struct sharing

The form that I’ve been showing you is a little misrepresentative. CSS has hundreds of properties. If the CSS engine held on to a value for each property for each DOM node, it would soon run out of memory.

Instead, engines usually do something called style struct sharing. They store data that usually goes together (like font properties) in a different object called a style struct. Then, instead of having all of the properties in the same object, the computed styles object just has pointers. For each category, there’s a pointer to the style struct that has the right values for this DOM node.

Chunks of the form pulled out to separate objects

This ends up saving both memory and time. Nodes that have similar properties (like siblings) can just point to the same structs for the properties they share. And because many properties are inherited, an ancestor can share a struct with any descendants that don’t specify their own overrides.

Now, how do we make that fast?

So that is what style computation looks like when you haven’t optimized it.

Steps in CSS style computation: selector matching, sorting by specificity, and computing property values

There’s a lot of work happening here. And it doesn’t just need to happen on the first page load. It happens over and over again as users interact with the page, hovering over elements or making changes to the DOM, triggering a restyle.

Initial styling plus restyling for hover, DOM nodes added, etc

This means that CSS style computation is a great candidate for optimization… and browsers have been testing out different strategies to optimize it for the past 20 years. What Quantum CSS does is take the best of these strategies from different engines and combine them to create a superfast new engine.

So let’s look at the details of how these all work together.

Run it all in parallel

The Servo project (which Quantum CSS comes from) is an experimental browser that’s trying to parallelize all of the different parts of rendering a web page. What does that mean?

A computer is like a brain. There’s a part that does the thinking (the ALU). Near that, there’s some short term memory (the registers). These are grouped together on the CPU. Then there’s longer term memory, which is RAM.

CPU with ALU (the part that does the thinking) and registers (short term memory)

Early computers could only think one thing at a time using this CPU. But over the last decade, CPUs have shifted to having multiple ALUs and registers, grouped together in cores. This means that the CPU can think multiple things at once — in parallel.

CPU chip with multiple cores containing ALUs and registers

Quantum CSS makes use of this recent feature of computers by splitting up style computation for the different DOM nodes across the different cores.

This might seem like an easy thing to do… just split up the branches of the tree and do them on different cores. It’s actually much harder than that for a few reasons. One reason is that DOM trees are often uneven. That means that one core will have a lot more work to do than others.

Imbalanced DOM tree being split between multiple cores so one does all the work

To balance the work more evenly, Quantum CSS uses a technique called work stealing. When a DOM node is being processed, the code takes its direct children and splits them up into 1 or more “work units”. These work units get put into a queue.

Cores segmenting their work into work units

When one core is done with the work in its queue, it can look in the other queues to find more work to do. This means we can evenly divide the work without taking time up front to walk the tree and figure out how to balance it ahead of time.

Cores that have finished their work stealing from the core with more work

In most browsers, it would be hard to get this right. Parallelism is a known hard problem, and the CSS engine is very complex. It’s also sitting between the two other most complex parts of the rendering engine — the DOM and layout. So it would be easy to introduce a bug, and parallelism can result in bugs that are very hard to track down, called data races. I explain more about these kinds of bugs in another article.

If you’re accepting contributions from hundreds or thousands of engineers, how can you program in parallel without fear? That’s what we have Rust for.

Rust logo

With Rust, you can statically verify that you don’t have data races. This means you avoid tricky-to-debug bugs by just not letting them into your code in the first place. The compiler won’t let you do it. I’ll be writing more about this in a future article. In the meantime, you can watch this intro video about parallelism in Rust or this more in-depth talk about work stealing.

With this, CSS style computation becomes what’s called an embarrassingly parallel problem — there’s very little keeping you from running it efficiently in parallel. This means that we can get close to linear speed ups. If you have 4 cores on your machine, then it will run close to 4 times faster.

Speed up restyles with the Rule Tree

For each DOM node, the CSS engine needs to go through all of the rules to do selector matching. For most nodes, this matching likely won’t change very often. For example, if the user hovers over a parent, the rules that match it may change. We still need to recompute style for its descendants to handle property inheritance, but the rules that match those descendants probably won’t change.

It would be nice if we could just make a note of which rules match those descendants so we don’t have to do selector matching for them again… and that’s what the rule tree—borrowed from Firefox’s previous CSS engine— does.

The CSS engine will go through the process of figuring out the selectors that match, and then sorting them by specificity. From this, it creates a linked list of rules.

This list is going to be added to the tree.

A linked list of rules being added to the rule tree

The CSS engine tries to keep the number of branches in the tree to a minimum. To do this, it will try to reuse a branch wherever it can.

If most of the selectors in the list are the same as an existing branch, then it will follow the same path. But it might reach a point where the next rule in the list isn’t in this branch of the tree. Only at that point will it add a new branch.

The last item in the linked list being added to the tree

The DOM node will get a pointer to the rule that was inserted last (in this example, the div#warning rule). This is the most specific one.

On restyle, the engine does a quick check to see whether the change to the parent could potentially change the rules that match children. If not, then for any descendants, the engine can just follow the pointer on the descendant node to get to that rule. From there, it can follow the tree back up to the root to get the full list of matching rules, from most specific to least specific. This means it can skip selector matching and sorting completely.

Skipping selector matching and sorting by specificity

So this helps reduce the work needed during restyle. But it’s still a lot of work during initial styling. If you have 10,000 nodes, you still need to do selector matching 10,000 times. But there’s another way to speed that up.

Speed up initial render (and the cascade) with the style sharing cache

Think about a page with thousands of nodes. Many of those nodes will match the same rules. For example, think of a long Wikipedia page… the paragraphs in the main content area should all end up matching the exact same rules, and have the exact same computed styles.

If there’s no optimization, then the CSS engine has to match selectors and compute styles for each paragraph individually. But if there was a way to prove that the styles will be the same from paragraph to paragraph, then the engine could just do that work once and point each paragraph node to the same computed style.

That’s what the style sharing cache—inspired by Safari and Chrome—does. After it’s done processing a node, it puts the computed style into the cache. Then, before it starts computing styles on the next node, it runs a few checks to see whether it can use something from the cache.

Those checks are:

  • Do the 2 nodes have the same ids, classes, etc? If so, then they would match the same rules.
  • For anything that isn’t selector based—inline styles, for example—do the nodes have the same values? If so, then the rules from above either won’t be overridden, or will be overridden in the same way.
  • Do both parents point to the same computed style object? If so, then the inherited values will also be the same.

Computed styles being shared by all siblings, and then asking the question of whether a cousin can share. Answer: yes

Those checks have been in earlier style sharing caches since the beginning. But there are a lot of other little cases where styles might not match. For example, if a CSS rule uses the :first-child selector, then two paragraphs might not match, even though the checks above suggest that they should.

In WebKit and Blink, the style sharing cache would give up in these cases and not use the cache. As more sites use these modern selectors, the optimization was becoming less and less useful, so the Blink team recently removed it. But it turns out there is a way for the style sharing cache to keep up with these changes.

In Quantum CSS, we gather up all of those weird selectors and check whether they apply to the DOM node. Then we store the answers as ones and zeros. If the two elements have the same ones and zeros, we know they definitely match.

A scoreboard showing 0s and 1s, with the columns labeled with selectors like :first-child

If a DOM node can share styles that have already been computed, you can skip pretty much all of the work. Because pages often have many DOM nodes with the same styles, this style sharing cache can save on memory and also really speed things up.

Skipping all of the work


This is the first big technology transfer of Servo tech to Firefox. Along the way, we’ve learned a lot about how to bring modern, high-performance code written in Rust into the core of Firefox.

We’re very excited to have this big chunk of Project Quantum ready for users to experience first-hand. We’d be happy to have you try it out, and let us know if you find any issues.

Read the whole story
1808 days ago
Fantastic explainer!
Portland, OR
Share this story

Lesson #3209 - Bees

1 Share

I told all of my professorial colleagues in a departmental retreat today that if I had been making comics under my real name and not under a pseudonym, I would never have gotten the job I had. In consideration of this comic, I stand by that statement.

Read the whole story
1871 days ago
Portland, OR
Share this story

RotterZwam: Abandoned Water Park Turned Indoor Mushroom Farm

1 Comment
[ By SA Rogers in Abandoned Places & Architecture. ]

Bags of old coffee grounds hang in the dank dressing rooms of an abandoned Rotterdam water park, growing oyster mushrooms. Two men turned the former Tropicana space, an old teen hangout, into the perfect damp, dim environment for their business, making use of the structure while the city council decides what to do with it. ‘RotterZwam’ rents the building on an anti-squat lease and have transformed it into a fascinating example of adaptive reuse and urban farming.

Tropicana is fairly infamous among Rotterdam locals, but closed after the former owner went bankrupt in 2010. The space had been plagued with problems, from hygiene to sexual assault. It sat empty until Siemen Cox and mark Slegers, RotteZwam’s owners, realized it looked like a giant greenhouse.

Though they hope that central glassed-in space – formerly the pool – will eventually become a greenhouse, for now, they’re making use of the dressing rooms and basement, which offer ideal conditions for fungal growth. The crew hangs bags of coffee grinds from the old Tropicana clothes hangers, and before long, they sprout oyster mushrooms.

They collect the coffee from local cafes, transport it in their carrier bicycle, and give the compost to worms to create an extremely low-waste operation. The produce about 20-50kg of mushrooms every week, and sell it to local restaurants, bakeries and food trucks. They also offer DIY mushroom-growing kits.

“Cities like Rotterdam produce nothing but waste and commuters,” they say in an interview with Vice’s Munchies. “This entertainment park represents that perfectly – we build things and, when we don’t want them anymore, we need others to clean it up, to sweep up our garbage. That’s not how nature works, though – in nature wast doesn’t exist. In this building we hardly ever buy a thing, because eery material or nail is already here.”

Share on Facebook

[ By SA Rogers in Abandoned Places & Architecture. ]

[ WebUrbanist | Archives | Galleries | Privacy | TOS ]

Read the whole story
1928 days ago
This is incredible!
Portland, OR
Share this story
Next Page of Stories