all my open browser tabs
The Worst Things For Sale is Drew's blog. It updates every day. Subscribe to the Worst Things For Sale RSS!
The statement from Chizine neglects a number of salient facts, such as the moment in July 2018, at Necon, when I explained to Brett Savory that my partner was facing a layoff, our cat was ill, we were in severe financial distress, and I had *never* been paid a single cent of royalties in what was at that time almost two years for a moderately successful book. He actually grinned and said, "Things are hard for everyone right now" before walking away. The following morning it was reported to me that Sandra was loudly complaining in the dealer room about me having asked about my royalties, and of course the two of them went on a whirlwind trip around the world a few weeks after that, showing us all that things weren't so rough for them, after all.Kurtz's experience was not isolated.
In fact, I'd asked after my royalties several times and was rebuffed or given excuses every single time (usually something wrong with their accounting software or something similar, which I later learned they’d been saying to authors for years). I only went to the HWA after several other frustrated CZP authors (one of whom hadn't been paid in five years!) strongly encouraged me to do so. I expressed fear of bullying and/or retaliation, and some of these authors promised me they'd have my back (they didn't). And yes, a lot of us got paid through my efforts, though it is untrue I'm paid in full. I was never paid royalties for the months of my first year of publication, 2016, though CZP continues to claim I was. I just gave up on this.
Air travelers cannot receive cash compensation if their flight is delayed by a passenger biting others and assaulting crew members, an adviser at the Court of Justice of the European Union said on Thursday.
Chewy and Miley, both two-year-old Schnauzer dogs, are getting their hair cut at a groomer in Bangkok for the first time since the new coronavirus outbreak began in Thailand in January.
As Thailand's capital cautiously reopens many restaurants shuttered over coronavirus fears, the feline "employees" of the Caturday Cafe are back at work.
Charlie I’Anson’s contract in the third tier has been terminated but the lockdown has left him unable to travel
Charlie I’Anson spent Thursday packing up boxes in the small flat he rents near Madrid, finalising the details of his dismissal from the football club for whom he played, and trying to contact the police to request permission to travel home. The night before, the news slipped out: two months after the last match, and on the day the first and second division players returned to work, the football federation decided to cancel the rest of the season in Spain’s third and fourth tiers. Like thousands of footballers, the English centre-back’s season was over with 10 matches remaining.
Related: Covid-19's impact on football: 'It could take 10 years to get where we were'
Continue reading...Despite rising coronavirus case numbers, the US state of Mississippi is moving out of lockdown and reopening parks, restaurants and other non-essential shops. Oliver Laughland went to the resort of Biloxi to see how residents were responding
The US southern state of Mississippi is the country’s poorest. It went into the coronavirus crisis with high levels of poverty and poor health outcomes. But following the period of lockdown and orders for residents to stay at home, the state’s governor Tate Reeves has eased restrictions - despite evidence that the rate of infections has not yet hit its peak.
The Guardian’s Oliver Laughland travelled to the Mississippi coastal resort of Biloxi where he tells Mythili Rao he found the lockdown has hit hardest those working in low paid jobs in the tourism industry. One restaurant worker describes how the loss of work meant he has had to rely on the charity of his neighbours and local food banks. But despite growing numbers of cases, people are flocking back to the beach and increasingly breaching recommendations of minimum social distancing. The state is reopening, but at what cost?
Continue reading...When a group of schoolboys were marooned on an island in 1965, it turned out very differently from William Golding’s bestseller, writes Rutger Bregman
For centuries western culture has been permeated by the idea that humans are selfish creatures. That cynical image of humanity has been proclaimed in films and novels, history books and scientific research. But in the last 20 years, something extraordinary has happened. Scientists from all over the world have switched to a more hopeful view of mankind. This development is still so young that researchers in different fields often don’t even know about each other.
When I started writing a book about this more hopeful view, I knew there was one story I would have to address. It takes place on a deserted island somewhere in the Pacific. A plane has just gone down. The only survivors are some British schoolboys, who can’t believe their good fortune. Nothing but beach, shells and water for miles. And better yet: no grownups.
Continue reading...Joint statement insists return will not happen until stringent ‘test and trace’ regime in place
Ministers’ plans to reopen schools as early as 1 June are in serious doubt after unions representing teachers and school staff insisted that they would not consider a return without a stringent coronavirus “test and trace” regime.
In an unusual joint statement, which one senior union official said indicated that an early return to a normal school timetable was “off the menu”, the Trades Union Congress said that there should be “no increase in pupil numbers until full rollout of a national test and trace scheme”, and called for the establishment of a Covid-19 taskforce with government, unions and others to agree on the safe reopening of schools.
Continue reading...Epidemiologists use the term to describe tragic excess deaths – but for Covid-19 it seems to be the de facto government policy
There’s a term we use in epidemiology to capture the essence of increases in deaths, or excess mortality, above and beyond normal expectations: “harvesting”. During heatwaves, or a bad season of influenza, additional deaths above what would be normally seen in the population fit this description. Harvesting usually affects older people and those who are already sick. Generally, it is viewed as a tragic, unfortunate, but largely unpreventable consequence of natural events. It carries with it connotations of an acceptable loss of life. It is, in a sense, what happens as part of a normal life in normal times. But the word also has darker connotations: those of sacrifice, reaping, culling. As such, while it may appear in textbooks of epidemiology, it doesn’t occur in national influenza strategic plans or national discourse. The concept of harvesting is restricted to epidemiological circles.
But what if politicians promote the notion of harvesting (while declining to use the term) where it is not a “natural” consequence of events but a direct consequence of government policy? What if the medical and nursing world do not accept harvesting in these circumstances? What if a policy that results in harvesting cannot be articulated because it is unacceptable to the broader population? This is where we have got to with the coronavirus pandemic. Nowhere better exemplifies this tension between a policy and its popular acceptance than the effects of coronavirus in nursing homes.
Continue reading...With states opening even as Covid-19 rages on, the president is rolling the dice on his career – and tens of thousands of lives
On Monday the Republican governor of Nebraska, Pete Ricketts, a close ally of Donald Trump and frequent visitor to the White House, opened his daily coronavirus briefing with a big announcement. “Today is May 4,” he said, “the first day of loosened restrictions statewide.”
With his declaration, Ricketts placed Nebraska at the vanguard of America’s reopening. Churches can now open their doors to worshippers, wedding bells and funeral dirges will be heard once more, hospitals can reschedule elective surgeries, and most Nebraskans will be able to resumehaving their hair cut, nails manicured, bodies massaged and skin tattooed.
Continue reading...[a-RN-au-D] was looking for something fun to do with his son and dreamed up a laser blaster game that ought to put him in the running for father of the year. It was originally just going to be made of cardboard, but you know how these things go. We’re happy …read more
Many studies suggest coronavirus has low transmission rates among children, but there are still risks to reopening schools that were closed due to social distancing policies
Once the coronavirus pandemic is over, we must work out how to stop the spread of poor information that has helped make a bad situation that much worse
At the Springplank school in the Dutch city of Den Bosch, staff have installed plastic shields around students' desks and disinfectant gel dispensers at the doorways as part of preparations to reopen amid the country's coronavirus outbreak. New infections in the Netherlands have been declining for weeks, and the government on Wednesday announced a schedule to relax some of its lockdown measures, with elementary schools to reopen on May 11. "Our teachers are not worried," said Rascha van der Sluijs, the school's technical coordinator.
Leaked letter from shadow minister reveals attempt to impose discipline on top team, writes Iain Watson.
From boosting the economy through to health benefits, Westminster has been talking up the measure.
In states like Texas, malls can operate at a 25% capacity and for some, it's a reason to get out of the house.
The diagnosis comes one day after Trump's personal valet tested positive for the virus.
Andrew's mother was dying in hospital under lockdown, so he used technology to spend time with her.
The situation for schools in Wales will not change on 1 June, the education minister says.
Education unions say they want scientific evidence it is safe for teachers and pupils to return.
Cast and crews might have to quarantine together in the future when filming begins again.
At React Conf 2019 we announced an experimental release of React that supports Concurrent Mode and Suspense. In this post we’ll introduce best practices for using them that we’ve identified through the process of building the new facebook.com.
This post will be most relevant to people working on data fetching libraries for React.
It shows how to best integrate them with Concurrent Mode and Suspense. The patterns introduced here are based on Relay — our library for building data-driven UIs with GraphQL. However, the ideas in this post apply to other GraphQL clients as well as libraries using REST or other approaches.
This post is aimed at library authors. If you’re primarily an application developer, you might still find some interesting ideas here, but don’t feel like you have to read it in its entirety.
If you prefer to watch videos, some of the ideas from this blog post have been referenced in several React Conf 2019 presentations:
This post presents a deeper dive on implementing a data fetching library with Suspense.
The React team and community has long placed a deserved emphasis on developer experience: ensuring that React has good error messages, focusing on components as a way to reason locally about app behavior, crafting APIs that are predictable and encourage correct usage by design, etc. But we haven’t provided enough guidance on the best ways to achieve a great user experience in large apps.
For example, the React team has focused on framework performance and providing tools for developers to debug and tune application performance (e.g. React.memo
). But we haven’t been as opinionated about the high-level patterns that make the difference between fast, fluid apps and slow, janky ones. We always want to ensure that React remains approachable to new users and supports a variety of use-cases — not every app has to be “blazing” fast. But as a community we can and should aim high. We should make it as easy as possible to build apps that start fast and stay fast, even as they grow in complexity, for users on varying devices and networks around the world.
Concurrent Mode and Suspense are experimental features that can help developers achieve this goal. We first introduced them at JSConf Iceland in 2018, intentionally sharing details very early to give the community time to digest the new concepts and to set the stage for subsequent changes. Since then we’ve completed related work, such as the new Context API and the introduction of Hooks, which are designed in part to help developers naturally write code that is more compatible with Concurrent Mode. But we didn’t want to implement these features and release them without validating that they work. So over the past year, the React, Relay, web infrastructure, and product teams at Facebook have all collaborated closely to build a new version of facebook.com that deeply integrates Concurrent Mode and Suspense to create an experience with a more fluid and app-like feel.
Thanks to this project, we’re more confident than ever that Concurrent Mode and Suspense can make it easier to deliver great, fast user experiences. But doing so requires rethinking how we approach loading code and data for our apps. Effectively all of the data-fetching on the new facebook.com is powered by Relay Hooks — new Hooks-based Relay APIs that integrate with Concurrent Mode and Suspense out of the box.
Relay Hooks — and GraphQL — won’t be for everyone, and that’s ok! Through our work on these APIs we’ve identified a set of more general patterns for using Suspense. Even if Relay isn’t the right fit for you, we think the key patterns we’ve introduced with Relay Hooks can be adapted to other frameworks.
It’s tempting to focus only on the total startup time for an app — but it turns out that users’ perception of performance is determined by more than the absolute loading time. For example, when comparing two apps with the same absolute startup time, our research shows that users will generally perceive the one with fewer intermediate loading states and fewer layout changes as having loaded faster. Suspense is a powerful tool for carefully orchestrating an elegant loading sequence with a few, well-defined states that progressively reveal content. But improving perceived performance only goes so far — our apps still shouldn’t take forever to fetch all of their code, data, images, and other assets.
The traditional approach to loading data in React apps involves what we refer to as “fetch-on-render”. First we render a component with a spinner, then fetch data on mount (componentDidMount
or useEffect
), and finally update to render the resulting data. It’s certainly possible to use this pattern with Suspense: instead of initially rendering a placeholder itself, a component can “suspend” — indicate to React that it isn’t ready yet. This will tell React to find the nearest ancestor <Suspense fallback={<Placeholder/>}>
, and render its fallback instead. If you watched earlier Suspense demos this example may feel familiar — it’s how we originally imagined using Suspense for data-fetching.
It turns out that this approach has some limitations. Consider a page that shows a social media post by a user, along with comments on that post. That might be structured as a <Post>
component that renders both the post body and a <CommentList>
to show the comments. Using the fetch-on-render approach described above to implement this could cause sequential round trips (sometimes referred to as a “waterfall”). First the data for the <Post>
component would be fetched and then the data for <CommentList>
would be fetched, increasing the time it takes to show the full page.
There’s also another often-overlooked downside to this approach. If <Post>
eagerly requires (or imports) the <CommentList>
component, our app will have to wait to show the post body while the code for the comments is downloading. We could lazily load <CommentList>
, but then that would delay fetching comments data and increase the time to show the full page. How do we resolve this problem without compromising on the user experience?
The fetch-on-render approach is widely used by React apps today and can certainly be used to create great apps. But can we do even better? Let’s step back and consider our goal.
In the above <Post>
example, we’d ideally show the more important content — the post body — as early as possible, without negatively impacting the time to show the full page (including comments). Let’s consider the key constraints on any solution and look at how we can achieve them:
<CommentList>
being downloaded, for example.This might sound difficult to achieve — but these constraints are actually incredibly helpful. They rule out a large number of approaches and spell out a solution for us. This brings us to the key patterns we’ve implemented in Relay Hooks, and that can be adapted to other data-fetching libraries. We’ll look at each one in turn and then see how they add up to achieve our goal of fast, delightful loading experiences:
One of the most appealing things about the fetch-on-render pattern is that it colocates what data a component needs with how to render that data. This colocation is great — an example of how it makes sense to group code by concerns and not by technologies. All the issues we saw above were due to when we fetch data in this approach: upon rendering. We need to be able to fetch data before we’ve rendered the component. The only way to achieve that is by extracting the data dependencies into parallel data and view trees.
Here’s how that works in Relay Hooks. Continuing our example of a social media post with body and comments, here’s how we might define it with Relay Hooks:
// Post.js
function Post(props) {
// Given a reference to some post - `props.post` - *what* data
// do we need about that post?
const postData = useFragment(graphql`
fragment PostData on Post @refetchable(queryName: "PostQuery") {
author
title
# ... more fields ...
}
`, props.post);
// Now that we have the data, how do we render it?
return (
<div>
<h1>{postData.title}</h1>
<h2>by {postData.author}</h2>
{/* more fields */}
</div>
);
}
Although the GraphQL is written within the component, Relay has a build step (Relay Compiler) that extracts these data-dependencies into separate files and aggregates the GraphQL for each view into a single query. So we get the benefit of colocating concerns, while at runtime having parallel data and view trees. Other frameworks could achieve a similar effect by allowing developers to define data-fetching logic in a sibling file (maybe Post.data.js
), or perhaps integrate with a bundler to allow defining data dependencies with UI code and automatically extracting it, similar to Relay Compiler.
The key is that regardless of the technology we’re using to load our data — GraphQL, REST, etc — we can separate what data to load from how and when to actually load it. But once we do that, how and when do we fetch our data?
Imagine that we’re about to navigate from a list of a user’s posts to the page for a specific post. We’ll need to download the code for that page — Post.js
— and also fetch its data.
Waiting until we render the component has problems as we saw above. The key is to start fetching code and data for a new view in the same event handler that triggers showing that view. We can either fetch the data within our router — if our router supports preloading data for routes — or in the click event on the link that triggered the navigation. It turns out that the React Router folks are already hard at work on building APIs to support preloading data for routes. But other routing frameworks can implement this idea too.
Conceptually, we want every route definition to include two things: what component to render and what data to preload, as a function of the route/url params. Here’s what such a route definition might look like. This example is loosely inspired by React Router’s route definitions and is primarily intended to demonstrate the concept, not a specific API:
// PostRoute.js (GraphQL version)
// Relay generated query for loading Post data
import PostQuery from './__generated__/PostQuery.graphql';
const PostRoute = {
// a matching expression for which paths to handle
path: '/post/:id',
// what component to render for this route
component: React.lazy(() => import('./Post')),
// data to load for this route, as function of the route
// parameters
prepare: routeParams => {
// Relay extracts queries from components, allowing us to reference
// the data dependencies -- data tree -- from outside.
const postData = preloadQuery(PostQuery, {
postId: routeParams.id,
});
return { postData };
},
};
export default PostRoute;
Given such a definition, a router can:
prepare()
function to start loading that route’s data. Note that prepare()
is synchronous — we don’t wait for the data to be ready, since we want to start rendering more important parts of the view (like the post body) as quickly as possible.React.lazy
dynamic import has completed — the component will render and try to access its data. If not, React.lazy
will suspend until the code is ready.This approach can be generalized to other data-fetching solutions. An app that uses REST might define a route like this:
// PostRoute.js (REST version)
// Manually written logic for loading the data for the component
import PostData from './Post.data';
const PostRoute = {
// a matching expression for which paths to handle
path: '/post/:id',
// what component to render for this route
component: React.lazy(() => import('./Post')),
// data to load for this route, as function of the route
// parameters
prepare: routeParams => {
const postData = preloadRestEndpoint(
PostData.endpointUrl,
{
postId: routeParams.id,
},
);
return { postData };
},
};
export default PostRoute;
This same approach can be employed not just for routing, but in other places where we show content lazily or based on user interaction. For example, a tab component could eagerly load the first tab’s code and data, and then use the same pattern as above to load the code and data for other tabs in the tab-change event handler. A component that displays a modal could preload the code and data for the modal in the click handler that triggers opening the modal, and so on.
Once we’ve implemented the ability to start loading code and data for a view independently, we have the option to go one step further. Consider a <Link to={path} />
component that links to a route. If the user hovers over that link, there’s a reasonable chance they’ll click it. And if they press the mouse down, there’s an even better chance that they’ll complete the click. If we can load code and data for a view after the user clicks, we can also start that work before they click, getting a head start on preparing the view.
Best of all, we can centralize that logic in a few key places — a router or core UI components — and get any performance benefits automatically throughout our app. Of course preloading isn’t always beneficial. It’s something an application would tune based on the user’s device or network speed to avoid eating up user’s data plans. But the pattern here makes it easier to centralize the implementation of preloading and the decision of whether to enable it or not.
The above patterns — parallel data/view trees and fetching in event handlers — let us start loading all the data for a view earlier. But we still want to be able to show more important parts of the view without waiting for all of our data. At Facebook we’ve implemented support for this in GraphQL and Relay in the form of some new GraphQL directives (annotations that affect how/when data is delivered, but not what data). These new directives, called @defer
and @stream
, allow us to retrieve data incrementally. For example, consider our <Post>
component from above. We want to show the body without waiting for the comments to be ready. We can achieve this with @defer
and <Suspense>
:
// Post.js
function Post(props) {
const postData = useFragment(graphql`
fragment PostData on Post {
author
title
# fetch data for the comments, but don't block on it being ready
...CommentList @defer
}
`, props.post);
return (
<div>
<h1>{postData.title}</h1>
<h2>by {postData.author}</h2>
{/* @defer pairs naturally with <Suspense> to make the UI non-blocking too */}
<Suspense fallback={<Spinner/>}>
<CommentList post={postData} />
</Suspense>
</div>
);
}
Here, our GraphQL server will stream back the results, first returning the author
and title
fields and then returning the comment data when it’s ready. We wrap <CommentList>
in a <Suspense>
boundary so that we can render the post body before <CommentList>
and its data are ready. This same pattern can be applied to other frameworks as well. For example, apps that call a REST API might make parallel requests to fetch the body and comments data for a post to avoid blocking on all the data being ready.
But there’s one thing that’s still missing. We’ve shown how to preload data for a route — but what about code? The example above cheated a bit and used React.lazy
. However, React.lazy
is, as the name implies, lazy. It won’t start downloading code until the lazy component is actually rendered — it’s “fetch-on-render” for code!
To solve this, the React team is considering APIs that would allow bundle splitting and eager preloading for code as well. That would allow a user to pass some form of lazy component to a router, and for the router to trigger loading the code alongside its data as early as possible.
To recap, achieving a great loading experience means that we need to start loading code and data as early as possible, but without waiting for all of it to be ready. Parallel data and view trees allow us to load the data for a view in parallel with loading the view (code) itself. Fetching in an event handler means we can start loading data as early as possible, and even optimistically preload a view when we have enough confidence that a user will navigate to it. Loading data incrementally allows us to load important data earlier without delaying the fetching of less important data. And treating code as data — and preloading it with similar APIs — allows us to load it earlier too.
These patterns aren’t just ideas — we’ve implemented them in Relay Hooks and are using them in production throughout the new facebook.com (which is currently in beta testing). If you’re interested in using or learning more about these patterns, here are some resources:
We’ve implemented two similar example apps that demonstrate these concepts:
While the APIs around Concurrent Mode and Suspense are still experimental, we’re confident that the ideas in this post are proven by practice. However, we understand that Relay and GraphQL aren’t the right fit for everyone. That’s ok! We’re actively exploring how to generalize these patterns to approaches such as REST, and are exploring ideas for a more generic (ie non-GraphQL) API for composing a tree of data dependencies. In the meantime, we’re excited to see what new libraries will emerge that implement the patterns described in this post to make it easier to build great, fast user experiences.
Velma, Emma and Dean believe mobile phone signals, wi-fi and other modern technology makes them ill.
A car factory worker turned cafe owner explains how coronavirus is affecting his business dream.