Tumgik
#if i reuse them no one mention it ok. multiple people can have the same name it's fine
ibis-gt · 3 years
Text
Poker Night
dippin my toes in the writing pool again with a short one about anya and felipe! there’s a bunch of side characters in this one that i just now made up so don’t worry if you have no idea who they are, i don’t either skdjfklsf
just under 2.5k words, kind of hurt/comfort. warnings: fearplay, threats of violence, bullying, peer pressure, felipe not having a very good time at all
Felipe looked around at the five giants seated at the table he was currently sitting on and forced a smile. Once again, Anya asked him to come along to one of the parties her friend Emily often hosted, and once again she’d dropped him off at the husbands’ table while she caught up with her friends. Quite literally dropped him off, plucking him off her shoulder and depositing him on the wooden tabletop with a “Play nice, fellas!” as she waltzed off.
Usually, they did play nice - Anya was built like a brick shithouse and would defend her tiny human husband with every ounce of strength she had. But tonight there’d clearly been some drink passed around, and now the five giants eyed Felipe with varying levels of displeasure. Seth glared at him with annoyance, Rolf looked bored and disinterested, Leo seemed resigned to essentially babysitting the tiny man, Amos heaved a sigh and rolled his eyes, but it was Bruno that really worried Felipe. Bruno was staring down at him with a mostly blank expression, but Felipe could see gears turning in his head, and he could tell it was going to come out to trouble.
He jumped as Bruno suddenly clapped his hands together, beaming brightly.
“Who’s up for a game of cards?” Bruno produced a deck from his pocket and began to shuffle them. The others took an interest, nodding their approval.
That took Felipe by surprise. It sounded harmless enough. “Yeah, that sounds like fun. Uh, don’t know if I’ll be able to play, though.” The cards were probably as big as he was, and he could maybe hold onto two at a time. Any more than that, and there would be serious delays as he figured out what to play. “Oh, don’t worry, I know how you can participate,” Bruno assured him. This was not, however, reassuring.
He dealt out a hand to each of the giants at the table, then began sorting out a set of huge wooden chips. Each one was about two feet in diameter. They had different colors and markings to indicate their value, but Felipe wasn’t sure which one meant what, and no one seemed like they were about to explain it to him. 
Felipe shuffled his feet and glanced around nervously. He hadn’t been dealt a hand, and he didn’t know what Bruno had in mind, but he didn’t think it would be all that fun for him. His suspicions were proved right when Bruno tossed a few chips in the middle to start the betting, then grabbed him by the back of his shirt and dropped him next to them. Felipe let out a quiet grunt as he hit the table and looked up in confusion. A few of the giants seemed to have caught on and were grinning down at him, but for the ones who were slower on the uptake, Bruno announced, “You’ll be one of the chips, of course.”
Felipe sat bolt upright and stared at him wide-eyed. Then he laughed nervously, trying to calm himself down. “Oh, haha, good joke! No, but seriously. What am I...” he trailed off, turning from side to side to see their faces.
Silence. Everyone stared at him. Some were still grinning, some were serious. Leo spoke up.
“C’mon, Bruno, you know Anya wouldn’t like that. Just let him sit it out.”
“Oh, lighten up,” Bruno grumbled. “It’s not like she’s gonna find out, is she?” He looked around the table, getting a head shake ‘no’ or a shrug from each in turn, then down at Felipe. “Is she?” he asked again.
“Uh…” Words failed him. He wanted to say yes, emphatically yes, he’d squeal at the first opportunity, and in fact he was going to stand up and start waving his arms and shouting right now to get her attention. But truth be told, Felipe was terrified. Everyone had been drinking and he didn’t know how deep in their cups they all were. Who knows what they’d do if he didn’t go along with it? Maybe if he was quiet and played along, they’d get bored and leave him alone. “...no, sure, she won’t. Ha.”
“Good,” Bruno said, giving him a smile that was not in the least bit comforting. “Then let’s start.” He threw in a few of his own chips. The others followed suit, betting based on whatever combination of cards they had. Felipe flinched every time a chip hit the table. They were being careful - none of the tossed chips hit him, but they landed close enough to worry him. He hunched his shoulders and tried to make himself as small as possible.
Bruno won the first round. He grinned that awful grin again and reached out, putting both hands around the stack of chips and pulling them in close. Felipe, still seated, was dragged along with them, back pressed up against the palm of Bruno’s left hand, trying to resist the urge to his feet and push back.
“Hi,” Bruno said, looking down at him. A few of the others chuckled.
“H-hi,” Felipe stammered, forcing a smile. “Uh, so, what - ”
“Chips don’t talk,” Bruno interrupted, and started dealing out the next round of cards. Felipe shut his mouth and hunkered down, hoping Bruno wouldn’t get any good hands. He was lucky for one round, and Bruno only tossed in two chips before folding. The next round, though, Felipe’s luck ran out. Bruno glanced at his cards and the corner of his mouth went up just a little. He tossed in four chips, then snagged the back of Felipe’s shirt again and dropped him down in the middle. Rolf whistled and looked at his own cards, tapping a chip thoughtfully on the table.
“How much is he worth?” Rolf asked. “Like, how do I meet or raise or whatever?”
“I don’t care,” Bruno said. “Whatever you think he’s worth.”
Rolf threw in six chips. Felipe wasn’t sure if he should be offended or flattered.
Seth ended up taking the hand, and as soon as he slapped his cards down in triumph, Felipe scrambled to his feet and jogged over to him, not wanting to be pushed across the table again. There was a snort of laughter from one of the other giants but he paid it no mind. Seth raked in the chips then looked down at Felipe, tilting his head to one side, seeming to appraise him. Then he gave a horrid grin of his own and pinned Felipe down with a thumb on his chest.
“Ain’t chips supposed to be flat? So you can stack ‘em?” he asked, clearly thinking he was being clever. “Should I…” The pressure increased slightly, and Felipe began to panic and struggle, trying to get himself out from under the thumb.
“Cut it out,” Bruno growled. “You hurt him and Anya’ll have our asses.”
The pressure disappeared as the thumb lifted up and away. Felipe got to his feet and backed away from Seth, eyes fixed on the giant. He felt like his knees were going to give out. Being meek and quiet hadn’t helped one bit, but now he couldn’t find his voice to call out for help. His throat was dry and tight from terror and it felt like his heart was lodged in it. Seth scowled at him and poked his chest with a finger, knocking him on his back.
“Go on,” he grumbled. “I’m bettin’ you. Hope I lose.”
Lose he did. Leo took that hand. He didn’t look too happy about it, either. “Well, come on then,” he sighed, and Felipe managed to stand on his shaking legs and wobble over. Felipe looked up at him with wide, hopeful eyes. Leo was the least happy with this setup, other than Felipe himself. Maybe he’d speak up now that he had him and could put an end to the whole thing. But Leo didn’t meet his eyes, just picked up his next hand and tossed a few chips in. Okay, next best thing, Leo never bet him and he could stay put and as far away from Bruno as possible. And Seth. Actually, just all of them.
Leo only managed to hold onto him for two hands before Bruno spoke up.
“Don’t get greedy, now,” he called. “Let us have a shot at him, too.”
Leo sighed and finally glanced down at Felipe again. “Okay, you heard him,” he said. “Get.”
Felipe got. Rolf won. Then Amos. Then Bruno. Then Bruno again. Each time, he’d slap his cards down as he reached for the chips, not giving Felipe time to register his victory. He seemed to delight in pushing the little man around and didn’t like it when Felipe tried to walk himself over to whoever had won him that time. Unfortunately he seemed to be the best at the game they were playing, with an impeccable poker face and a decent winning streak. Since he was also the dealer, Felipe half suspected he was cheating, but he lost often enough not to irk anyone else at the table. Bruno started to play with him whenever he had him. He’d dangle him by the back of his shirt and gently swing him back and forth, or pin him under his palm and drum his fingers on the table. Once he even picked Felipe up and began to toss him up in the air and catch him, not very high, but enough to get a frightened yelp out of him. Bruno seemed to think that might draw too much attention, though, and quickly set Felipe back down, shaking like a leaf and trying not to hyperventilate.
Rolf looked about as uncomfortable as Leo had when he won Felipe for the first time. Felipe caught him glancing at Leo and looked up at the giant too, but the combined effort of their stares still couldn’t persuade Leo to speak up, and Rolf didn’t seem to have the nerve to try on his own. Felipe changed hands a few more times before ending up with Bruno yet again. At this point he was fighting back tears. He desperately wished they’d get bored and give it up already, but it seemed pride was on the line for Seth and Amos, and Bruno was enjoying himself immensely. Felipe’s mind started to wander towards what would happen when the game was over for good. What would whoever had won him do? Would they try to take him home? Stuff him in a pocket or a cupboard for later? Or would they make him do something public and embarrassing? More embarrassing than being reduced to a literal object to be passed around, that is.
Just then, his saving grace appeared. He practically melted with relief as he heard Anya’s voice.
“Hey, y’all, what’re you up to? Where’s Felipe?” She caught sight of him and smiled. Despite how terrified he was, his heart sang out at the sight of her. She was still the most beautiful woman he’d ever seen. The others shifted nervously in their seats and glanced at each other, except for Bruno and Leo. Leo’s eyes were locked on Bruno and his face was grim. Bruno looked at Anya with his perfect poker face intact, although he was betrayed slightly by a small trickle of sweat down the side of his face.
Anya took in the scene and started to pick up on the energy at the table. Her smile started to fade. “No cards for you, honey?” She asked Felipe. “Are you helping Bruno, then? I’ll tell ya right now he doesn’t need it. He’s just about the best player here.” She looked around at everyone and then back at Bruno. She looked at the chips on the table all around Felipe, took in his posture, his expression, the way he was trembling ever so slightly. Her smile was completely gone now, and she set her jaw. When she spoke again, her voice was flat. “He’s not helping you, is he. He’s not playing at all.” 
Anya held out her hand palm up to Felipe, and he nearly tripped over his own feet sprinting across the table towards her. He leapt into her palm and wrapped his arms around her thumb, pressing his forehead to the tip. “Thankyou thankyou thankyou thankyou,” he gasped, his fragile facade of calm completely gone. The tears started to flow and he let them. Who cared anymore. He was safe, he was with his wife, the whole rest of the world could go to hell.
“You sons of bitches,” she spat. “I can’t believe you - ”
“Anya,” Felipe squeaked, and she held him up, her face instantly softening. “Let’s just go. Please.”
She looked like she was going to argue, but instead she shot a look at the cowering, ashamed giants, and stalked off. She headed for the exit, putting a hand on her friend Emily’s shoulder on the way.
“You set your husband right before I do it for you,” she warned. Emily spun around to glare at the husbands’ table.
“What kind of bullshit did you pull this time, Bruno?” Emily called, just as Anya slipped out the door, Felipe held to her chest.
She put a fair amount of distance between them and the house before lifting him up close to her face so she could see him better, the light dimming as evening approached.
“Honey? Are you okay? Do you want me to drop you off at the house and go back and kick their asses?”
Felipe managed a strangled laugh through his tears. “No, no, I don’t care. It doesn’t matter,” he lied. “I just want to forget it all.” That bit was true enough. He was so embarrassed by the whole thing. He wanted to pretend like it had never happened.
“I’m so sorry, I should never have left you with those idiots. I knew they’d be drinking, too, and Bruno always gets that mean glint in his eye when he drinks…”
“Wasn’t your fault,” Felipe said, sniffing and wiping his nose on his shirt. “They were just being dicks.”
“Did they hurt you? Because I’ll tell you right now if they did, I swear I’ll - ”
“No, no, they didn’t. And I’m not just saying that so you won’t go twist ‘em into pretzels. I’m fine, really.”
Anya gave him a Look. She rubbed his back with her thumb, working the tension out of him bit by bit. “I believe you that they didn’t hurt you physically,” she said softly. “But I don’t believe you’re fine. You were shaking like a leaf, honey. They scared you. You can admit it. There were five of them, they’re several times your size and could’ve snapped you like a twig without thinking about it.” He shivered, dropping his gaze. “Yeah, that’s what I thought. I’m never leaving you alone with them again. You poor thing. Let’s get you home.”
61 notes · View notes
starfast · 3 years
Text
So you want to write an autistic character
So I watched the trailer for Sia’s movie just to see if it really was that bad. Spoiler alert: Yes it is. It made me feel like Sia was making fun of me for two and a half minutes. But it also made me really fucking angry because there’s not autism representation to begin with, and most of what we do have isn’t really that great, which is what drove me to make this post. I don’t have many followers so even if like 3 people see this, then at least that’s 3 people who have seen this.  
What would I like to see less of
Literally incapable of detecting sarcasm: “Wait,” you say, “But Starfast, there are autistic people out there who are like this!” Sure, there might be, but for me personally detecting sarcasm is a lot less difficult than literally every autistic character has made it out to be. Yes, there are times where it goes right over my head but those times are usually when there’s not enough context for me to figure out whether the person is being sarcastic or not. Some of us actually are able to tell when you’re being sarcastic, it usually depends on context.
The “Sheldon Cooper”:  Autism is really diverse and yet I feel like 99% of autistic characters are basically all just carbon copies of Sheldon Cooper from BBT. They’re maybe overly formal, blunt, or have a hard time picking up social cues. And while these are all things that are commonly associated with autism (although this type of character rarely shows any major downsides to having autism, more on that later), like I said earlier, autism is different for everyone. Not all of us are going to feel represented by this type of character. Honestly I don’t even relate to a lot of autistic characters because they just keep reusing the same autistic stock characters and that’s really disheartening to me. It’s almost like they’re not making autistic characters for autistic people.
The Burden: This probably doesn’t need to be explained that much but it was the one thing that really pissed me off about S**’s movie. In the trailer, I really got the very distinct impression that the older sister saw Music as a burden. Her life was just oh so difficult because she had this autistic sister. No one wants to be thought of that way. And idk if you neurotypicals know this but autistic people have feelings and we hear it loud and clear when you say these kinds of things and it hurts. 
Using autism as a punchline: I think it’s fine to have an autistic character to provide comic relief, BUT! if your comic relief involves laughing at an autistic character’s very autistic behaviour then you’re doing it wrong. This kind of goes back to my first point- the reason why I hate seeing the “incapable of detecting sarcasm” character is because it’s almost exclusively played for laughs. Please stop making fun of us. 
What would I like to see more of
Diversity: I feel like this doesn’t really need much explaining. Autism can affect anyone regardless of age, race, gender, sexuality, etc. And yet most autistic characters I’ve encountered are straight white guys. Let’s see more girls, more POCs, more LGBT+ who are autistic. 
Obvious drawbacks/struggles: When I talked about the Sheldon Cooper-type character I mentioned that this type of character doesn’t really seem to face many challenges that are directly related to autism. What I mean by this is that sometimes they’ll maybe just miss the odd social cue and it’s kinda embarrassing but it rarely gets worse than that. An autistic character is going to face challenges that a neurotypical won’t ever have to deal with and if you don’t acknowledge that then you’re not really properly portraying an autistic character. Show more autistic characters struggling to make friends, having meltdowns or experiencing sensory overload, having a hard time articulating themselves. The list goes on, honestly. 
Actually saying it: Have you ever seen it where there’s a certain character and a bunch of people go “hey, that character seems like they could be [insert literally any minority] and then the creator goes “Oh, yeah that’s totally what I intended!” I personally don’t really like this, because it feels kind of disingenuous. If you’re going to write an autistic character, it would be nice to have that brought up within the story. Autism isn’t a dirty word, you’re allowed to say it. The only exception I can think of would be if you’re writing a historical fiction or some other setting where autism hasn’t been recognized but most examples I can think of don’t fall into that category whoop there it is. 
Literally just anything that isn’t a stereotype. This seems to be setting the bar pretty low, but it still needs to be said. Autism looks different for everyone and just because someone doesn’t fit the mold for a stereotypical autistic person doesn’t mean they’re not autistic. No one wants to be represented by a stereotype. 
“I’m not autistic but I want to write an autistic character. Can I do that?” 
I can’t speak for the entire autistic community when I answer this but my opinion is yes, it’s ok provided that you’re being respectful and doing research beyond reading symptoms off of WebMD. That being said, here’s my final advice: 
Listen and talk to autistic people: If you’re not listening to the group you’re trying to represent then you’re not doing a good job. There are lots of people here out there who would be willing to answer your questions or be a sensitivity reader. There’s a lot of people here on tumblr who are willing to answer your questions (you can even ask me, but I’m just one person and I don’t have all the answers. I’d recommend talking to multiple people). 
Autism Speaks is not your friend: There’s been a lot of talk about why this organization sucks, but it mostly boils down to trying to end autism and not actually helping us. So make sure you’re steering clear of them while you’re doing your research. 
Reddit and Quora are actually great resources: Reason being is that these kinds of sites will give you lots of first hand information about being autistic, and that’s the best kind of information to have, usually. Most sites will just list symptoms, but the right reddit/quora thread will provide more insight about how these symptoms affect their daily life. Additionally, you’ll have multiple people offering their own views and since autism is so different for everyone it’s good to have more than one person’s opinion (psst... this tip works for writing other minority characters too!) 
167 notes · View notes
tl-notes · 3 years
Text
Kobayashi’s Maid Dragon S2 Episode 2 Notes
Here’s some notes for episode two, too, if you’d care to join me.
Tumblr media Tumblr media
The “stay quiet” here is 大人し[い] otonashii, which takes the word for “adult” and adjectivizes it. It’s a common word with a variety of meanings, such as  when something is “behaving” properly and not raising a fuss (from children to computer code to a chronic disease to political forces, all sorts of things) or when something comes across as “mature” (like a clothing design or a young person). 
In this case the idea is that the dragons had chosen to “behave” and mind their own business, which (they seem to assume) led the humans into underestimating them and deciding to attack. (”Stay quiet” probably does a pretty good job of getting that across, but just to fill it out.)
Tumblr media
This is 残念ながら zannen nagara, or “unfortunately...”. 
The reason I bring it up here, is that it’s not a particularly intimate way of speaking and leans somewhat formal—potentially implying Ilulu has no more close relatives left to give her this news (and/or maybe her family’s social position is one where other dragons had to treat them with respect).
Tumblr media Tumblr media
The second line here is 平常心を保つよ、私は, which is a fairly strong declaration of intent. I kind of feel like “I need to keep a clear head” sounds less confident, like convincing herself “ok bad situation, but if I just do this I’m fine.” In contrast, the Japanese imo is more of a “[Ilulu can do what she may,] but it won’t get it to me either way.” Just a mild point of characterization I suppose.
Tumblr media
Just for clarity, she does use the word 雄 osu here, which is the more biological term for “in a sexually reproducing species, the one that produces sperm,” rather than a more gender-based term.
Tumblr media
The TV show, シャシャシャシャキーン Sha-sha-sha-shakiin, is a combo reference to irl Saturday-morning kids’ variety show じゃじゃじゃじゃ~ン Ja-ja-ja-jaaN and weekday-morning シャキーン! Shakiin!. 
The former’s name comes from the Japanese equivalent of ta-dah!, while the latter’s comes from the ”sound” for becoming alert, going from relaxed/sleepy/bored/etc. to “wide awake let’s go.” (though not necessarily sleep/wake related)
If you’ve seen these two emoji:
(´・ω・`)  (`・ω・´)
The one on the right is the “シャキーン” one, and is the contrast to the gloomy one on the left (ショボーン shobon). Or these, going from asleep to awake:
( ˘ω˘ )スヤァ…  (`・ω・´) シャキーン
In manga and stuff you’ll also see it used for e.g. someone drawing/brandishing a sword, striking a cool poses with a lens flare, things like that.
I think it gets translated to metallic-y sounds in English fairly often in those cases (like drawing a katana, or a mecha pose), hence the translation above. 
Tumblr media
The verb for “frolic” here is じゃれる jareru (no relation to jajaan above), which is like to play/mess around, typically in a physical sense. For example it’s used in the compound word じゃれ合う jareau, which is often used in the same way English might say “playful wrestling” about kids or animals.
Though the word Kobayashi uses is actually a different じゃれる compound, じゃれつく jaretsuku, which is like playfully/affectionately grabbing/cuddling up/etc., (also primarily regarding kids or animals). There’s a bit of overlap with some of the uses of あまえる amaeru mentioned in the last episode’s notes.
Assuming I had the visuals, I’d probably just write this as “Please not on my lap...” or similar. (Kobayashi also uses a different verb conjugation for Tohru vs. Kanna in this scene, ~つくな vs. ~つかないで; Kanna’s being more plead-y compared to Tohru’s more “cut it out!” feel, hence the “please.”)
Tumblr media
“Contact” here is “skin-ship,” a portmanteau-esque combination of skin and kinship or relationship. It’s primarily a Japanese word (you won’t find it in English dictionaries typically), but it was apparently coined by an American speaker at an international WHO seminar in 1953 (from which a Japanese attendee brought it back to Japan and it was later popularized). 
The original use of the word was in reference specifically to parent-child physical intimacy, but as it became more widespread in usage the meaning extended to all sorts of relationships, from the platonic to the romantic. 
One reason, presumably, that the term caught on so powerfully in Japan is that it has historically been a very touch-adverse culture (at least compared to say the US), and this extends even to parents with their children after the first few years. You’d see (and still see) psychologists recommend “more skinship” to people, for example.
The relative lack of skinship may partially explain the head pat thing mentioned in last episode’s notes (e.g. when you want to touch your kid, but hugs aren’t on the menu) and things like the old “hand-holding is lewd” meme. (Note this isn’t just me getting all orientalist here; there’s been a good bit of research on the skinship gap, and how it may be shrinking, by Japanese scholars.)
This line is also a bit of foreshadowing that Tohru has realized Kobayashi’s... situation already.
Tumblr media
The Japanese here is 心と心でつながった後は体ですよ, which I only really mention because I kinda felt like the English’s “Now...” implied she was saying they only recently ‘connected their hearts,’ which I don’t feel from the Japanese wording and would say is probably not how Tohru thinks. E.g. more of a “Our hearts are already connected; now it’s time for our bodies!” kinda thing.
Tumblr media
This 3/3 is March 3rd, which “equals” ♀ because that’s the date of Hinamatsuri, sometimes also referred to as Girl’s Day. The third day of the third month was originally a holiday brought over with the Chinese calendar, and it morphed from a more spring/peaches holiday into it’s more girl-oriented version at some point in the Edo period.
Tumblr media
One of the highlights of Hinamatsuri is the doll displays, as pictured in this short bit with the Saikawa sisters. There are various types of displays, but this sort of staircase arrangement is the most common I believe. Each level has a certain type of doll that goes on it, with the top level having an “emperor” and an “empress” doll—which is the pair Riko replaces with dolls of herself and Kanna.
There’s some similarities between these doll displays and stereotypical Christmas trees: a family is likely to have a set of ornaments/dolls they mostly reuse each year, you put them up some time in advance of the actual holiday, then get lazy and leave them up too long put them away for a year after it’s over. A lot of businesses and such will put up displays as well.
Tumblr media
“The judge in the underworld” is left vague here and isn’t a specific reference to anything, but is generally in line with the typical “image” of what happens after you die (setting aside actual religious beliefs) in Japan. 
Please see the documentary series Hoozuki no Reitetsu for more info.
Tumblr media
As of right now in the anime, Ilulu has only shown up twice, and only once of those when Kobayashi was alone. The implication seems to be that there have been other Ilulu encounters that we haven’t seen. 
Also, for clarity, the Japanese is 私が一人の時にいつもイルルは来るから, which is more of a “whenever I’m alone Ilulu shows up” than a “she only shows up when I’m alone.” (The English could sorta be read either way I think?)
Tumblr media Tumblr media Tumblr media Tumblr media
This bit is それだけじゃないって、争い以外もあると思ってくれているからだ。私はそんなトールを信じているから… だからその為にイルルと和解したい
The main point of contention I have with this English is that it implies Kobayashi wants Tohru and Ilulu to make up. However, I’d say this is more Kobayashi wanting to come to terms with Ilulu herself (and just by extension Tohru/the other dragons/maybe other humans). 
That is, by making peace between herself the human and the “hostile” dragon Ilulu, she’d be helping prove Tohru’s belief correct—and she has faith in Tohru that it is (see also last season finale).  
(Notably while Tohru is Chaos faction herself, there’s not really been another Chaos dragon yet to be convinced like this. Kanna is no-faction, Fafnir is technically no-faction even if Chaos-ish, Quetzalcoatl is an observer, Elma is Harmony, and Tohru’s father is an exception on multiple levels.)
Without getting too deep into the “why,” one quick thing I’ll point out is that she says 和解したい wakai shitai, not してほしい shite hoshii or させたい sasetai etc., meaning it’s something she wants to do herself, not want/make someone else do. Generally speaking you can’t use the ~たい “want to” form for anyone but yourself (you don’t know what anyone else is thinking, after all), unless quoting them, asking, or in the ~がる “seems to want to” form.
Tumblr media
This is a 防犯ブザー bouhan buzaa, a crime-prevention buzzer, also known as a personal or self-defense alarm. They emit a very loud sound when activated. The idea is you, well, use it like she does here, when someone is trying to do a crime to you.
Since most Japanese children walk to school, it’s extremely common for these devices to given to students (either by parents or a gov’t body). It’s technically recommended for adults to carry them too, though the advent of the mobile phone has driven down carry rates.
This particular one was probably purchased in episode four of season one, if you want to rewatch and see why!
Tumblr media
This is 私にぶつけたい気持ちでもあるの?in the Japanese.
The verb for “tell” is ぶつける butsukeru, an evocative word meaning ~to slam against (somewhat similar to “vent” in English when used with emotions/feelings). 
The “something” is 気持ち kimochi, ~emotion/feeling/thought.
So the Japanese here feels a lot more expressive than "something you want to tell me,” I would say (that could just as easily be a translation of 話したいこと). That said it’s not an easy thing to express in English within the confines of the format here, especially if you want to keep the “target = ‘me’” part.
It might feel somewhat like “You got something bottled up you wanna hit me with?”, though I doubt if I’d use that either.
As a side note, the manga has Kobayashi say an extra line after this, about being the “main tank” to take her “hate” (Japanese for “aggro” in MMOs). 
Tumblr media
A small note that “that girl and that boy” is あの子とあの子 ano ko to ano ko, so no gender specification in the Japanese (it’s a good language for talking about people without specifying a gender!).
Tumblr media
“Next time” here is 今度 kondo, which is an interesting word because you can situationally use it for “recently,” “this time,” “next time,” or “soon.” 
The reason I bring it up here is the English “next time,” personally, leaves me thinking “Was there a previous time? What ‘next’ do you mean?”—just a heads up that that’s not really an issue in the original line.
Also: this whole extended scene with Kobayashi saving Ilulu is one of the “many senses” mentioned in the episode title. (see also episode one notes re ikemen)
Tumblr media
As an aside, this "play” is じゃれ合い jareai, the noun form of the jareau that was mentioned in the above “frolic” note.
Tumblr media
If you were wondering: “Do dragons use paper?”, the word here is 形骸化 keigai-ka, (almost) lit. ~reduced to bones, meaning something that once was strong/effective is now basically just a formality. It’s similar to the phrase “dead letter” in reference to old laws that aren’t really enforced anymore.
So two potential points of ~lore relevance~ here: 1) the rules probably used to be enforced, 2) we have no evidence (either way, from this) that they actually have them on paper somewhere.
Tumblr media
こりゃトールの父ちゃんは本格的に優しかったみたいだな
This might just be me reading too much into the English (again), but one difference in nuance between these two lines is that the English has Kobayashi implying Tohru’s dad “seemed” kind (which implies he’s not really kind, just kind in contrast to this villain), while the Japanese is more taking this as evidence that Tohru’s dad was actually being kind (see also last season finale).
For those wondering if the みたい in that line would imply a “seems”: it sort of does, but it applies across the whole observation here. I.e. “seems Tohru’s father was genuinely nice” vs. “making Tohru’s father seem genuinely nice” (which I’d guess would probably use 優しく見えてくる or something). 
Tumblr media
When you see “underestimate” in anime, most of the time it’s なめる nameru. It comes from the verbified archaic adjective 無礼し nameshi, meaning a combination of looking down on, acting rude towards, etc., and uses the same characters as “rude” (though often written in hiragana/katakana).
It also is a homonym of the verb “to lick,” so “Don’t underestimate humans” sounds identical to “Don’t lick humans.”
Tumblr media Tumblr media
“Functional member of society” is 社会人 shakaijin, ~lit. person of society, which is a very commonly used word to refer to basically anyone who is an active member of society. It includes homemakers, so it’s not strictly “has a job at a company,” but in many contexts it’s used like “people with jobs” versus “students and NEETs.”
(Not that there’s anything wrong with the translation, just some extra context.)
A technique reminiscent of this shadow puppet silhouette style was also used in Hyouka, another Kyoani show and one directed by the late Series Director Takemoto Yasuhiro. 
Tumblr media
I kind of feel like yelling “Stay with me!” at someone injured is something you do when they’re in danger of fading away, not when they’re waking back up? Maybe that’s just me.
The Japanese is お気を確かに o-ki wo tashika ni, a polite (since Tohru almost always speaks kinda formally to Kobayashi, as part of the maid thing) way of saying “pull/hold it together,” and is used in a variety of situations.
Tumblr media
Kanna’s line is a question (e.g. like “are you okay?”) in the Japanese here, whereas the English sounds more like something you say to someone who’s injured to try to reassure them. 
Tumblr media
This line is その子離れようとしないんです sono ko hanareyou to shinai n desu.
The English is a pretty literal translation: hanareru is the verb for leaving/separating (in some senses), and the ~you conjugation means “try to ~”. However, that conjugation also has a second use in just indicating intent—especially when used in the negative, like here—so e.g. “She didn’t want to leave your side,” or “She wouldn’t leave your side at all.”
Tumblr media
(◎Д◎)
Just in case: this is an emoji for expressing shock. 
Tumblr media
One thing that is left out of the English in this line is the だけ dake, “only.” 
So Kobayashi’s not necessarily surprised at this by itself, but in contrast to the fact that Tohru says she probably can hide her claws/tail (so why not this too?). 
Tumblr media
The base phrase Tohru is saying here is 私たちの仲じゃないですか, which roughly means “that’s just our relationship,” and is used commonly when being thanked for doing a favor for someone close. It’s similar in meaning to something like “hey of course, no problem, I know you’d do the same for me.”
Tohru puts a little spin on it by adding the “eternal” to make it 永遠の仲, which is a separate phrase that means probably what you’d think it means.
Tumblr media
This quick cut to Tohru’s feet and the light “foot pop” motion... I have a hard time believing it’s anything but the director trying to give some subtle “goodbye kiss when leaving for work” vibes, even if they aren’t literally kissing. Just me?
Tumblr media
Here she says あのトール ano Tohru, lit. “that Tohru,“ which in this sort of context carries a meaning similar to using an italicized “that” in English: not just any Tohru, but that Tohru, the famous one. The implication is that yes indeed Tohru is well-known among other dragons—and known to be quite strong and merciless.
Tumblr media
It’s not a particularly big deal, but technically this is 人間と, i.e. Living with.
Tumblr media
The ball hands thing is generally thought of as “Doraemon hands” in Japan. Doraemon gets the name from the food “dorayaki,” but “Dora” is also how you pronounce the first two syllables in “Dragon” (ドラゴン doragon).
Keep this in mind.
Tumblr media
挨拶 (あいさつ) aisatsu, often translated as “greeting(s)”, is a lot bigger of a thing culturally for Japan than it might be for where you live. Though translated as “greetings” it also includes farewells and more. Basically a general term for “in X situation, say Y” style semi-set phrases.
In more traditionally minded companies, for example, employees are often expected to give a rote ohayou gozaimasu when they arrive (even if they think no one is around to hear it), and may get chewed out for not doing so or half-assing it. Then when passing someone in the hallway etc., an otsukare-sama desu, and yet another phrase when leaving for the day. Also the ittekimasu and itterasshai (when leaving home/saying bye to them) or tadaima and okaeri (returning home/welcoming back) that probably many anime-watchers are familiar with. Even itadakimasu is an aisatsu. 
Obviously every culture utilizes “greetings” like this, but in Japan they’re pretty heavily ritualized and treated as a cornerstone of human relations, a key part of showing respect for your fellow humans (even people you hate!) and ensuring the smooth working of society. It’s not the thing they chose to have Tohru put first in her “living with humans [in Japan]” notebook for nothing!
Tumblr media
The English “the” is a popular word to use in Japanese as an intensifier, similar to how it’s used in a sentence like “this isn’t just an [example], it’s the [example]!” 
It’s usually pronounced “za” and often written that way in katakana (ザ) for this usage. (If you type “za” in a Japanese IME, most will offer up “the” as one of the options to convert the text to, even.) 
Tumblr media
The word she says here is 喝 katsu, which, in this sense, is a stereotypical thing for a Zen teacher to say to a student as a stand-in for explaining some deep Zen concept that words can’t describe. So here, it’s kinda like “Yes this may seem contradictory, but really it’s just too complicated for you! No more questions!” 
Obviously that’s oversimplified and it’s used in other ways too (see Saikawa’s father during the sports festival), but just for the purposes of this joke, there you have it.
Tumblr media
The word used in the Japanese here is 建前 tatemae. If you’ve ever studied any Japanese, you’ve likely heard about honne vs. tatemae, your inner feelings vs. the front you put up for social reasons. 
People new to the language are sometimes prone to approaching that distinction with “well why doesn’t everyone just honne all the time, why play games?”, but of course almost everyone splits themselves like this. You probably hate your boss, but you also probably don’t tell them that to their face to avoid getting fired. Or maybe you have some family members you can’t stand, but act nice around anyway because it’s not worth the trouble to start fights. 
Japan just put names to the idea, and maybe leans a little more toward encouraging tatemae in more situations.
Tumblr media
This is せいぜい悩むんですね.
せいぜい seizei as an adverb means doing something to utmost extent one is capable of. You’ve likely heard it from a villain somewhere saying something like “Struggle all you like, wahaha!”. 
Though it’s not necessarily down-talky like that, in modern times that is the trend (you can use it for yourself no problem, but if used to talk about someone else’s actions it may come off as belittling). Tohru, as one of the strongest beings in the setting and with the pride to match, uses it a lot.
悩む nayamu is to worry, fret, ruminate over (some difficulty etc.).
The sentence in general is one that is highly context dependent, but here it’s Tohru thinking to herself, somewhat impressed, that Ilulu is actually putting serious thought into the question of what she wants to do with her life. 
And, as the background suggests, finding it surprisingly adorable/admirable; up until just a few days ago, Ilulu was known as one of the most extremist Chaos faction dragons obsessed with nothing but destruction, yet look at her now. In a way, Tohru’s taken over an older sister kind of role for her.
(For the curious, if the ね was dropped or swapped to a よ here, that would imply she was directing the comment “at” Ilulu, rather than saying it in observation.)
Tumblr media
The word here is 契る chigiru, which usually means to swear/pledge (e.g. swear a pact, pledge your love), but can also be a somewhat fancy word for having sex, especially of a married couple.
I feel like I personally would have used more of a euphemism for the translation.
Tumblr media
The phrase here is ダメの助 dame-no-suke, where dame is no/bad/can’t do/useless, and (no)suke is a common ending to first names; both actual names and sort of on-the-spot nicknames; someone looking sleepy might be called a 寝坊助 nebou-suke in the same way as “sleepyhead.”
Or, as here, sticking to the end of things for comedic effect or as indication of a panicked/confused thought process.
Tumblr media
( ° ρ ° )
Just in case: this one is also expressing shock, but a kind of dumbfounded shock. The ρ is a drooling, slack-jawed mouth.
Tumblr media
In the next episode preview they talk about where Ilulu will sleep, since they don’t have room for another bed. Ilulu wants to sleep in the closet—or more specifically, the 押し入れ oshi-ire, which is a particular closet layout you’ll find in many Japanese bedrooms. 
The typical difference is that an 押し入れ was originally designed for 和室 washitsu, traditional-style Japanese rooms with tatami floors, primarily as storage space for folded-up futon/blankets/pillows, as you would put those away during the day to free up space. Thus they typically are rather wide, mildly deep, and have a waist-height, solid horizontal divider capable of supporting a lot of weight. 
They actually are pretty okay for sleeping in if you’re not claustrophobic or tall.
Anyway, I bring this up because you know who else very famously sleeps in one of these? That’s right: Doraemon.
18 notes · View notes
championfrita · 4 years
Text
Pokémon Sword and Shield Review
So...I've taken some time to fully play Pokémon Shield. Now, I know this is pretty delayed, and I got the double pack so I wanted to play Sword first to see if how I felt was really accurate or if I was being too harsh. That said, let's talk about my experience with the Galar Region.
Initial Impressions
Overall, I was excited to play Shield at first. Everything was bright and exciting and the characters were easy to recognize and not overly generic.
The first few hours of this game, well it's a slow burn. And I do mean SLOW. Even with the text set to Fast and me taking things at my own pace it took me at least a good couple hours to reach the Wild Area. Furthermore, this game has an infernal amount of handholding, even when given the option to say "I know all this already" it still gives a brief explaination for almost anything and STILL makes you sit ALL THE WAY THROUGH the catch tutorial.
It's 2019 and older players still don't get the option to skip this. Come on GameFreak.
That said, the longer I played the more I began to notice...how should I put this? Blatant laziness?
The Wild Area
Now, the CONCEPT of the Wild Area in theory is amazing. It's still not too bad as is, but there are definitely flaws. For starters, the same tree has been copy pasted all over the place to make up 90% of the foliage.
More than that, though, despite the Wild Area having a good selection of Pokémon and a fairly varietied environment (desert, lakes, forest) it feels oddly...empty. There are no real secrets to speak of, no hidden areas, no easily missed items. Everything is all right out there to see and spread pretty far apart. I don't know if it's a lack of Trainers or the fact that I don't have an Online membership so I played alone, but the Wild Area feels like it just needs something MORE.
Dynamax Raid Battles, even when done alone, are fairly fun and sometimes challenging with the turn limit. Radiant AI Trainers spawn in to assist you if you're playing alone so there's no worries about having to take one on with just one Pokémon.
Camping, which can be done anywhere but is introduced to the player here, is an absolute treat. Have YOU played fetch with a unicorn? I have, and I love it. The wide variety of curries you can make with different ingredients is nice, and your Pokémon even get EXP boosts if you play with and feed them while camping.
The Pokémon
Honestly, I'm really not impressed. The Galar Dex of new Pokémon feels painfully small, so much so that playing Pokémon GO and catching a few Unova Pokémon made me yearn for the days when we used to get regions completely FULL of new Pokémon. Remember when you had to wait until AFTER the main game to start catching Pokémon from past gens? I...well, this might be an unpopular opinion, but I LIKED that.
That said, using a sparse selection of Galar Pokémon and Galar Regional Variants on my team definitely made the Gym Challenge more difficult. I picked Scorbunny, because Fire Types, and honestly didn't really care for it or its evolutions at first. Cinderace has really grown on me though and I like Pyro Ball as a move. It's flashy and powerful and that suits me just fine. Most of the new Pokémon's DESIGNS were good and I liked them, there just really weren't ENOUGH of them.
I'm fairly pleased with the regional variants as well. It was difficult to adjust to Ponyta and Rapidash being Psychic Type, but I really liked having them on my team. At the same time...Meowth not evolving into a Persian doesn't really sit right with me.
I'm all for branch evolutions, but Perrserker honestly just looks more like a giant Galar Meowth than anything. I played this with only the info given in the few scattered trailers I'd seen, so I was genuinely excited to see what a Galarian Persian would look like only to end up with Perrserker. The Typing is phenominal, and I think it's great to see a Steel Type Meowth for a change, but I just don't like where they went with it. Eh. Ces't la vie, moving on.
The Story
It's weak. Straight up, the story in this game is poor. There were so many directions they could have gone. I really liked the idea of Rose being this charismatic chairman hype man for the League and being the bad guy. I saw it coming, but it was a nice change to see just based on his personality. Still, it feels rushed. His motivations are really one dimensional and glossed over. Like, "Oh, here's the bad guy. Go get him." It worked in Gen 1 because Giovanni was a MOBSTER. He was MEANT to be a bad guy straight to the core in general, but Rose just doesn't have that vibe.
Not only that, but the "Bad League Members" are kinda meh. That feels REALLY lazy. They didn't even really get a decent uniform change when they started taking on the name Macro Cosmos in Rose Tower. They got black glasses. That's it. Just that. The fight with Eternatus feels painfully rushed and shoehorned in too, almost like they thought "Oh no, we need to give them a big nasty boss to fight! Let's just throw a random monster at them and say Rose summoned it. Seems like a solid plan."
I DID like the after story with Piers though. It really solidifies that older brother sort of nature with him, even if he tries to hide it most of the time.
The Characters
I liked Hop. As a character he's really fun and I like how they gave him this over excited very grand gestured sort of personality. He's really just happy to be ANYWHERE as long as it's with his Pokémon and you. His admiration for his big bro might come off strong and make him seem a little flat at first, but he's overall portrayed as a good kid and I like him.
Leon on the other hand...well I hated him for most of the game. His design is great and he looks fabulous, but he just has the most cocky, obnoxious, pandering personality 90% of the time. Still, I have to give credit where credit is due and recognize that he IS actually a multifaceted character. He showboats not just because he's too confident but also to give the crowd a show and put people at ease in times of danger. Not only that, but his recognition of his little brother's accomplishments and his graceful acceptance of defeat when you beat him reveals a really well written character.
I don't DISlike Sonia, and I have no problem with Prof. Magnolia sitting on the sidelines, but she can be a little...irritating at times with the way she speaks about and to people. The Gym Leaders, aside from Piers, feel a little...light.
I mean, most Gym Leaders don't have detailed backstories, but these ones feel paper thin personality wise as well. I had to look at the official GUIDE just to be sure what the relationship between Melony and Gordie even WAS because you only seem him in her Special League Card in Shield and that tells you nothing about him. The only real leaders that stood out to me were Piers and Raihan, and while I was iffy about his design at first I LOVE Raihan. He has so much more personality and ferocity than any of the other leaders. And the social commentary about him needing to constantly take and post a selfie, even after losing, is a nice touch.
The Galar Region
Is very linear. Like, VERY linear. Even when you take a branching path it either loops back around or gives you a free ride to wherever you have to backtrack to. I hope you like Hammerlocke, cuz you're gonna be visiting there several times.
I know that the region is based off the UK, and maybe my Americanized idea of cities is different (idk, I've never been to the UK), but a lot of the towns in this game feel really small. Like, almost smaller than some of the towns in Hoenn small. Maybe it's a lack of significant interactable buildings, but despite many of them having multiple floors you typically can only access one and that's kind of a disappointment. The hotel in Wyndon won't even let you get in the elevator, and while I get that Alola also did that, it's kind of jarring when the hotel in Motostoke WILL let you see other floors.
That said, I kind of expected more than ONE Wild Area. The one we DID get is fine, and I appreciate what it is and lets us do, but I honestly thought there would be multiple places to really explore outside the standard straight lines. Pokémon has never been a franchise to shy away from puzzles before so I expected this to not be any different. Unfortunately, I was wrong.
Moreover, many of the environment pieces are just UGLY. A lot of the ground textures are reused 3DS assets, and those copy pasted trees I mentioned earlier? Also 3DS assets. How do I know? They're pentagonal instead of round. In other words, they have five sides. Why? Because the 3DS hardware couldn't handle complex environmental shapes that well so they could get away with it, but now that we have nice round berry trees the contrast becomes painful. The Wild Area is so ugly the first time you see it is at NIGHT. They were so aware of what they did they hoped making it darker would hide the lazy flop instead of showing off how bad it was.
It isn't like they COULDN'T fix it either. Look at Ballonlea and Glimwood Tangle. They're absolutely beautiful and very well done. The modeling with them is fantastic and I love the glowing effects. They absolutely could've made the poorly done areas look amazing, but for some reason they didn't and the game suffers some as a result.
Other Thoughts
The Gym Challenges...they were not fun. Like, honestly some were ok. Herding Wooloo was easy, but they really didn't feel like anything I would expect from a Gym. The water puzzle in Nessa's Gym was fine, and I personally liked the spinning cup ride, but the rest just felt like agonizingly long padding because they couldn't come up with anything. Look at Circhester's challenge. It's a dowsing rod gauntlet where you have to avoid falling in pits in an artificial blizzard. It. is. SO. SLOW. That said, Spikemuth having just a Trainer gauntlet instead was kind of awkward. I reached the end and asked myself "Was that it? Is this it? Is this all there is to Spikemuth? Just one giant alleyway and a Pokémon Center?"
Raihan's three trials of worthiness challenge? It was more difficult than the battle AGAINST RAIHAN. Speaking of, I beat Hop, Marnie, Bede, all the Gym Leaders, Rose, Oleana, and Leon on my first try every time. While it was more difficult with my specific Pokémon choices, it really wasn't much. And can I just say that the Gym Badges are kinda lame? I get what they were going for, but the designs of each piece could've been really unique and intricate and instead we got glorified stamps.
I liked a lot of the general features of the game. Camping, clothing shops, League Cards. I love designing League Cards, even if I'm the only one who's ever gonna see em. That said, the clothing choices were really narrow based on what we got in Sun and Moon. The variety of different items was pretty small, though I loved all the punk leather stuff but WOW IS IT EXPENSIVE. Like Lumiose Boutique expensive. AND WHY IS THERE NEVER A REDHEAD HAIR COLOR THAT ISN'T JUST AUBURN RED? There are actually A LOT of redheads with LIGHT RED hair (that's more a personal gripe than anything, I know).
A lot of the music felt almost like rehashes of older BGMs. Like, Postwick, Route 1, and Wedgehurst all sound like they have remixed Hoenn music. A lot of the other music tracks just don't feel fitting for the areas or for Pokémon games in general. I like parts of the Slumbering Weald music and I like the Gym Music, but the opening of Slumbering Weald feels awkward and like it doesn't fit a mysterious forest we're not allowed to be in.
I know I've complained a lot, but there were some things I genuinely liked. A lot of the Pokémon designs, place names, and other radiant decor and parts of the region are actually subtle and not so subtle references to cultural points of the UK. Skwovet and its evolution for example are a gray and red squirrel respectively and are a nod to invasive species, which is neat.
In Conclusion
Is Pokémon Sword and Shield amazing? No. Is it bad? No. Sword and Shield fall into that mediocre middle ground of being ok but nothing to write home about. Could I have done without them? Sure, they aren't some world ending imperitive must play. They're ok, and they make for a fine jumping on point and a fine little adventure if you have spare time. Have other mainline games done it better? Heck yeah, but that doesn't mean Sword and Shield haven't done a few good things too.
Overall, it sort of feels like GameFreak bit off more than they could chew, or were afraid to make changes because of unfamiliarity with the Switch's hardware and software limitations. Pokémon Let's Go had a lot more effort, but it also was much safer and had a much easier to work with art style to everything. Chibi proportions are a lot easier to fake than a more realistic counterpart. Things can be not perfect and it's less noticable than with more realistic proportions, and I think they were afraid to push back the deadline any further for the inevitable backlash despite that being what they likely needed. The DLC may change my mind, but as it stands, just the fact that they feel they can JUSTIFY their laziness with DLC packs really upsets me.
I give Pokémon Sword and Shield a 5/10.
It's just, OK.
Tumblr media Tumblr media Tumblr media Tumblr media Tumblr media Tumblr media Tumblr media
2 notes · View notes
Link
In this post, we'll see what atomic CSS is, how it relates to functional / utility-first CSS like TailwindCSS, and that big players are adopting it in their modern React codebases. As I'm not a expert of this subject, don't expect a deep dive about the pros and cons. I just hope you get an idea about what it's about. Note: Atomic CSS is not really related to Atomic Design.
What is atomic CSS?
You may have heard of various CSS methodologies like BEM, OOCSS...
<button class="button button--state-danger"> Danger button </button>
These days, people really like Tailwind CSS and its utility-first concept. This is close to Functional CSS and Tachyon.
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"> Button </button>
With a stylesheet of a bunch of utility classes, you can go a long way. Atomic CSS is like an extreme version of utility-first CSS: all CSS classes have a single, unique CSS rule. Atomic CSS was first used by Thierry Koblentz (Yahoo!), in Challenging CSS Best Practices in 2013.
/* Atomic CSS */ .bw-2x { border-width: 2px; } .bss { border-style: solid; } .sans { font-style: sans-serif; } .p-1x { padding: 10px; } /* Not atomic, because the class contains 2 rules */ .p-1x-sans { padding: 10px; font-style: sans-serif; }
With utility/atomic CSS, we acknowledge it's ok to couple the structure and presentation layers: when we need to change the button color, we modify the HTML, not the CSS. This tight coupling is also acknowledged in modern CSS-in-JS React codebases, but it seems the CSS world figured out first that the "separation of concern" of the web didn't feel right. Specificity is also less a problem, as we use simple class selectors. We are now styling via the markup, which has several interesting properties:
the stylesheet grows less as we add new features
we can move the markup around, and the styles are moved at the same time
we can remove features, and be sure that we remove the related styling at the same time
For sure, the html is a bit more bloated. This can be a concern for server rendered web apps, but the high redundancy in class names compress well with gzip, in the same way it worked well for duplicated css rules previously found in your CSS files. You don't need to use utility/atomic CSS for every cases, just the most common styling patterns. Once your utility/atomic CSS is ready, it will not change or grow much. It's possible to cache it more aggressively (you can append it to vendor.css for example, and expect it to not invalidate across app redeploys). It is also quite portable, and you can use it in other applications.
Limits of utility/atomic CSS
Utility/atomic CSS looks interesting, but they come with a few challenges as well. People usually write utility/atomic CSS by hand, carefully crafting naming conventions. It can be hard to ensure the convention is easy to use, consistent, and not bloated over time. Can multiple persons work on this CSS and keep it consistent? Is it subject to the bus factor? You also need to work on a good utility/atomic stylesheet up-front, before being able to iterate on features that will use it. If the utility/atomic CSS is made by someone else, you will have to learn the class naming conventions first (even if you know everything about CSS). This convention is opiniated, and it's possible that you don't like it. Sometimes, you need some extra CSS that is not provided by your utility/atomic CSS. There's no unique way to provide the remaining one-off styles.
Tailwind to the rescue
The approach of Tailwind is very convenient, and solves some of these problems. It does not really provide a unique utility CSS file for all websites. Instead, it only provides a shared scope and naming conventions. From a configuration file, it allows you to generate your own custom utility CSS. Knowledge of Tailwind is portable to other applications, even if they don't use exactly the same class names. It reminds me a bit of the "Learn once, write anywhere" philosophy of React. I've seen people reporting that Tailwind classes cover something between 90% or 95% of their needs. It seems the scope is large enough, and we don't often need to use one-off style. At this point you might wonder why use atomic CSS instead of Tailwind?. What would you gain in enforcing the atomic CSS rule of 1 rule, 1 class? You would end up with a larger html markup, and a less convenient naming convention? Tailwind already has many atomic classes anyway. So, should we abandon the idea of atomic CSS, and simply use Tailwind? Tailwind is a great solution, but there are still a few problems that remain unsolved:
the need to learn an opiniated naming convention
CSS rules insertion order still matters
can unused rules be easily removed?
what do we do with the remaining one-off styles?
Handwritten atomic CSS might not be the most convenient compared to Tailwind.
Comparison with CSS-in-JS
There's a relationship with CSS-in-JS, and utility/atomic CSS. Both approaches advocate for styling from the markup, somehow trying to emulate performant inline styles, which gives them many similar properties (like the ability to move things around with confidence). Christopher Chedeau greatly helped spread the idea of CSS-in-JS in the React ecosystem. In multiple talks, he explains the problems of CSS:
Tumblr media
Utility/atomic CSS solve some of these problems too, but definitively not all (particularly, the non-deterministic resolution of styles). If they share similarities, can't we use them both together?
Enter atomic CSS-in-JS
Atomic CSS-in-JS can be seen as "automatic atomic CSS":
You don't need to create a class name convention anymore
Common and one-off styles are treated the same way
Ability extract the critical CSS of a page, and do code-splitting
An opportunity to fix the CSS rules insertion order issues in JS
I'm not aware about all CSS-in-JS libraries out there currently supporting atomic CSS. Supporting it is actually an implementation detail of the CSS-in-JS library. Support might come and go, or can even be made optional. I will highlight 2 particular solutions, that recently lead to 2 large-scale atomic CSS-in-JS deployments, using 2 talks as sources:
React-Native-Web at Twitter (more details in Nicolas Gallagher's talk)
Stylex at Facebook (more details in Frank Yan's talk)
See also: Styletron, Fela, cxs
React-Native-Web
React-Native-Web is a very interesting library: it permits to render React-Native primitives on the web. We are not really talking about cross-platform mobile/web development here (watch the talks for more details). As a web developer, you just need to understand that React-Native-Web is a regular CSS-in-JS library, that comes with a small set of primitive React components. Wherever you see View, you can replace it in your mind with div, and you are good to go. React-Native-Web has been created by Nicolas Gallagher, working on Twitter mobile. They progressively deployed it to mobile, not sure when exactly but probably around 2017/2018. Since then, it has been used by other companies (Major League Soccer, Flipkart, Uber, The Times...), but the most significant deployment has been the new 2019 Twitter desktop app by a team lead by Paul Armstrong.
Tumblr media
Stylex
Stylex is a new CSS-in-JS library developed at Facebook for the 2020 Facebook rewrite (currently in beta). It seems they plan to open-source it some day, possibly under a different name. It's worth mentioning that Nicolas Gallagher, the author of React-Native-Web, was hired by Facebook 2 years ago. It's not a big surprise to see some of its concept being reused by Facebook. Unlike React-Native-Web, Stylex does not seem focused on cross-platform development. All the infos I have are from the talk :) We'll have to wait for more details.
Scalability
As expected with atomic CSS, both Twitter and Facebook have seen a massive reduction of their CSS, as it now follows a logarithmic curve. There's an initial price to pay for simple apps though.
Tumblr media Tumblr media
Facebook shared concrete numbers:
Their old site was 413Kb of CSS just for the landing page
Their new site is 74Kb for the whole site, including the dark mode
Tumblr media
Source and output
The 2 libraries looks quite similar here, but it's hard to say, considering we don't know much about Stylex. It's worth highlighting React-Native-Web will expand the CSS shortand syntaxes like margin: 0.
Tumblr media Tumblr media Tumblr media Tumblr media Tumblr media
Production inspection
Let's look at what the markup looks like on Twitter:
Tumblr media
Now, let's look at the new Facebook:
Tumblr media
Many people will probably be horrified when seeing this, but it actually works, and remains accessible. It might be a bit harder to navigate styles in the Chrome inspector, but devtools can help:
Tumblr media
CSS rules order
Unlike handwritten utility/atomic CSS, the JS libs are able to make the styling not dependent of the CSS rules insertion order. As you may know, in case of conflicting rules, it's not the last class of a class attribute that wins, but the rule that is inserted last in the stylesheet. Specificity issues are solved by only using simple class-based selectors.
Tumblr media Tumblr media
In practice, these libraries avoid outputting classes with conflicting rules on the same element. They ensure that the last style declared in the markup always wins. The "overridden classes" are filtered, and don't even make it to the DOM.
const styles = pseudoLib.create({ red: {color: "red"}, blue: {color: "blue"}, }); // That div only will have a single atomic class (not 2!), for the blue color <div style={[styles.red, styles.blue]}> Always blue! </div> // That div only will have a single atomic class (not 2!), for the red color <div style={[styles.blue, styles.red]}> Always red! </div>
Note: This predictable behavior is only possible thanks to using the most strict atomic CSS. If a class had multiple rules, and only one of them was overridden, the CSS-in-JS library wouldn't be able to filter that class without removing the non-overridden rules as well. If a class had a single shorthand rule like margin: 0, and the override was marginTop: 10, it's the same problem. The shorthand syntax like margin: 0 is expanded to 4 distinct classes, and the library is able to filter overridden classes that should not appear in the DOM with more granularity.
You still prefer Tailwind?
Once you know all the Tailwind naming conventions, you can code an UI very fast. It might feel less productive to go back to writing every CSS rule by hand, like you do in CSS-in-JS. Nothing prevents your for building your own abstractions on top of an atomic CSS-in-JS framework. Styled-system might be able to run some of the CSS-in-JS libraries supporting atomic CSS. It's even possible to reuse naming conventions for Tailwind in JS, if you feel you are productive with it. Let's take some Tailwind code:
<div className="absolute inset-0 p-4 bg-blue-500" />
Now, let's take a random solution (react-native-web-tailwindcss) I just found on google:
import {t} from 'react-native-tailwindcss'; <View style={[t.absolute, t.inset0, t.p4, t.bgBlue500]} />
In term of productivity, this is not very different. And you could avoid typos with TypeScript.
Conclusion
To me, using Atomic CSS, CSS-in-JS, and Tailwind all at the same time makes sense. That's almost everything I have to say about atomic CSS-in-JS. I have never used atomic CSS, atomic CSS-in-JS, or Tailwind in any large production deployment. I'm probably wrong on some parts, feel free to correct me on Twitter. I think atomic CSS-in-JS is a trend to watch in the React ecosystem, and I hope you learned something useful with this post. As I've not been able to find any article about atomic CSS-in-JS, I wrote this mostly for myself. I want a resource to link to when I mention atomic CSS-in-JS in upcoming blog posts (I plan to write more articles about React-Native-Web and cross-platform, stay tuned). Thank you for reading.
0 notes
topicprinter · 5 years
Link
So you have a brand/business/startup that you think should test some Influencer Marketing? I agree, you probably should. In the past two years, depending on the project, almost nothing that has had a cheaper CPM (and sometimes CPI) for my clients than Influencer Marketing, but it’s taken me nearly 500 total engagements to figure it all out (you can google my username if you want to see my LinkedIn or verify me)A while ago it was the total Wild Wild West of Advertising, with rate fluctuation looking at like 300% for the same sized audiences. Brands were paying ridiculous rates to Influencers who built their followings with mostly bots and booty shorts, but that’s dying down now, and what’s left after that dust settles is an extremely authentic way to grow your brand, convert and literally influence people to use/try/buy your stuff. With that, I wanted to take the time to write out what I’ve learned about how you can do your own Influencer Marketing tests, even with minimal budgets, yourself. Firstly, I want to say, there are three major ways you can go about Influencer Marketing:​DIY (which is the purpose of this post so I won’t elaborate on what that means yet.Going through an agency like God and Beauty (I recommend them)Using a platform like Influence.com or the similarly named influence.co.The difference between these strategies basically is more money investment vs. more time investment for you and your team. For instance, if you go through an agency, they’ll do the heavy lifting for you from start to finish, but you’ll need to pay a decent percentage of your total budget to get that assistance. Agencies are also great if you’re starting out because you can benefit from people who have been in the trenches (like Kyle at G&B) for thousands of posts since the inception of the advertising channel. Basically, if you’re a bootstrapped, self-funded company, you’ll need to go the DIY approach, and my entire near 15-year career has been dedicated to helping early-stage businesses so, why stop now! Let me tell you how to do your own Influencer Campaign:Step 1) DiscoveryThe first thing I always do is develop a keyword list that I want to use to discover Influencers who will have an audience of our target users. For this exercise, I didn’t spend a ton of time developing this list, but I would obviously suggest you research this in-depth with more time. Let’s say I’m a healthy food delivery startup focused on affluent 25-45-year-olds. I won’t name any names, because they’re not paying me, but just pick one in your mind. Assume that after I wrote out all the keywords, I searched dozens of terms in the channels I want to advertise on and found these 5 to be the most accurate:Develop Influencer Keywords:“Healthy”“Medicine”“Wellness”“Fitness”“Organic”For the sake of this exercise, let’s imagine these 5 terms are super targeted to our users based on significant research. I’ll source and develop lists of Influencers for each term,(for this exercise I’ll just show 1 each) to test out an engagement and identify which “community” or keyword focus is best for us to scale up with this strategy.Identifying InfluencersI then go to various Social Media platforms, and/ or Influencer Platforms like Aspire, HeartBeat, Influence.co etc and search for users based on these keywords. Each user should have a solid blend of these three metrics:​Audience - How many total followers.Engagement - How active are followers.Activations - How many directly ask followers to purchase?Beyond the 3 mentioned above, do they have the audience your company wishes to target? This can be ascertained by looking at the keyword relevance of their profile, posts and their content. Their location is also important if your business is focused on specific geographies.Average Post EngagementThen I’m looking at the average engagement of their posts.This sheet has the formulas I use for determining the engagement ROI of an influencer before I engage them.FYI the rest is dummy content but shows you an example of the metrics and KPIs I look for.I’ve found that much of my Influencer Marketing success has come from smaller Influencers under 100k followers, not only because they have more engagement, but because they’re also less saturated, and have more interest in large partnerships including cross-platform and multipost campaigns.For this exercise, I’ll suggest larger partnerships with large Influencers only.Previous ActivationsThen I’m looking for previous activations that they’ve done with similarly aligned brands. I want to see SOME activations, showing the type of content and the average engagements but I don’t want to see too many. I like to look for at least one post a month but not more than 1 post a week.If they saturate too much then their “influence goes down quite a bit.'' Now, you also need to test various channels. You may already know that Instagram works best for your business organically, but I also like to look at a few other outlier platforms like Pinterest and Youtube or even industry-specific forums for test engagements, or if Influencers have diverse audiences across multiple platforms we can test cross-platform multi-post engagements as well. For the sake of this exercise, I’ll just pick 5 relevant Influencers on Instagram.Here are the 5 Influencers I chose in 2 minutes for the above keywords:See original post for photos:​Note: You would want to try several other search terms, even with multiple words.Step 2) PitchSo if I am not dealing with an agency or a platform I start with a very simple cold outreach message like the email below:Or via DM to get their email and add them to my list of Influencers: 📷📷​See original post for photos:Take a moment to brainstorm and see if you have something valuable to offer the Influencers besides just cash. Many of them will say no to anything besides financial reward, but some ideas of other things to offer are below. Reach out to them with short succinct messages that are valuable and your response rate will be decent. Focus on Influencers who are not doing a lot of paid posts as they’re more likely to be interested in other value.Other Things that are valuable:-Free merch-Giveaways-Content Ideas-ExclusivesThe pitch then becomes more focused on collaboration with strict guidelines for content to ensure success. What I’ve found with Influencers is that the larger their audience, the lazier they tend to be, so we want to make it exciting by pitching large partnerships, but also hold them accountable with strict guidelines so they can’t “slack off” on the content creation, often trying to reuse content they’ve already created…The bottom line for all of my influencer pitches is how can I make an engagement with my brand more valuable to their audience than other brands that reach out to them. We want them to feel like this is valuable for more than just financial reasons...so coming at them with creative ideas and fun ideas that will delight and impress their followers will be best at helping them be ok with not getting a big paycheck. This is especially true for the under-100k Influencer.Also, if you have an upcoming event you can invite them to, it’s even better. Influencers love free stuff and that means swag, and party/event invites too, so if you’re doing an event or launch party you can invite all press and all potential Influencers and the pitch becomes something like this:📷See original post for photos:Note: the average response rate of an invite is like 75% for me..vs 35% for other messages.Step 3: CreateThe secret tip to having a successful Influencer Marketing campaign, is having control over the content. The more guidelines you give the Influencer the better the outcome. In my experience, content like the below works best...that is created solely to promote our product, with product placement in the post, showing the influencer using it, and actually believable. This is ideal. To have maximum engagement we want Influencers who would actually use the product.📷On the other end of the spectrum, a poor Influencer post is often just a random photo of just the Influencer, with the focus on the Influencer's sexuality/body and even other products in the post.📷See the difference in the total engagements between the above posts, now guess what? The influencer in the second image has a larger following (slightly) and we paid both engagements the same amount. So know exactly what you want them to do ahead of time. It helps to create a PDF kit that you can just email them as you sign them up. This entire process should only take a week’s worth of work for everything from sourcing, messaging, following up, PayPaling them etc. You can easily start off with 20-30 of these and see how it works for your business before scaling up to larger Influencers, and working with Agencies and bigger platforms/engagements at scale.As I’m writing this I’m wondering about all the negative comments I’ll get from other Digital Marketers out there who still shun the thought of engaging in Influencer Marketing. But the data doesn’t lie, for certain brands, with certain target demographics, this stuff really works, and the key is knowing how to do it. I hope this helps you scale your business. If you’ve got questions please comment below. You can also reach me by Googling my username.See original post for photos:
0 notes
suzanneshannon · 5 years
Text
What Hooks Mean for Vue
Not to be confused with Lifecycle Hooks, Hooks were introduced in React in v16.7.0-alpha, and a proof of concept was released for Vue a few days after. Even though it was proposed by React, it’s actually an important composition mechanism that has benefits across JavaScript framework ecosystems, so we’ll spend a little time today discussing what this means.
Mainly, Hooks offer a more explicit way to think of reusable patterns — one that avoids rewrites to the components themselves and allows disparate pieces of the stateful logic to seamlessly work together.
The initial problem
In terms of React, the problem was this: classes were the most common form of components when expressing the concept of state. Stateless functional components were also quite popular, but due to the fact that they could only really render, their use was limited to presentational tasks.
Classes in and of themselves present some issues. For example, as React became more ubiquitous, stumbling blocks for newcomers did as well. In order to understand React, one had to understand classes, too. Binding made code verbose and thus less legible, and an understanding of this in JavaScript was required. There are also some optimization stumbling blocks that classes present, discussed here.
In terms of the reuse of logic, it was common to use patterns like render props and higher-order components, but we’d find ourselves in similar “pyramid of doom” — style implementation hell where nesting became so heavily over-utilized that components could be difficult to maintain. This led me to ranting drunkenly at Dan Abramov, and nobody wants that.
Hooks address these concerns by allowing us to define a component's stateful logic using only function calls. These function calls become more compose-able, reusable, and allows us to express composition in functions while still accessing and maintaining state. When hooks were announced in React, people were excited — you can see some of the benefits illustrated here, with regards to how they reduce code and repetition:
Took @dan_abramov's code from #ReactConf2018 and visualised it so you could see the benefits that React Hooks bring us. pic.twitter.com/dKyOQsG0Gd
— Pavel Prichodko (@prchdk) October 29, 2018
In terms of maintenance, simplicity is key, and Hooks provide a single, functional way of approaching shared logic with the potential for a smaller amount of code.
Why Hooks in Vue?
You may read through this and wonder what Hooks have to offer in Vue. It seems like a problem that doesn’t need solving. After all, Vue doesn’t predominantly use classes. Vue offers stateless functional components (should you need them), but why would we need to carry state in a functional component? We have mixins for composition where we can reuse the same logic for multiple components. Problem solved.
I thought the same thing, but after talking to Evan You, he pointed out a major use case I missed: mixins can’t consume and use state from one to another, but Hooks can. This means that if we need chain encapsulated logic, it’s now possible with Hooks.
Hooks achieve what mixins do, but avoid two main problems that come with mixins:
They allows us to pass state from one to the other.
They make it explicit where logic is coming from.
If we’re using more than one mixin, it’s not clear which property was provided by which mixin. With Hooks, the return value of the function documents the value being consumed.
So, how does that work in Vue? We mentioned before that, when working with Hooks, logic is expressed in function calls that become reusable. In Vue, this means that we can group a data call, a method call, or a computed call into another custom function, and make them freely compose-able. Data, methods, and computed now become available in functional components.
Example
Let’s go over a really simple hook so that we can understand the building blocks before we move on to an example of composition in Hooks.
useWat?
OK, here’s were we have, what you might call, a crossover event between React and Vue. The use prefix is a React convention, so if you look up Hooks in React, you’ll find things like useState, useEffect, etc. More info here.
In Evan’s live demo, you can see where he’s accessing useState and useEffect for a render function.
If you’re not familiar with render functions in Vue, it might be helpful to take a peek at that.
But when we’re working with Vue-style Hooks, we’ll have — you guessed it — things like: useData, useComputed, etc.
So, in order for us look at how we'd use Hooks in Vue, I created a sample app for us to explore.
Demo Site
GitHub Repo
In the src/hooks folder, I've created a hook that prevents scrolling on a useMounted hook and reenables it on useDestroyed. This helps me pause the page when we're opening a dialog to view content, and allows scrolling again when we're done viewing the dialog. This is good functionality to abstract because it would probably be useful several times throughout an application.
import { useDestroyed, useMounted } from "vue-hooks"; export function preventscroll() { const preventDefault = (e) => { e = e || window.event; if (e.preventDefault) e.preventDefault(); e.returnValue = false; } // keycodes for left, up, right, down const keys = { 37: 1, 38: 1, 39: 1, 40: 1 }; const preventDefaultForScrollKeys = (e) => { if (keys[e.keyCode]) { preventDefault(e); return false; } } useMounted(() => { if (window.addEventListener) // older FF window.addEventListener('DOMMouseScroll', preventDefault, false); window.onwheel = preventDefault; // modern standard window.onmousewheel = document.onmousewheel = preventDefault; // older browsers, IE window.touchmove = preventDefault; // mobile window.touchstart = preventDefault; // mobile document.onkeydown = preventDefaultForScrollKeys; }); useDestroyed(() => { if (window.removeEventListener) window.removeEventListener('DOMMouseScroll', preventDefault, false); //firefox window.addEventListener('DOMMouseScroll', (e) => { e.stopPropagation(); }, true); window.onmousewheel = document.onmousewheel = null; window.onwheel = null; window.touchmove = null; window.touchstart = null; document.onkeydown = null; }); }
And then we can call it in a Vue component like this, in AppDetails.vue:
<script> import { preventscroll } from "./../hooks/preventscroll.js"; ... export default { ... hooks() { preventscroll(); } } </script>
We're using it in that component, but now we can use the same functionality throughout the application!
Two Hooks, understanding each other
We mentioned before that one of the primary differences between hooks and mixins is that hooks can actually pass values from one to another. Let's look at that with a simple, albeit slightly contrived, example.
Let's say in our application we need to do calculations in one hook that will be reused elsewhere, and something else that needs to use that calculation. In our example, we have a hook that takes the window width and passes it into an animation to let it know to only fire when we're on larger screens.
In the first hook:
import { useData, useMounted } from 'vue-hooks'; export function windowwidth() { const data = useData({ width: 0 }) useMounted(() => { data.width = window.innerWidth }) // this is something we can consume with the other hook return { data } }
Then, in the second we use this to create a conditional that fires the animation logic:
// the data comes from the other hook export function logolettering(data) { useMounted(function () { // this is the width that we stored in data from the previous hook if (data.data.width > 1200) { // we can use refs if they are called in the useMounted hook const logoname = this.$refs.logoname; Splitting({ target: logoname, by: "chars" }); TweenMax.staggerFromTo(".char", 5, { opacity: 0, transformOrigin: "50% 50% -30px", cycle: { color: ["red", "purple", "teal"], rotationY(i) { return i * 50 } } }, ...
Then, in the component itself, we'll pass one into the other:
<script> import { logolettering } from "./../hooks/logolettering.js"; import { windowwidth } from "./../hooks/windowwidth.js"; export default { hooks() { logolettering(windowwidth()); } }; </script>
Now we can compose logic with Hooks throughout our application! Again, this is a contrived example for the purposes of demonstration, but you can see how useful this might be for large scale applications to keep things in smaller, reusable functions.
Future plans
Vue Hooks are already available to use today with Vue 2.x, but are still experimental. We’re planning on integrating Hooks into Vue 3, but will likely deviate from React’s API in our own implementation. We find React Hooks to be very inspiring and are thinking about how to introduce its benefits to Vue developers. We want to do it in a way that complements Vue's idiomatic usage, so there's still a lot of experimentation to do.
You can get started by checking out the repo here. Hooks will likely become a replacement for mixins, so although the feature still in its early stages, it’s probably a concept that would be beneficial to explore in the meantime.
(Sincere thanks to Evan You and Dan Abramov for proofing this article.)
The post What Hooks Mean for Vue appeared first on CSS-Tricks.
What Hooks Mean for Vue published first on https://deskbysnafu.tumblr.com/
0 notes
siliconwebx · 5 years
Text
What Hooks Mean for Vue
Not to be confused with Lifecycle Hooks, Hooks were introduced in React in v16.7.0-alpha, and a proof of concept was released for Vue a few days after. Even though it was proposed by React, it’s actually an important composition mechanism that has benefits across JavaScript framework ecosystems, so we’ll spend a little time today discussing what this means.
Mainly, Hooks offer a more explicit way to think of reusable patterns — one that avoids rewrites to the components themselves and allows disparate pieces of the stateful logic to seamlessly work together.
The initial problem
In terms of React, the problem was this: classes were the most common form of components when expressing the concept of state. Stateless functional components were also quite popular, but due to the fact that they could only really render, their use was limited to presentational tasks.
Classes in and of themselves present some issues. For example, as React became more ubiquitous, stumbling blocks for newcomers did as well. In order to understand React, one had to understand classes, too. Binding made code verbose and thus less legible, and an understanding of this in JavaScript was required. There are also some optimization stumbling blocks that classes present, discussed here.
In terms of the reuse of logic, it was common to use patterns like render props and higher-order components, but we’d find ourselves in similar “pyramid of doom” — style implementation hell where nesting became so heavily over-utilized that components could be difficult to maintain. This led me to ranting drunkenly at Dan Abramov, and nobody wants that.
Hooks address these concerns by allowing us to define a component's stateful logic using only function calls. These function calls become more compose-able, reusable, and allows us to express composition in functions while still accessing and maintaining state. When hooks were announced in React, people were excited — you can see some of the benefits illustrated here, with regards to how they reduce code and repetition:
Took @dan_abramov's code from #ReactConf2018 and visualised it so you could see the benefits that React Hooks bring us. pic.twitter.com/dKyOQsG0Gd
— Pavel Prichodko (@prchdk) October 29, 2018
In terms of maintenance, simplicity is key, and Hooks provide a single, functional way of approaching shared logic with the potential for a smaller amount of code.
Why Hooks in Vue?
You may read through this and wonder what Hooks have to offer in Vue. It seems like a problem that doesn’t need solving. After all, Vue doesn’t predominantly use classes. Vue offers stateless functional components (should you need them), but why would we need to carry state in a functional component? We have mixins for composition where we can reuse the same logic for multiple components. Problem solved.
I thought the same thing, but after talking to Evan You, he pointed out a major use case I missed: mixins can’t consume and use state from one to another, but Hooks can. This means that if we need chain encapsulated logic, it’s now possible with Hooks.
Hooks achieve what mixins do, but avoid two main problems that come with mixins:
They allows us to pass state from one to the other.
They make it explicit where logic is coming from.
If we’re using more than one mixin, it’s not clear which property was provided by which mixin. With Hooks, the return value of the function documents the value being consumed.
So, how does that work in Vue? We mentioned before that, when working with Hooks, logic is expressed in function calls that become reusable. In Vue, this means that we can group a data call, a method call, or a computed call into another custom function, and make them freely compose-able. Data, methods, and computed now become available in functional components.
Example
Let’s go over a really simple hook so that we can understand the building blocks before we move on to an example of composition in Hooks.
useWat?
OK, here’s were we have, what you might call, a crossover event between React and Vue. The use prefix is a React convention, so if you look up Hooks in React, you’ll find things like useState, useEffect, etc. More info here.
In Evan’s live demo, you can see where he’s accessing useState and useEffect for a render function.
If you’re not familiar with render functions in Vue, it might be helpful to take a peek at that.
But when we’re working with Vue-style Hooks, we’ll have — you guessed it — things like: useData, useComputed, etc.
So, in order for us look at how we'd use Hooks in Vue, I created a sample app for us to explore.
Demo Site
GitHub Repo
In the src/hooks folder, I've created a hook that prevents scrolling on a useMounted hook and reenables it on useDestroyed. This helps me pause the page when we're opening a dialog to view content, and allows scrolling again when we're done viewing the dialog. This is good functionality to abstract because it would probably be useful several times throughout an application.
import { useDestroyed, useMounted } from "vue-hooks"; export function preventscroll() { const preventDefault = (e) => { e = e || window.event; if (e.preventDefault) e.preventDefault(); e.returnValue = false; } // keycodes for left, up, right, down const keys = { 37: 1, 38: 1, 39: 1, 40: 1 }; const preventDefaultForScrollKeys = (e) => { if (keys[e.keyCode]) { preventDefault(e); return false; } } useMounted(() => { if (window.addEventListener) // older FF window.addEventListener('DOMMouseScroll', preventDefault, false); window.onwheel = preventDefault; // modern standard window.onmousewheel = document.onmousewheel = preventDefault; // older browsers, IE window.touchmove = preventDefault; // mobile window.touchstart = preventDefault; // mobile document.onkeydown = preventDefaultForScrollKeys; }); useDestroyed(() => { if (window.removeEventListener) window.removeEventListener('DOMMouseScroll', preventDefault, false); //firefox window.addEventListener('DOMMouseScroll', (e) => { e.stopPropagation(); }, true); window.onmousewheel = document.onmousewheel = null; window.onwheel = null; window.touchmove = null; window.touchstart = null; document.onkeydown = null; }); }
And then we can call it in a Vue component like this, in AppDetails.vue:
<script> import { preventscroll } from "./../hooks/preventscroll.js"; ... export default { ... hooks() { preventscroll(); } } </script>
We're using it in that component, but now we can use the same functionality throughout the application!
Two Hooks, understanding each other
We mentioned before that one of the primary differences between hooks and mixins is that hooks can actually pass values from one to another. Let's look at that with a simple, albeit slightly contrived, example.
Let's say in our application we need to do calculations in one hook that will be reused elsewhere, and something else that needs to use that calculation. In our example, we have a hook that takes the window width and passes it into an animation to let it know to only fire when we're on larger screens.
In the first hook:
import { useData, useMounted } from 'vue-hooks'; export function windowwidth() { const data = useData({ width: 0 }) useMounted(() => { data.width = window.innerWidth }) // this is something we can consume with the other hook return { data } }
Then, in the second we use this to create a conditional that fires the animation logic:
// the data comes from the other hook export function logolettering(data) { useMounted(function () { // this is the width that we stored in data from the previous hook if (data.data.width > 1200) { // we can use refs if they are called in the useMounted hook const logoname = this.$refs.logoname; Splitting({ target: logoname, by: "chars" }); TweenMax.staggerFromTo(".char", 5, { opacity: 0, transformOrigin: "50% 50% -30px", cycle: { color: ["red", "purple", "teal"], rotationY(i) { return i * 50 } } }, ...
Then, in the component itself, we'll pass one into the other:
<script> import { logolettering } from "./../hooks/logolettering.js"; import { windowwidth } from "./../hooks/windowwidth.js"; export default { hooks() { logolettering(windowwidth()); } }; </script>
Now we can compose logic with Hooks throughout our application! Again, this is a contrived example for the purposes of demonstration, but you can see how useful this might be for large scale applications to keep things in smaller, reusable functions.
Future plans
Vue Hooks are already available to use today with Vue 2.x, but are still experimental. We’re planning on integrating Hooks into Vue 3, but will likely deviate from React’s API in our own implementation. We find React Hooks to be very inspiring and are thinking about how to introduce its benefits to Vue developers. We want to do it in a way that complements Vue's idiomatic usage, so there's still a lot of experimentation to do.
You can get started by checking out the repo here. Hooks will likely become a replacement for mixins, so although the feature still in its early stages, it’s probably a concept that would be beneficial to explore in the meantime.
(Sincere thanks to Evan You and Dan Abramov for proofing this article.)
The post What Hooks Mean for Vue appeared first on CSS-Tricks.
😉SiliconWebX | 🌐CSS-Tricks
0 notes
marcosplavsczyk · 6 years
Link
Have you ever gotten a new computer, hooked it up and said: “this computer is blazing fast, I love it”? I have. A year from then, I was like “this computer is so slow, I need a new one”.
Performance is a big deal and this was the opening line in an article that was written on How to optimize SQL Server query performance. The initial article shows not only how to design queries with the performance in mind, but also shows how to find slow performance queries and how to fix the bottlenecks of those queries. I’d highly recommend reading the above article first because this one would give a lot more meaning but also because it’s an appendix to this topic.
Before we continue further, here’s a quick recap of the covered subjects and their main goals:
Query optimization overview – In this part, we got familiar with what query plans are all about. This part explained in detail how query plans help SQL Server in finding the best possible and efficient path to the data and what happens when a query is submitted to SQL Server including steps that it goes through to find those routes. Furthermore, we also covered statistics and how they help the Query Optimizer to build the most efficient plan so that SQL Server can find the best way to fetch data. We also mentioned a few tips and tricks (guidelines) on how to be proactive in designing queries with the performance in mind to ensure that our queries are going to perform well right out the gate.
Working with query plans – Here we jumped over to a free tool called ApexSQL Plan to get familiar with query plans and understand how to “decipher” them which will ultimately help us find the bottlenecks in slow performance queries. We mentioned statistics again, but this time we’ll also show where they’re stored in SQL Server and how to view them. Furthermore, these statistics can be maintained and kept up-to-date to ensure that the Query Optimizer will create best guesses when fetching data. We also covered examples of different use case scenarios on how SQL Server is accessing data using full table scan vs full index scan vs index seek, etc.
Optimizing query performance – In the last part, we put some of those guidelines from previous sections into use. We took a poorly designed query and applied design techniques to practice by writing it the right way. At the end, we wrapped things up with best practices and some guidelines. We barely touched a few topics that play a big role when it comes to querying performance and the purpose of this article is to get familiar with those topics in detail and put them to practice with some examples.
So, let’s first summarize what’s happening under the hood when we hit that execution button. Think of a query/execution plan as just a map. It’s a map that SQL Server is drawing of the most efficient path to the data. When SQL Server accepts a query coming from either an application or directly from a user, it passes it to the Query Optimizer which will then create a query/execution plan:
This execution plan is just SQL Server method to access data stored in data pages on disk. These query plans require resources to create and therefore SQL Server will cache them:
The next time a query comes in and has a similar Where clause or path to the data, SQL Server will reuse the query plan for performance game. There are of course aging algorithms that will remove old query plans from the cache, but this is internal stuff and, as always, SQL Server does a great job at managing it.
Statistics
So, we already said that statistics are important because they help the Query Optimizer. We also briefly described that statistics hold information about columns the Query Optimizer uses to generate query plans. You might be wondering how exactly statistics help the Query Optimizer to make its best guesses when accessing data? Here’s a good analogy to answer this question. If you ever planned a party, most of the time when people send invitations they’ll say, “please RSVP” which basically means “please respond” whether or not they plan to attend the party. They do this so they can plan accordingly: how much food to order, how many drinks to get, etc. because this allows them to have a better estimate of all those stuff they need so they don’t get too many or too little and that’s exactly what statistics do. The more up-to-date statistics are the better decisions will Query Optimizer create on how to execute a query and find data the efficient way.
The statistics are created on indexes and columns. So, the first thing we can do is to run the sp_helpstats stored procedure that returns statistics information about columns and indexes on the specified table. Run the query below passing the name of your table and the “ALL” parameter that will give us both the indexes and statistics that are generated for the specified table:
sp_helpstats[ @objname = ] 'object_name' [ , [ @results = ] 'value' ]
Executing this command will return all auto-generated and managed statistics and indexes by SQL Server:
This is as basic as it gets. However, we can run DBCC SHOW_STATISTICS command to displays current query optimization statistics for a specific table or indexed view. Again, passing a name of your table and a name of statistics:
DBCC SHOW_STATISTICS ( table_or_indexed_view_name , target )
In this case, we’re going to look at the primary key (PK_Customer_CustomerID) of the CustomerID which is clustered index that will show us all statistics information:
The returned table information in the result set shows various useful information like a total number of rows in the table or indexed view when the statistics were last updated, an average number of bytes per value for all the key columns in the statistics object, a histogram with the distribution of values in the first key column of the statistics object, etc. The point is all those stats are going to help the Query Optimizer in making the best decision to create the best execution plan possible.
This exact information is also available from Object Explorer. If we navigate to a table in a database, there should be a Statistics folder under it which holds the data we previously saw in the result set. To do this, right-click a statistic and choose Properties at the bottom of the context menu:
If we switch over to Details page in the top left corner, we’ll see the exact same data that we were just looking at:
We did mention that SQL Server manages to update of these statistics automatically and you can verify this setting by going to your database in Object Explorer, right-clicking it and choosing the Properties command at the bottom of the context menu:
If we switch over to Options page in the top left corner, you should see under the Automatic rules two items: Auto Create Statistics and Auto Update Statistics options set to True:
Probably a good idea to leave those enabled unless you want full control over statistics creation and updating. However, if e.g. there is a reason to update them manually we can just go to statistic’s properties and under the General page, you’ll find the Update statistics for these columns option. Here’s also the information on when the statistics were last updated. Select this option and hit the OK button to automatically do an update on the spot:
The Query Optimizer determines when statistics might be out-of-date and then updates them when needed for a query plan. If you’re wondering how we can tell if the statistics are getting stalled, well we can usually see this by looking at the execution plan. How? In most situations just by looking at the estimated rows and actual rows. If we hold the mouse over an operation it will bring up the tooltip in which we can see if there’s a big gap between the Actual number of rows and Estimated number of rows then we know that statistics need to be updated. In the case below both numbers are the same which means the statistics are up-to-date, so update those manually only if the numbers are wildly off:
Joins
In the initial article, we covered different types of scans and indexes. Often, we write complex queries with multiple tables involved, joining data from different tables. Well, this is where SQL Server internally has three different ways to tie data from multiple tables together joining them. We know it, in the T-SQL world, as the Join statement but SQL Server under the hood has many ways that it can join data together and it’s always going to choose the best one. I just want to show you how they look like in execution plans and because it’s good to know in general how SQL Server internally brings data together.
Let’s start off by writing a simple Join statement of two tables. We can actually force the Query Optimizer to use a specific type of join when it joins tables together. This can be done by using either loop, hash, or merge options that enforces a particular join between two or more tables. The following example uses the AdventureWorks2014 database:
SELECT p.ProductID, p.Name, p.ListPrice, p.Style FROM Production.Product p JOIN Sales.SalesOrderDetail sod ON p.ProductID = sod.ProductID OPTION(LOOP JOIN)
If we look at the execution plan of the above query in ApexSQL Plan, we’ll see that SQL Server is doing a loop join. What this loop basically does is for each row in the outer input, it’s scanning the inner input and if it finds a match it’s going to output it into results:
If this is the best way to join data? Well, let’s execute the same query but without forcing the type of join. To do this, just remove the options parameter. This time the Query Optimizer chose the merge join:
I’m sure that some will say, “Hey, we just went from 34.9% to 43.8%. How is that good”. Well, that’s not the point. Similar to the rules for index scans vs index seeks, some rules apply in general but do not necessarily mean that it will always be the most efficient way. Also, most of the cost will come from merge join because it has to sort the data. Bear with me, we can prove this by hitting the History tab from the main menu to view the execution plans for both queries. If we look at the Execution time column, note the time counter is 2.32 when we forced the loop join and less when the Query Optimizer chose merge join:
Furthermore, we can also check both plans and hit the Compare button to see additional stats and from this example, we can see that merge join is performing much better just by looking at the reads columns:
Let’s also see what a hash join does by forcing the execution plan to use it:
Numbers can be confusing sometimes. What I like to do is put all three joins in the same query text and look at the execution plan:
What we get in the execution plan when placing multiple statements is an overview of total query cost relative to the batch. In this case, if we select the statement with the merge join, which is also the type of join SQL Server will choose by default, we can see below in the execution plan that the total query cost is 20.1%:
If we switch over to other two, we can see that the loop join took 46.6% and the hash join took 33.3%:
So, the hash join is for large amounts of data. It’s really the work course that SQL Server is going to use for things like table scans or index scans, anything that isn’t a seek, also in cases when it’s a seek but still, it’s pulling a large amount of data.
Now, the general rule of thumb is nested loops are good for small amount of data. The SQL Server will most likely choose this type of join when there’s not a lot of data to work with. You’ll see the merge join with a medium amount of data, and the hash joins with a large amount of data. If the queries are covered with indexes, SQL Server will work with less amount of data and this is where loop joins are most likely to be seen. On the other hand, if you’re missing indexes, SQL Server will work with a large amount of data (table scans) and you’ll probably see hash joins or at least merge joins.
Index Tuning Wizard
Back to indexes, remember that we should revisit them often. On a database with a large number of objects this sound like mission impossible. Not really. Let’s take a look at one tool, part of SQL Server, that’s called Index Tuning Wizard which can help us with this stuff. Remember that the biggest single thing we can do in our databases performance-wise is have a good indexing strategy.
So, let’s get familiar with this Index Tuning Wizard and see what we can do with it. This tool can be used when developing an application, database, or query. The first thing we should do is to set up a workload. This is done by running a query against your database and trapping the results. Then we can send these results to Index Tuning Wizard which will tell us, based on the query itself and results, what should be indexed and covered by statistics and give us recommendations in general.
A workload is just a set of T-SQL statements that execute against a database that we want to tune. So, next step is to either type our T-SQL script into the Query Editor or use e.g. existing stored procedures (turn them into a workload). To simplify this example, we’re going to use a series of the most used Select statements that are hitting our database. As shown below, this is just five frequently used Select statements in one query:
It’s always a good idea to execute the batch just to verify that the query is valid and that the result set is without warning or errors. Also, after a successful execution, the status bar of SSMS will present the number of rows returned and the total duration time. As we can see from this example, the whole process took over ten minutes and returned 242K+ number of rows which is a pretty good workload:
All we should do now is save the file with a .sql extension:
Next, on the SQL Server Management Studio Tools menu, click Database Engine Tuning Advisor:
This will pop-up the Connect to Server dialog, so leave everything as it is or make the appropriate changes and hit the Connect button to continue:
In the next window, we need to set a few things up before we can continue further:
Browse for the workload file that was previously created
Select the appropriate database for workload analysis
Select the appropriate database and tables to tune
Click the Start Analysis button to start the next tuning step
The Progress bar shows information about actions taken and their status:
It will go thru the steps of tuning five times and once it’s done it will move on to next step (Recommendations tab). This step might take a while, but once it’s done, a list of index recommendations will be shown. There’s also estimated improvement number (75% in this case) which is informative in its way. Is it true? Well, let’s finish the optimization and check the results later:
If we scroll horizontally to the right, there’s a column called Definition under which there’s a preview T-SQL code for creating those missing indexes and statistics:
Clicking on a link from the Definitions list will open the SQL Script Preview window showing the T-SQL script for creating missing indexes and statistics which can be copied to the clipboard and used later:
Instead of copying each script one-by-one to the clipboard (when the list is long), we can save all the recommendations by clicking the Save Recommendations command in the Actions menu:
Once it’s done, this newly created script can be executed against the targeted database:
Go back to SSMS, open the script and execute it. There should be a message that the command completed successfully:
Most of us would not be able to figure it out exactly how to create these best possible indexes and statistics, but this tool makes our lives easier.
Back to the estimated improvement number… how did creating the indexes and statistics improved overall performance? Good. Running the same heavy query, the execution time went down almost by a half.
Bear in mind that the number represented in the Database Engine Tuning Advisor is just an estimation. The results might vary but overall there should be an improvement.
One last thing, also getting familiar with Dynamic Management Views (DMV) can also help us find slow performing queries. This tool can be used to find poor or long time running queries. It is actually just a collection of views and functions that can be run to find information about SQL Server. These views and functions return data about what is going on in SQL Server. There’s a lot of docs on Microsoft official site and they’re also categorized nicely, so it’s highly recommended to check out online books and find out more about DMVs.
Here are the two quick ones that can be used in the real word on any SQL Server:
-- Return top 10 longest running queries SELECT TOP 10 qs.total_elapsed_time / qs.execution_count / 1000000.0 AS AverageSeconds, qs.total_elapsed_time / 1000000.0 AS TotalSeconds, qt.text AS Query, DB_NAME(qt.dbid) AS DatabaseName FROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt LEFT OUTER JOIN sys.objects o ON qt.objectid = o.object_id ORDER BY AverageSeconds DESC;
The above query will return the top 10 longest running queries in a database. All this query does is basically just running the sys.dm_exec_query_stats view that returns information about a query that is sitting in a database specified in the Select statement and then cross apply it to a table value function passing the handle (which is a column from a view) which will give us the actual query that was executed.
The query below will return the top ten expensive queries in term of input/output (disk read operations):
-- Return top 10 most expensive queries SELECT TOP 10(total_logical_reads + total_logical_writes) / qs.execution_count AS AverageIO, (total_logical_reads + total_logical_writes) AS TotalIO, qt.text AS Query, o.name AS ObjectName, DB_NAME(qt.dbid) AS DatabaseName FROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt LEFT OUTER JOIN sys.objects o ON qt.objectid = o.object_id ORDER BY AverageIO DESC;
Neither of them will return any data in this case because there’s no real activity in the environment (SQL Server) set up for this article but use these on a big server that has a lot of activity and the results set will be filled with data.
I’d wrap things up by saying one last tip and that is to also get familiar with SQL Server Profiler. With this tool, we can set up a trace against a server or database and basically trap all the statements coming into either server or database. Furthermore, this tool allows us to see exactly what is hitting our server, what data is being passed and parameters, logins, and logouts, etc. It also integrates with the Index Tuning Wizard, we saw it when we created the workload. Once you get the hang on all these tools and you combine them with the executions plans, the query troubleshooting will become much easier.
I hope these two articles have been informative for you and I thank you for reading.
How to optimize SQL Server query performance
How to optimize SQL Server query performance – Statistics, Joins and Index Tuning
Useful links
Statistics
How to: Create Workloads
Start and Use the Database Engine Tuning Advisor
System Dynamic Management Views
SQL Server Profiler
  The post How to optimize SQL Server query performance – Statistics, Joins and Index Tuning appeared first on Solution center.
0 notes
blountlygreen · 7 years
Text
Designing in Circles-Designing a Home Part 2
Well, quick pro tip-don't decide to do weekly updates just as work is going to get busy. I'm going to try and catch up this week-goal is to try and post something every day for the next seven days! Let's see how it goes...
Onto our regularly scheduled content:
When it comes to designing a home, something I wanted to keep in mind was how much material goes into building a home. Short of digging a hole in a ground and calling it home, a house is going to take a lot of resources. Some people might point out the benefits of scavenging, but it depends where you live. If you're having to drive long distances for 'free' stuff on Craigslist and looking for building sites with a lot of scrap, probably in a big truck, that isn't as resource friendly as you might hope. It is also important to keep in mind building for longevity-using green materials is great, but if they aren't going to last well, you might want to reconsider.
Anyways, the point is is that I knew trying to design a 'green' home wasn't as simple as just buying everything with a sticker that says, "Environmentally friendly!" Not to mention doing that wasn't personally affordable, since it seems like businesses have learned that people will pay more to save the environment and will price accordingly even if it isn't justified.
So, my first idea was building a home from repurposed materials. I thought homes built from old buses, trains, and shipping containers was a pretty awesome idea (for awhile I was a huge fan of the TV show You Live in What?). At least in principle, but I wanted something that wasn't so narrow-cue in one of my personal favorites grain silo houses. It seemed a beautiful mix of reuse and a look that appealed to me (my dad, on the other hand, was horrified). So why didn't I go with that? This part of Alabama is more about meat production than farming, and several sources failed me when it came to finding anything used. I didn't like the idea of having something shipped across the U.S. for multiple reasons, which left the only option buying new which rather defeated the point. If you live in an area that has more silos available, however, I highly recommend looking into it. I think it's a really cool way to build while using fewer materials.
I said we went around in circles last post when it came to figuring out what direction we were going in and I wasn't kidding. Tiny home vs. small home. Round vs. square vs. rectangle. Wood vs. earthbag vs. straw. The debate raged for several weeks while we worked on prepping the site.
So, let's break it down for anyone in a similar situation. I really like a lot of things about the tiny house movement. It would have been quicker to build and used fewer materials. However, I ended up going with a small house instead (I am defining tiny as under 500 square feet and small under 1,000) because I knew I was going to have semi-frequent visitors who'd be spending at least one night if not more, and I didn't want them to feel cramped. Also, in line with my previous post I was concerned about trying to sell a tiny house if it ever came to it.
Next is the shape of a house. A round house gets you the best square footage and is also very resistant to wind (we get a lot of tornadoes so this was a consideration). Unfortunately, despite the larger amount of space you end up with some really funky room designs the smaller you get and things got crowded. If you are ok with an open house plan it might work better, but I was going with a two bedroom design at this point. After a house that is round a square one is best for footage, but the shape of the property was better suited for a rectangle, so that is what we ended up with. Don't forget to incorporate where you are building into your planning (more on that later).
Finally, building materials. Boy, this was a doozy. Dad lives in a beautiful straw-bale house and was quite hopeful I would follow his example (especially since he had prior experience with it), but my personal tastes lean away from the typical straw-bale look which is white or some shade of brown stucco galore. I like things a little more broken up color wise and definitely smoother. Earthbag construction was similar to strawbale in that it is often sealed with a stucco or plaster, and dad didn't have any familiarity with it so we put that aside pretty quickly. I found a Japanese technique I loved for wood, Shou Sugi Ban where you use fire to create a natural repellent to insects, weather, and, ironically, fire. The common technique is to burn the outside of the wood, clean off the excess char (unless you're doing an alligator look), and use an oil like linseed or tung oil to seal.
Dad was leery of doing a house in wood, and especially doing that much burning, so I took another look at strawbale and came to a compromise. If we could break up the stucco some and try to smooth the walls out more than he did on his, we were good to go on straw-bale construction.
With the size, shape, and materials nailed down it was time to do a house plan. I started out using a cool app called Home Design 3D that I had a lot of fun with. For ideas, there's a great great site called Dream Green Homes which specializes in plans that are made with environmentally friendly materials (including round plans!) It is obviously also a good option if you want to skip making your own plan and just buy one. One of the tips I got off of there is to try and design your house to have as much of the plumbing on one interior wall as possible, which made sense and was something I incorporated into my own design.
My best advice here is to look through as many different plans as you can, pick what you like, and play around a lot with something like the home design app I mentioned. Also, if you have the space use stakes and string or something to stake out your plan in the making. Being able to do that was what helped me decide against a round house and also part of what inspired me to do a bigger house. Make sure it is something you are ultimately going to be comfortable in, because once you start it is hard to go back.
And my last tip for this section is that I did my final plan in Google Sheets. Yes, you read that right. Google Sheets. I made my pixel sizes the same for the rows and columns, numbered the top and bottom, and used the gridlines and color options to design my house. Home Design 3D doesn't have a single paid version option, but instead several paid upgrades and it wasn't worth it when I was familiar enough with Google Sheets to make my favorite house plan there instead. This might not work on a bigger project, but for the size I ended up with it was fine.
Tomorrow I'll be talking about my house plan specifically, the different features I put in, and why. I'll also go over a little more in depth about straw-bale, including some warnings for anyone considering using straw-bale construction.
0 notes
mikegchambers · 7 years
Text
7 AWS Lambda Tips from the Trenches
Fourthcast has used AWS Lambda to host Alexa skills since the early days and learned a lot of pitfalls and valuable lessons
The Fourthcast development team has been using AWS Lambda to host Alexa skills since the early days of the Alexa Skills Kit. Lambda, at times, can be like your neighbor’s pit bull. Sure it looks all cute an fluffy, but you know at anytime something viscous could happen. We’ve experienced many of those “Lambda bites”. Here’s what you should do to avoid them yourself.
1. Keeping your instances warm
You may already know that Lambda functions, when not used for a while, get recycled. The next invocation will require redeploying the function, which takes some extra time and thus additional latency to your users. We call this a “cold” invocation, as opposed to a “warm” invocation.
What you may not have known is that cold invocations are much worse if your Lambda function uses the network. The table below shows some timings of invoking a very simple lambda skill. Invoking a cold non-networked function takes 7 times as long as a warm one. But a cold function that uses network takes 15 times longer than a network-using warm function.
Even worse, if your function is inside a VPC, it can take more than 10 seconds to attach the Elastic Network Interface. We’ve had production skills timeout without ever really don’t a thing besides trying to talk to the network on a cold start.
To address this, Fourthcast uses a warming trigger on all of our Lambda functions. We attach the CloudWatch Events — Schedule trigger with a 5 minute period. Since Lambda functions go cold at around 7 minutes of non-use, this keeps the function warm pretty much continually, and significantly improves startup latency.
A warming trigger on a skill
However, be warned that your function won’t stay active forever. Redeploying code or changing configuration will always cause a recycle. Also Alexa skills with heavy and concurrent use will require multiple deployments to run simultaneously. That second (or third) deployment will start cold. The warming function only keeps one deployment warm. Finally Lambda functions are automatically recycled periodically. We see a forced recycle about 7 times a day.
If you use the warming trigger, be sure to ignore events without the Alexa request key, and don’t rely on your invocation count to be meaningful for analytics anymore. Also don’t worry about the additional costs. Even at the biggest instance size, you’ll only be using up about 9,000 of your 266,667 free invocations allowed per month. If you use that much, you probably don’t need to warm your skill anyway.
2. Upgrade to Node.js 6.10
If you’re not a Node.js team, great … move on your merry way! But if you’ve got skills using Node.js 4.3, it’s time to upgrade.
Node.js 4.3 had several annoying bugs, but the worst among them is an OpenSSL bug that you wont’ discover until you’re running under load in production. This little doozy will put your entire function into a bad state. SSL connections will fail without cause intermittently, but only if you’re using DynamoDB. There’s a work around, but mostly, just upgrade to Node.js 6.10.
3. Finish What You Started
In programming models that support async operations (here’s looking at you Node.js), it’s possible, and sometimes easy, to finish your function and hand a response back to Alexa before everything has finished processing.
Aysnc operations that get caught up in the Lambda freeze/thaw are absolute death. They’ll pop back to life in some later invocation, but will likely be timed out. The tell-tale sign is bizarre timeouts with request id’s in Cloudwatch that correspond to requests issued hours earlier. These kinds of errors can often push libraries or OpenSSL into odd failure states that can only be resolved by forcing a redeploy, such as resizing the function.
Notice that the request id of the logged events are not the same as the request they were reported in. These are echoes from a failed prior invocation. Very bad.
You don’t want these kinds of Heisenbugs. Look carefully for anything that is executing in async, but not on the logical path to completing the Lambda function. The normal culprits for us have been caching puts and analytics. Since they’re not critical to the skill logic, you do not know that they didn’t finish. One such error caused us to believe we were logging analytics for 6 months before we realized maybe only one in three datums were actually stored. Also avoid any async work done at startup, outside of the handler.
While you shouldn’t rely on this, make sure that you’re using the callback rather than any of the functions on the context object to complete the invocation. This will do a best-effort to complete in-flight async operation before freezing your function.
4. Set Timeouts Shorter
Most libraries for async operations come along with long default timeout periods. In Node.js it is normally 2 minutes. With Alexa, if you’re not answering the user within 7.5 seconds, Alexa will respond with a failure message for you. A well-behaved skill should be much faster than that.
It’s much better to fail an async operation early and be able to tell the user that something is wrong in your own words rather than to get the dreaded, “There was a problem with the requested skill’s response” message. Also, debugging long-running calls that have been frozen, as mentioned above, are a huge pain.
In the case of interacting with an AWS service via the SDK, make sure you also set a low value for maxRetries, since these are cumulative with timeouts.
5. Avoid Global State
Because of container reuse, it’s possible to stuff data into global memory and ,with a good probability, it will be there in the next invocation. However, despite the fact that we’ve seen major tool libraries for Alexa leverage this, it should be strongly avoided. A deployment can be recycled at any time for many different reasons. Also there is no guarantee that requests within the same session will be routed to the same deployment.
I have also seen some debate about if it’s OK to store data in global state that will be used again strictly within the same request. Normally in Node.js (e.g. in an express based website) this is a huge red-flag, since that state could be clobbered by other interleaving requests. However, while I can’t find any documentation that guarantees this, in practice Lambda will not issue a request to an instance if another is currently in-flight. Because of this, using global state in a single request is possible, but I wouldn’t rely on it. It’ll mean weird bugs if you migrate off of Lambda.
In short, avoid using global memory. At Fourthcast we use global state only as a first-level cache.
6. Log Your Own Errors in Cloudwatch
Most our skills at Fourthcast catch any errors and return a user-friendly error message. If you do this, make sure that you log custom metrics for tracking these “soft errors” since Lambda’s invocation error metrics won’t be relevant anymore. At Fourthcast we use a custom Cloudwatch metric for soft errors, which allows as to attach an alarm and be alerted of high error rates.
7. Give It Some Room
Run you skill at one of the higher memory levels. The low memory instances are also allocated a smaller slice of processor and have very slow file and network IO. Many mysterious errors clear up when we’ve suddenly got more memory. With Lambda’s very generous free tier, you’re not likely to incur costs anyway, so go ahead, set it to 1536 MB.
Lambda is the perfect tool for hosting Alexa skills, but you’ve got to watch out for these pitfalls and “Lambda bites”. At Fourthcast, we’ve hosted all of our skills using Lambda, and don’t miss fiddling with servers at all.
Fourthcast is a service that takes your podcast, and turns it into an Alexa skill. 33 million people will own a voice-first device in 2017. What will they listen to? Put your podcast on Alexa in just a few clicks! Get Started!
Have a podcast and want to try it out? Get Started!
7 AWS Lambda Tips from the Trenches was originally published in A Cloud Guru on Medium, where people are continuing the conversation by highlighting and responding to this story.
from A Cloud Guru - Medium http://ift.tt/2rfoqrt
0 notes