Podcasts about ios safari

  • 17PODCASTS
  • 19EPISODES
  • 41mAVG DURATION
  • 1MONTHLY NEW EPISODE
  • Jan 29, 2024LATEST

POPULARITY

20172018201920202021202220232024


Best podcasts about ios safari

Latest podcast episodes about ios safari

Digitalia
Digitalia #708 - Come Ti Frego

Digitalia

Play Episode Listen Later Jan 29, 2024 92:56 Transcription Available


Apple rilascia le nuove regole dedicate al mercato europeo sulla base del Digital Market Act. I commenti di Spotify e Mozilla. La fine dei videogiochi in formato fisico porta problemi di accessibilità. Le immagini false di Tailor Swift. Queste e molte altre le notizie tech commentate nella puntata di questa settimana.Dallo studio distribuito di digitalia:Michele Di Maio, Francesco Facconi, Massimo De SantoProduttori esecutivi:Alberto Sartori, Davide Tinti,Valerio Bendotti, Giuseppe Marino, Paola Danieli, Giulio Magnifico, Mattia Lanzoni, Luca Di Stefano, Nicola Bisceglie, Fabio Filisetti, Andrea Bottaro, Alberto Cuffaro, Elisa Emaldi - Marco Crosa, Gabriele Di Lorenzo, Antonio Gargiulo, Douglas Whiting, Dardi Massimiliano, Daniele Corsi, Mirto Tondini, Maurizio Galluzzo, Fabrizio Mele, Gianluca Fulli, Giuliano Arcinotti, Nicola Gabriele Del Popolo, Alessio Pappini, Giuseppe Brusadelli, Nicola Fort, Nicola Gabriele Del Popolo, paolo bernardini, Feró, @michele_da_milano, @jh4ckal, Idle Fellow, @21milionman, Fiorenzo Pilla, Anonymous, @juleeho, ArzigogoloSponsor:Links:Apple is finally allowing full versions of Chrome and Firefox on iPhoneApple announces support for third-party iPhone app stores in the EUUpdate on apps distributed in the European UnioniPad users will miss out on third-party app stores and moreApple announces changes to iOS Safari and the App Store in the EUApple Details How It Plans to Comply with the EUs DMAApple's Deliciously Dripping with Disdain Press ReleaseApples Plans for the DMA in the European UnionApples new extortion regime to keep big app makersApples Proposed Changes Reject the Goals of the DMA SpotifyMozilla says Apples new browser rules are as painful as possibleFortnite back on iOSThe loss of GAMEs trade-ins is a blow to video game accessibility23andMe admits hackers stole raw genotype dataNew Hampshire robocall kicks off era of AI-enabled election disinformationTaylor Swift Is Living Every Womans AI Porn NightmareEric Schmidt quietly created a company called White StorkGingilli del giorno:How do Video Games Graphics work?GammaNoclipSupporta Digitalia, diventa produttore esecutivo.

Apple Coding Daily
Se anuncian cambios en iOS, Safari y el App Store en la Unión Europea

Apple Coding Daily

Play Episode Listen Later Jan 25, 2024 29:09 Transcription Available


Apple tenía de límite hasta el próximo 7 de marzo de 2024 y ya tenemos su alternativa para cumplir la Ley de Mercados Digitales de la Unión Europea encima de la mesa. A partir de marzo, Apple permitirá las tiendas alternativas al App Store, nuevos medios de pago (incluso dentro del App Store), cambios en los navegadores, el NFC y otra serie de elementos que se abren para cumplir con la Ley. Los desarrolladores podrán acogerse a dos tipos de acuerdo de pago dentro de la Unión Europea y ciertos desarrolladores con unas condiciones muy concretas podrán ofrecer tiendas alternativas aunque las apps se seguirán revisando como hasta ahora. Te explicamos, punto por punto, todos los cambios que llegarán al App Store desde marzo de 2024 en la Unión Europea y qué repercusión tendrá para los usuarios y los desarrolladores. Convierte en un Senior iOS Developer con el Swift Full Stack Bootcamp. Encuentra toda la información aquí: IV Swift Full Stack Bootcamp 2024. Descubre nuestro canal de Twitch en: twitch.tv/applecoding. Descubre nuestras ofertas para oyentes: - Cursos en Udemy (con código de oferta) - Apple Coding Academy - Suscríbete a Apple Coding en nuestro Patreon. - Canal de Telegram de Swift. Acceso al canal. --------------- Consigue las camisetas oficiales de Apple Coding con los logos de Swift y Apple Coding así como todo tipo de merchadising como tazas o fundas. - Tienda de merchandising de Apple Coding. --------------- Tema musical: "For the Win" de "Two Steps from Hell", compuesto por Thomas Bergensen. Usado con permisos de fair use. Escúchalo en Apple Music o Spotify.

The Bike Shed
328: Terrible Simplicity

The Bike Shed

Play Episode Listen Later Mar 1, 2022 52:36


Chris is helping with efforts to introduce security, practices, and policies at Sagewell. Right now, they are refining the usage of 1Password to standardize passwords and secure information. He also shares (what he believes) is a terrible idea around fixing inconsistencies around symbols and strings. Steph shares an update around factories. Also, at Sagewell, Chris is helping to build mobile apps, one for iOS and one for Android, and is considering pursuing having them be all native. Good idea? Terrible idea? Chris and Steph riff on that a bit. This episode is brought to you by ScoutAPM (https://scoutapm.com/bikeshed). Give Scout a try for free today and Scout will donate $5 to the open source project of your choice when you deploy. Services down? New Relic (https://newrelic.com/bikeshed) offers full stack visibility with 16 different monitoring products in a single platform. GitHub - alassek/activerecord-pg_enum (https://github.com/alassek/activerecord-pg_enum): Integrate PostgreSQL's enumerated types with the Rails enum feature Feature #7792: Make symbols and strings the same thing (https://bugs.ruby-lang.org/issues/7792) - Ruby master - Ruby Issue Tracking System RailsConf 2016 - Turbolinks 5: I Can't Believe It's Not Native! by Sam Stephenson (https://www.youtube.com/watch?v=SWEts0rlezA) GitHub - hotwired/turbo-ios (https://github.com/hotwired/turbo-ios): iOS framework for making Turbo native apps Become a Sponsor (https://thoughtbot.com/sponsorship) of The Bike Shed! Transcript: CHRIS: Weird stuff happens when we sing, Steph. STEPH: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Steph Viccari. CHRIS: And I'm Chris Toomey. STEPH: And together, we're here to share a bit of what we've learned along the way. So, hey, Chris, what's new in your world? CHRIS: Hello, Steph. What is new in my world? We are continuing with some of the efforts that we're doing to introduce security, and practices, and policies, and all those fun sorts of things at the organization. One of the things that this is pushing on is we are further refining our usage of 1Password at the company as a way to standardize passwords and secure information and how we store that, how we move it around, as well as integrating SSL, and all those other fun fancier things. But I'm personally historically a LastPass user, and now I'm getting to experience 1Password. So now I'm a child of two worlds, and it's terrible, and I hate it. I hate every moment of this existence. So what I need to do is move over to 1Password, but now I'm in that space where I'm like, I can see the flaws of both systems. This is terrible. I don't like it. 1Password does seem to be great; I will say that. There's one really interesting thing about 1Password. I'm interested...you're a 1Password user, right? STEPH: I'm not; I use LastPass. I'm also a child of two worlds because we use 1Password for thoughtbot stuff, but then I use LastPass for my stuff. CHRIS: Gotcha. Okay, so you survive in the middle space. I'm slowly trying to move everything over because I think 1Password has a little bit more of what I'm going for. And I would like, frankly, to be in one cohesive, consistent space, although having two different accounts seems interesting. I definitely can handle it. But knowing which I'm in and how to save a password to one versus the other, it's a whole thing. The one thing that I find really interesting though is 1Password has a feature where it will do two-factor, two-factor authentication. It will do that for you. Specifically, it's doing, as far as I can tell, the TOTP. I don't know what that acronym stands for, but it's the fancy type of two-factor, so not SMS, not text message-based, and not others like WebAuthn is a thing that I've heard of, which I don't know if that is distinct from YubiKey or hardware keys. So there's a bunch I'm trying to learn about this space a little bit more. I'm very interested in the hardware keys because those seem cool. WebAuthn seems like a new standard. That sounds cool. Don't know anything about it, though. So mostly, I know about SMS, and I do not like that one. I do not want to use text messages because, as far as I understand it, they're not super secure. So that's not the space I want to be in. But the TOTP, the Google Authenticator, or Authy, or that space of password or two-factor code generation tools those seem good. And 1Password has a feature where they're like, hey, yeah, sure, we'll have your password and your two-factor. And so they grab the QR code, which is typically the QR code is a way, as far as I understand it, to share the seed. And then, that seed is used by an algorithm to generate the current code value for a given point in time. So it takes like, given that seed and the current timestamp, we will generate you the relevant code, which can then be verified on the far side. But that seed only exists for one moment in time, et cetera, et cetera. But I've always thought of it as this separate thing. The idea of having that all in one system is interesting and kind of scary to me. But as I think about it, I'm like, if 1Password or LastPass, in either case, gets compromised, we're all done. Like, this is over. We should throw in our cards, give away the internet. This whole experiment has failed is my sense. But it was very interesting because I had not seen this. I've always had these as separate systems. So for me, I have had LastPass, and I have Authy on my phone for the two-factor. But it's frankly very clunky, and I don't like it. And the 1Password thing is fantastic where I say like, yeah, 1Password, fill in my password and username, and then also fill in my two-factor because you have it. This is great. But, and this is where I hesitate, and I don't know, I will say this: I trust that 1Password has thought about this deeply way more than I can and have come to a place of deep confidence that this is a fine and okay thing to do. But I'm still intrigued. What's going on here? STEPH: That was a lot. I have so many thoughts. [laughs] CHRIS: Sorry, that was a lot of words, a lot of ideas, a lot of space there. It's just where I'm at. STEPH: People couldn't hear me, but I was laughing when you were talking about LastPass or if these accounts get hacked in. And I'm imagining someone who uses the combination of their cat's name and their birthday as their password and then like, aha, I win. [laughs] It's like, no, we just all lose. [laughs] But that amused me. Going back, you talked about having it all in one place. And that actually doesn't surprise me that we're different in this area. Because you also like all of your email...you like one source of everything, which makes so much sense, but I'm different. And with these accounts, I like that I have the distinction between all of thoughtbot is in 1Password while all of mine is in LastPass because it's just a very clear delineation between those two accounts. And I'm sure both of these platforms have figured out a really good way to then separate those two. But I just remembered there was someone at thoughtbot that accidentally...because they have everything in 1Password, they accidentally shared their personal vault with a client. And so they were just typing in Slack. They're like, "Oh, shit, oh shit, like, how do I undo this?" And we're all just watching like, "We don't know. But please let us know how it turns out." [laughs] It turned out fine. I think they actually realized they hadn't fully shared it but based on the UI they thought that they had. So it all turned out okay. So that just lives with me. I'm a little scared of that now now that I know that story. So watch out, friends. CHRIS: Oh, wow. Well, now, yeah, I'm also now scared of that. I wasn't, but now I am. STEPH: And I forgot the other thoughts now. Those were my two main thoughts based on the journey that you've shared. CHRIS: Particular to the thing you were sharing there, yes, now I will have nightmares about it. But also, it feels manageable because they're both entirely different accounts, and then also within that, there are different vaults. So as I'm building up the password infrastructure at Sagewell, there's going to be different...like, the dev team will probably have one vault and then a shared vault for the dev team. And then other teams within the organization will have that. And so it feels like there are at least structures within the tool to manage that. But mostly, my consideration is around the two-factor thing. And like, is this reasonable to do? And again, I'm sure 1Password has thought way harder than I have about it. And I trust that they're like, yeah, this seems fine that they're not just like, I don't know, it doesn't seem bad. They're like, no, no, definitively for information-theoretic reasons, this is fine. But it was surprising. STEPH: That was it. The other comment that you made about two-factor auth that resonated with me because there was a point not that long ago where we have one of those, either New Relic or I forget which account it was, but it was with the systems. We really only needed one person to have access, but every now and then, someone else may need to access that account. And so we wanted to be able to store it in 1Password or LastPass somewhere like that. But then the two-factor auth was a problem because then you had to coordinate with that other person to say, "Hey, I just need to check something. Would you let me in?" And because we could then leverage that feature, then we could just store all of it. And then that person could just go to 1Password or LastPass and then have access to all of it, and that was really nice. That was a very nice solution to I want to say it was a small problem but yet also very important for team happiness. So that was really nice. CHRIS: The amount of times that I've been like, "I just tried to sign in to the shared account, and it says that it sent a two-factor request to somebody's phone, but it didn't tell me whose phone. And I'm not sure if we know who that person is or if that person's still around," that version of the story feels true. And so, the idea of being able to centralize two-factor seems great. It almost feels too good to be true, is perhaps where I'm at. I am putting on my tinfoil hat, and I'm saying, yeah, but oh man, security, though. And again, I will 100% defer to 1Password on this. They've thought about it. But it's mostly I want to get to the place where I understand the thought process that they went through to decide that this is perfectly fine because they definitely did that work. I'm certain of that. I just want to read a white paper or something, and I haven't found it yet. [laughs] I'm like, let me get to that deep place of trust because that's what I want to be at with security tooling and those sorts of things. STEPH: Yeah, I haven't looked for something like that, but that sounds...I'm kind of surprised that doesn't exist. CHRIS: Oh, it quite possibly exists. I haven't done much of a search, frankly, at all. Mostly, I'm in the space of like, huh, that's weird and then moving on with my day. Because there's not a lot of free time to go search for the white papers on the internet. But yeah, so moving from 1Password or LastPass or 1Password, or maybe I'll just end up with both for a while. I really hope I don't end up in that space, although you're describing it as a positive, so maybe I will. STEPH: I have found it helpful for me. When you find that white paper, because you are more likely the type of person to read that white paper than I am the type of person to read it, then I would love a summary. That would be much appreciated. CHRIS: I'm so intrigued by the persona that you're describing of me of; like, you're the kind of person who would read a white paper. I'm like, well, I don't know if that feels true or if it's definitely true or definitely not true. But if I do happen to find it, and especially if I happen to read it, [laughs], I will share it with you and perhaps with the listeners as well. Let's see, one other small thing. I have a bad idea. I don't want to share the bad idea with you. I want to more share it with the audience, and then I want the audience to tell me exactly how bad of an idea it is. STEPH: [laughs] CHRIS: Because I'm sure it's a bad idea. I'm just not sure how bad. STEPH: I love that there's not even a scale of goodness here. It's just nope, this is terrible, but I don't know how terrible it is. [laughs] CHRIS: What's fun is in the later parts of this episode, we're going to go into a segment of good idea, bad idea, sorry, good idea, terrible idea because I like that framing. No, this one is firmly bad idea, but how bad is the question. So we're working on the app, and we keep running into inconsistencies around symbols and strings. As any Rubyist who has worked in the language for any amount of time, especially in a Rails app, you have experienced this unpleasantness. There are strings; there are symbols. They're often used somewhat interchangeably, and yet they're different. You'll hit bugs. You'll hit edge cases. You'll hit nils that you didn't expect to be there because you tried to fetch a symbol. It, in fact, was a string, et cetera. So, what if we just applied HashWithIndifferentAccess everywhere, just deep in the internals of the app or in the Ruby runtime? What if we were to just turn this on? My sense is this would be terrible for performance reasons. My understanding is that's why symbols exist is because they are a more performant mechanism. Strings are complicated within the object model of Ruby because they're mutable. These are things that I understand very loosely, as you can tell by the tone of voice that I'm using. But symbols and strings they're separate. They're separate for reasons, performance I believe to be the main reason. But what if we were to just say, well, what if it could be like easy, though? That's what I want. Like, this is the promise of Ruby is that I want to express my code in a way that feels like the words I would use to describe to another human. That's the way I always think of Ruby is it's as close to the words I would use to describe the sort of business logic as possible. And yet these symbols versus strings thing it's just annoying, frankly. And again, I think very good reasons for it, I'm sure. But what if we were to just do the silly thing and turn on HashWithIndifferentAccess for everything? I don't even know that that's fundamentally possible. I don't know that there's the relevant hook or the way to do that. But I would love that because we're using it somewhat regularly throughout our app right now, where we're getting data from one API. And in our test suite, it's one way, and in our code, it's the other way. And granted, that speaks to us being inconsistent in our usage. But overall, I would just love for this to not be a thing. And so, how bad of an idea would it be? How much of a performance hit? That's my guess as to what it would be. Maybe there's actual fundamental correctness that would go wrong here. But my sense is by collapsing the space together; we would actually get more correct. I don't know. Anyway, how bad do you think of an idea this is? STEPH: I was thinking through some of the bugs that you're running into. And I think you provided some nice insight around that around it's the fact that you're fetching data from API. So it's typically you're parsing. That's how you're getting the string and symbol differences is because when you're parsing JSON and then you have a mixed case of maybe you have a symbol, maybe you have a string, or maybe you're parsing it differently. Are there other places in the application where that's a concern? CHRIS: I want to say one other place that we're running into it specifically is we're using a lot of enums, particularly ActiveRecord::PGEnum backed enums. So these are Postgres enums at the database level. And then, within our Rails models, we define them as enums. And the enum is typically defined within the model as a mapping of symbol to string. It could be symbol to symbol. I'm not even sure. I think this might be in terms of our implementation. But you say like, it's an enum. The key is foobar with an underscore, and it's a symbol, and then the value is foobar, but it's a string. And maybe both the key and the value could be symbols; maybe that's a thing, maybe this is our fault. But certain times, when you're interacting with the value, it's a symbol. Certain times I find it to be a string. I feel like that's true. I don't think I'm making that up. [laughs] It's possible I'm making it up. But that's another place where I feel that inconsistency or other values within the system that like as they go through certain type coercion layers, they'll start as a symbol, and then they get saved to the database, and then they get reflected back, and they come back as a string. And it's like, well, that's unfortunate. It was a symbol a minute ago, and now it's a string. And so our tests suddenly break in this way, or our code is inconsistent. And it's enough of a nuisance that I had the bad idea the other day. And so, I wanted to bring the bad idea to this space. STEPH: I think you're right. I think the main reasoning for not having everything just be strings is for looking for that performance benefit. And so then using that HashWithIndifferentAccess then you'd have to loop over everything and then convert it. So I imagine, like you said, there would be a performance hit there. I don't know how bad of an idea it would be. But when you said this, it brought up a memory because I remember someone proposing or the Ruby community talking about the fact, like, what if we didn't have strings? What if everything was just a symbol? Or can we just have one over the other? And there is a ruby-lang issue; it is 7792. And we shall also put it in the show notes and send it to you. [chuckles] And this person is proposing make symbols and strings the same thing. And then some people call out specifically the idea of using HashWithIndifferentAccess and saying, yes, that works wonderfully, but then you are going to have a performance hit for it. So it sounds exactly like everything you're saying. I don't know the outcome. I mean, clearly, the outcome is we're not there. But it seems like a really good place to see the reasoning or different approaches that maybe people have tried in this space. CHRIS: Ooh, I love that. I definitely want to read that and see what sort of deeper thinking folks have done on this. Because again, this feels like another one where definitely folks have thought about this, folks who know more about it and have chosen the current path that we're on for reasons. But I would be really intrigued if I could be like, yeah, I would just like it to be easy to start, and then have the performance optimization be something that I could opt into. Again, that's probably not tractable within the language. Like, oh, we have a hot code path here that we want to actually have immutable symbols only. And that's the sort of thing if we've done this HashWithIndifferentAccess everywhere, you can't back out of it. And so, therefore, you're stuck in a performance low point. That feels like a bad case. And so maybe that's the reason is like, you will shoot yourself in the foot with this definitely. But yeah, I'm intrigued. So I will definitely read what you're sharing here. And we'll include it in the show notes, of course. I'm probably not going to do this, just saying that out loud because it seems like a bad idea. I just want to know how bad of an idea. STEPH: I do love it, for when I'm building a class that's working specifically closely with an API, I do reach for HashWithIndifferentAccess frequently. Because like you said, I just don't want to worry about it. I want to set it up top. It's one of the rare times that I actually will use something in an initializer where I'm like, hey, pass in the data. I'm just going to run it through this method. And then all the data from here on forward you can access it in either way. So the class doesn't have to care; a tester doesn't have to care. So I do feel your pain, or I at least will always reach for it whenever I'm building a class specifically around interactions with JSON. CHRIS: So for a segment that I framed as how terrible of an idea this is, you're like, hmm, I don't know how terrible. That seems to be your take, which is interesting. STEPH: Good point. Let me assess for a moment. I'm going to go just from skimming this issue, although I think partially this issue is talking about the fact that if you merge symbols and strings, it's like, hey, friend, you're going to break a ton of stuff and break a bunch of libraries, and these two things do serve a purpose. So this may not be exactly what you're looking for, but it has some interesting conversation on there. But embedding it deep down in the app so that just happens naturally sounds like it's just a performance concern. So yeah, it comes down to what is the question? How big is the performance? So I feel like I can't say it's a terrible idea until I actually know what the performance hit is. CHRIS: So a plausible question. That's where we're going to put this in the category of. [laughter] STEPH: Plausibly terrible, but still worth researching. CHRIS: Not obviously not terrible. But anyway, these are some of the ideas at the top of my head right now. That's a rough summary of my week. Mid-roll Ad Hey, friends, let's take a quick break to hear from today's sponsor, New Relic. All right, so you've probably experienced this before where you're just starting to fall asleep, and it's a calm, code-free peaceful sleep, and then you're jolted awake by an emergency page. It's your night on call, and something is wrong. But I have some good news because you have New Relic, which means you can quickly run down the incident checklist and find that problem. So let's see, our real user monitoring metrics look good. And that's where New Relic measures the speed and performance of your end-users as they navigate the site. But it looks like there's an error in application performance monitoring. If we click on the error, we can find the deployment marker where it all began, roll back the change, and, ooh, problem is solved. We can go back to bed, back to sleep, and back to happy. That's the power of combining 16 different monitoring products into one platform. You can pinpoint issues down to the line of code so you know exactly why the problem happened and can resolve it quickly. That's why more than 14,000 other companies, including GitHub and Epic Games, use New Relic to improve their software. So you know that next late-night call is just waiting to happen, so get New Relic before it does. And you can get access to the whole New Relic platform and 100 gigabytes of data free forever. No credit card required. Sign up at newrelic.com/bikeshed. That's newrelic N-E-W-R-E-L-I-C .com/bikeshed, newrelic.com/bikeshed. STEPH: I have an update that I can share around factories because the last time we were chatting, I was sharing that strategy that we're pursuing where we're trying to minimize factories and then speed up the CI time by reducing the work that those factories are doing. So Joël Quenneville has done some phenomenal work and this past week, specifically improving factories. And he found one particular factory that he was digging into. So some stats before the change. The factory was taking around two seconds, which I know on paper doesn't sound so bad, but it gets more interesting. So total database time is around 1,000 milliseconds. And 833 total database queries were being made, which includes reads, creates, and updates. So then after, Joël was diving into this looking mainly to reduce the number of database queries because that's such a big number. So after the change, which took a lot of research on Joël's part, the factory is now taking around one second, so half of that time. The total database time is around 666 milliseconds. And the total database queries went from 833 down to 647, so a nice improvement there. But the real wonderful outcome of the story is not just those stats, but okay, so how did we impact CI? So we spent time working on this factory. And we have reduced, and we can see some of that in the stats. But how does that apply to the bigger picture? And so Joël took the time of the last 20 successful builds, and based on those builds, we average 27 minutes and 37 seconds for each build. With the factory change that he made, that same test suite was now averaging 21 minutes and 33 seconds. So shaved off six minutes from the build time, which is about a 22% decrease in the build time which is just fabulous. So that was a really nice win from all the work that had been invested in improving that one factory. CHRIS: That's a heck of a haircut there so glad to see that the efforts are paying off. STEPH: Yeah, it was a really nice win to see that we had researched which factories we should pursue, and then we were methodical about that. And then Joël worked hard to improve this factory and saw such a large payoff. It's one of those areas where the team has already invested a lot of effort and hours into improving the test suite. And it's challenging when you have so many areas that you'd like to improve and 100-plus engineers also contributing to that same codebase. So how do you improve and keep up with it all at once? They had spent about a year, so I think they were recognizing that yes, there are still a lot of areas to improve but also felt like small efforts wouldn't move the needle. So it was a nice data point to remind ourselves that we can still reduce the CI build time in a significant way. We just need to be very strategic about where we invest our time in those improvements. There is also an interesting conversation that Joël and I were having because we have a daily sync with each other each day. We've now been embedded with a team with a client, which is wonderful, but before then, we were also chatting with each other. And we like to chat about code, so we've had lots of fun conversations around code. And one, in particular, this week, came up about how people view code differently. And there's even a tweet that Joël shared that I can link to in the show notes. And there's one view that code is a liability, and if a line can't justify its existence, then it should be deleted. And then there's another view that code is an asset. If a line isn't causing any immediate issues, then why not keep it? And part of the reason that came up was while I was going through and reading pull requests, there was a particular change where someone was memoizing an expensive call, which was great, something that we wanted to do. But then they were also memoizing a very fast operation in two other places where it was just like parsing some params something that, you know, superfast and only getting called in maybe two places. And it was one of those that just caught my attention to be like, hey, I love that you memoized this other call, but this one, I don't think we need the additional overhead or complexity of adding memoization. And I found myself when I was writing that suggestion for the author that I was already looking for more than just to say, like, hey, this is more than we need. Because I've realized that often I take that stance of code is a liability. So if we don't need it, let's just get rid of it. But I've definitely run into other people where they're like, well, it's not hurting anything, so why can't I just leave it? And getting that kind of pushback on suggestions about removing code. So it was a fun opportunity to think through okay, well, why is this memoization not just unnecessary, but how could it actually cause us problems? And what's the cost of keeping it in, not just the cost of removing it but also the cost of keeping it in? And that was fun to talk about. CHRIS: I'm so glad you're bringing this particular conversation up because if we're being honest, I saw Joël tweeted about this. I saw it. I sent an email to myself linking to the tweet with the subject of the email being ahhhh, just A-H-H-H-H, which I believe was me being like, oh my God, we got to talk about this. I apparently didn't want to write all of those words, so I just wrote ahhhh. But as a handful of asides, one, if you're not following Joël Quenneville on Twitter, @joelquen, that is a mistake, because Joël is one of the clearest, most concise, and effective thinkers about code that I've ever seen. The writing that Joël produces is absolutely fantastic. And having worked with Joël for forever, I still will look at his Twitter feed and be like, well, this is fantastic. You're saying amazing things that I have not heard you say. So, again, strongest recommendation I can make; please follow Joël on Twitter and also via the Giant Robots blog and all of those other places. But in particular, I saw this one come through, and I was like, oh, man, we have to talk about this. So I actually have it up in my email app right now behind the scenes. [laughs] I was like, oh, I want to mention this to you, Steph. So I'm very excited that you're bringing it up in this moment. It is such an interesting thing. It's such an interesting case of like; I deeply believe both of these truths, and yet they do seem to be in contradiction. And so what do we do with that? More generally, I feel like that's true of a lot of stuff in life, like, the ability to hold two competing ideas in your head and be able to know where one applies and where one doesn't. That is a critical thing to get to in life and to figure out how to do, and that's some of the hard work of thinking. But in particular, this one, the idea that code is a liability. You have a line of code...I'm going to read it precisely as Joël wrote it, "Code is a liability. If a line can't justify its existence, it should be deleted. Code is an asset. If a line isn't causing any immediate issues, why not keep it?" And I think for me, if I were to try and interpret this, because I do believe both of those sides, I would apply one during code review. When code is coming into the application or when I'm writing code, do I need this? Do we need this? Is this necessary? Because it really should be necessary to come into the app. But then once something has made it in, especially the longer something's been in there, I think code sort of ages and matures. And so, the longer it's been part of the app and not causing an issue, the more I am liable to just leave it at rest. Just say, sure, or not at rest but as part of the runtime production code. But these are two competing ideas, but I think they apply at different times in the conversation. And so I'm definitely on memoization. In particular, memoization is a form of caching. Caching I have run into a handful of caching bugs in my life, let me tell you. I'll probably run into a few more. So if we can avoid caching, let's do that. So that's a particular question around that thing. But again, that idea of like the point in time to have that conversation is during code review or initial authoring or when it's about to come into the app. But if we've had some memoization in the app for forever and you're like, do we need this memoization? I don't know, but don't remove it because maybe it's very important at this point. Maybe it's one of the cornerstones holding up our application. So that's a bunch of thoughts about that. But also super glad that you brought this up because I was very excited about this particular tweet. STEPH: Yeah, there's someone that said something very similar to what you just said around they agree with number one for all new code. And they agree with number two, where code is an asset for refactoring. And I thought, yep, that's a great way to look at it. And I hadn't really thought about that specific perspective. And so it was one of those moments. Because I do like when people will push back on something that I so firmly believe on, not that this person did. I was, frankly, having a conversation with myself based on previous conversations with other pull requests authors that I've had that it's not related to this particular pull request. But in general, when people do push back on something that I do have such a firm belief in...and early eager optimization around memoization is something that I'm just like, I don't want to do it, especially for something that's so cheap and in such a fast execution and something that we're only calling twice. There's no benefit to it at that point. But then when someone says, "Well, but it's not hurting anything," then I appreciate that question because then it's more of not just pushback, but it's sort of well, tell me more. What is the pain that I'm introducing by keeping this in? And then that can be a really nice conversation to have with someone around; like you just said, I've seen caching bugs, and this could be a caching bug, and they are painful to then triage. And so we've introduced this optimization, but it's actually just going to cause us debugging pain later. And we really didn't even get the reward from it in the first place. So I really like those conversations when I feel like there's a little bit of a challenge of where I'm like, oh, I hold this as a deep truth, and somebody doesn't, and I would like to have that conversation with them. There are also some other fun conversations; one was around introducing a query object, which, as you know, we're both really big fans of. And then there was another great question because not everybody who works on this team is really familiar with Ruby and RSpec. They work in Scala, but then sometimes they hop over to the Ruby side. And so then they hop into the Ruby channels, and they're asking questions. And one of them was around the idea of introducing an RSpec Matcher. And they're like, "Am I doing this right? Is this how you would extract something to then improve your test? " And so that was a really fun conversation around like, yes, you did it right. This is exactly how you write a Matcher. But let's talk about use cases because extracting something to an RSpec Matcher to me means it meets the most generalized sense of usefulness that you want the whole team to use this and that you're willing to put in the extra overhead to then introduce this essentially like new RSpec DSL for the rest of the team to use and then maintain that. So it is the most aggressive step that I take when I'm trying to introduce a helpful tool. So then I shared my progression for when I'm extracting something for a test. And first, I will start with just a local method to that test because then it's scoped to just that test. And from there, then I will think about extracting to a shared helper. So maybe it's a module that can get included. But then its scope can still be confined to a couple of tests, but then we've also increased some of its observability. So then other developers will notice it and be able to share with it. And then from there, if I'm like, oh, this is super generic, it is testing time, and it's something that everybody is going to benefit from, then I reach for something like an RSpec Matcher or introducing a custom RSpec Matcher. So lots of fun testing conversations this week. CHRIS: That was a wonderful hierarchy. I like that a lot. I feel like that would make a good blog post. STEPH: There are some things that I realize that I just think of inherently about that I realize that would be fun to share. I'm much better at podcasting than I am at blog posting. [laughs] CHRIS: There's this friend I know, Joël Quenneville, very good at the blogging. He could probably help talk you through writing this up as a quick blog post. But you just described this heuristic hierarchy that you have. And you could probably provide quick examples of each, and I think encapsulate that knowledge. I, too, default to podcasting because it's easy for me to just say stuff here, and then it's there it is. But what you just said also mirrors exactly what I would think of as sort of the hierarchy and the reasons you're like, I'm not sure I'd go all the way to an RSpec Matcher. That hesitation is meaningful and comes from experience that you've had. And again, that seems sort of a trade-off of like, well, why not? Is it hurting anyone? What's the cost here? You know that cost. You have that in your head. And so now if you can capture...I don't want to put work on your plate. But I think that would be a great blog post. I would be happy to read that blog post and share it with other folks. STEPH: Cool, cool. Cool. So I totally hear you. So here's my hierarchy. Typically, I start with a podcast, and then I share it there. And then maybe it'll go to a tweet. And then once I'm like, okay, this is super generic, it can help everybody, then we've reached blog post status. CHRIS: I love how tweet is higher in the hierarchy than a podcast for you. That somehow the throw away let me just have 140 characters or 280, or whatever we're at these days, that somehow that's next in your hierarchy. But I agree; I share that place in the world. STEPH: Yeah, just writing is hard. Here I get to show up, and I say things. And then we have wonderful Mandy, who is then editing all of our words, so there's a safety net here. If it's just me and a keyboard, who knows what's going to happen? CHRIS: Then you'll probably think about the switches that you're using on the keyboard. And do you need a new keyboard? Should it be silent? What do we do? STEPH: I was thinking more how many exclamation marks do you use? That's always a question. CHRIS: Not too many, not too few. It's a difficult question. STEPH: [laughs] Mid-roll Ad Hi, friends, and now a quick break to hear from today's sponsor, Scout APM. Scout APM is an application performance monitoring tool that's designed to help developers find and fix performance issues quickly. With an intuitive user interface, Scout will tie bottlenecks to source code, so you can quickly pinpoint and resolve performance abnormalities like N+1 queries, slow database queries, and memory bloat. Scout also recently implemented external service monitoring, adding even more granularity when it comes to HTTP requests and API calls. So give Scout a try today with a free 14-day trial and experience first-hand why developers worldwide call Scout their best friend. And as an added bonus for Bike Shed listeners, Scout will donate $5 to the open-source project of your choice when you deploy. To learn more, visit scoutapm.com/bikeshed. That's scoutapm.com/bikeshed. STEPH: Pivoting just a bit, [laughs] what else is going on in your world? CHRIS: What else is going on in my world? So we are building out a whole platform over here at Sagewell, and one of the things that we need to build is a mobile app or, frankly, two mobile apps, one for iOS and one for Android. And I'll be honest; I resisted this for a while. I am a big, big believer in the web as a platform like deeply in my heart of hearts. That's the place that I want to spend my time. That's the thing that I believe in. And there are absolutely cases where truly native mobile apps shine, completely outshine what we can do on the web platform sometimes for reasons that are, I think, not great, limitations of the available mobile web platforms, et cetera, reasons that I'll slam my fist on the table or whatever it is. But there are plenty of really great mobile experiences, offline, et cetera, that we just can't...offline is not even a great example. See, I can't even find a great example. There are definitely things, though, where truly native mobile apps are 100% superior. But again, I'm such a big fan of the web platform that that's what I wanted to do. I wanted to hold on to this dream of, like, what if we just make a really great web app and it's just great? And then consistently, our backend is one singular thing. Our frontend is kind of one singular thing. And yeah, we got to deal with responsive design. But that's to me a much more tractable problem than fracturing our entire application architecture across a bunch of different platforms and having all of the logic of our domain splintered and especially depending on how you implement it. That's sort of a big question. I've talked a ton about Inertia.js on this podcast, and that's because I believe it's a really great example as to how to pull some of the logic back to the server-side, which, in my experience, that's where I want the logic to be implemented, our deep domain logic. I just want that to be on my server in a Rails controller, or a Rails model, or a command object, or any of those sorts of things, query objects, all of these wonderful things but server-side that's centralized in one space. Nonetheless, though, we had to build a mobile app. These are the truths of the world. Sometimes it just comes down to the expectation of your user base. And there are certain things that by building a mobile app we will get so, for instance, in our case, having biometric login, so fingerprint, or facial ID, or any of those sorts of things. Those are actually material security differences. They are actually, as far as I can tell, available on the web but not consistently on every browser, et cetera. So that's something that we can get by having our app as a native app. Push notifications is another one that certain platforms, certain web platforms have dragged their feet on, Apple Safari. iOS Safari, specifically, I'm looking at you, but that's an example of something that by going the truly native route, we'll get that. Similarly, access to some of the lower-level things, cameras, et cetera, that is something that we'll get a better experience of. And again, you can hear in my voice I don't want to really seed it to the native platform, but it is true right now, at a minimum. So we had a decision to make as to how we would implement these applications, and we went with an interesting route. So for anyone that's familiar with Turbolinks native, or I believe Turbo iOS is pretty similar. But I'm more familiar with Turbolinks native as there was a talk I Can't Believe It's Not Native I think is the name of the talk that was given a while back talking about the Turbolinks native architecture. So basically, what's happening under the hood is let's still render these things server-side. Let's send down some HTML. In our case, it's a weird sort of hybrid of HTML and not HTML. But broadly, let's say that the server is rendering things. And our native application is going to then be a native shell that wraps around WebViews. But it does so in not just a single WebView sort of way. It's instead trying to find that optimum hybrid spot where let's do native things where they make sense. So, for instance, we have introduced a tab bar at the bottom of our application that is a truly native UI. We similarly have push notifications, biometric login, et cetera. Those are features of the native platform that we're using. But then, for most of the screens, most of the screens that are just some text, maybe a button, maybe a form, et cetera, we are using the server-rendered code that we have. And so server-rendered, in our case, because we're Inertia, it's sort of a misnomer because technically it is being rendered on the client-side in the WebView. But, I don't know; we're now getting too nuanced and in the weeds for it. But what we've opted for is to reuse the same views, controllers, et cetera. All of that is still being reused. Our iOS and our Android codebase at this point are wrappers around those WebView stacks. So it's not just a singular WebView; it's a stack of WebViews. So if you're doing swipe to navigate thing on iOS, that'll work...or Android. I think Android has an actual back button, though, within the applications. But most importantly, we've introduced a tiny little bridge layer. So from our WebViews, we can communicate to the wrapping native context. And similarly, from our native context, we can send messages into our WebView. So we can have a button in our native UI. And when a user clicks that button, it will send a message to the WebView that it's wrapping around and vice versa. We can do push notifications. We can do all that sort of stuff. For any given view, like, say, the login view, we can say, "Hey, don't render the normal server-side thing. Instead, render this truly native, local Swift or Kotlin view that we want to use there." So it's an interesting choice. I think it's something that I've certainly seen applications that are just like, let's take some HTML and wrap it in a WebView, and it'll be fine. And they don't make great apps. But I think this time it might just be a good idea. I actually do think that the approach that we're taking, at a minimum, is buying us a ton of simplicity in terms of having to duplicate what are somewhat nascent domain concepts across multiple platforms. We're not entirely certain as to what our platform and what our business is going to be. So we'd love to non-enshrine that across three different platforms that are hard to update. Like the web, I can kind of change that every day. But iOS and Android because I have to go through review cycles, because I have to get them out to devices, because there are slow update cycles that individuals will use, I'm going to be stuck supporting whatever version of these applications are out there. And so if more of that is the dynamic content that's driven by the server, frankly, I just feel way better about that, at least for now, at least for the point in time that we're at. But I kind of believe that this may be a really useful architecture for us long term. That was a bunch of me rambling about the architecture. Let me pause there, thoughts, questions, comments, concerns? STEPH: First, I really appreciate the thoughtful approach and explanation. Also, you highlighted the reasons that y'all are pursuing having a native app, and all of that makes a lot of sense. Because there is that user expectation of you told me about a service that then there must be an app that I can download because that's what I'm accustomed to using versus having to go to a browser and then having to then remember the URL of the site that I'm supposed to go to. So there's that convenience factor. There's also the idea that some people go to the App Store and search for their solutions instead of going to a browser and searching for a service. So having that presence in the App Store can seem like a really huge win because then even if it maybe slowly pushes them back to use the website or as long as they get a decent experience, they've now at least been exposed to the idea of the service and that it's out there. But then, as you pointed out, building a mobile native application is a lot of work. And then it becomes a question of like, well, are you going to hire people to work specifically on these platforms? And then, is it really worth that investment at this point? Or is it worth the approach that you're taking where you're going the more hybrid approach? I am curious; maybe this is something that you'll know. So as you are investing in this hybrid approach and you are starting to collect more users that are then using the app versus going to the browser, then what does that pivot look like, or how does that further investment look like? If you realize that the UI isn't quite delivering the expectations that you want that if you'd actually built a native iOS or Android application, then what does that investment look like? Can you still reuse some of the work that you've done? Is it totally scrapping that work? I think that would be my biggest question around taking this first approach. Is it an all-in bet that we are now stuck to this? Or is there some salvageable pieces to then move this forward into native apps should we need to do that? CHRIS: That's a heck of a question. Have you made a terrible decision or just like an iffy decision? I think that the framework that we're choosing or, frankly, building right now will actually be amenable to a potential transition entirely into the native world in the future. So again, one of the options that we have here is the ability to say, no; this facet of the application is entirely native. We're going to opt-in. And so it actually happens at the navigation layer. So we can say, if a person transitions to the /user/signin route, instead of just rendering that WebView right in place, push a native Swift or Kotlin. Depending on the context that we're in or the platform that we're in, push the native view onto the stack and use that. And so we're able to, on a screen-by-screen basis, make a decision of no, we'd like to opt into native behavior here. And so, if we did eventually see that the vast majority of the users of the platform are using it via the native app, we should probably continue to invest in that and push in that direction. I think we could do it in sort of a gradual style, and that is critically important to me. I don't want to make a big bet and then be like, oh no, we got to rewrite from the ground up. And there's no way to do that incrementally. It's going to be a whiz-bang Friday launch that everyone's going to hate. That's the thing I want to avoid most in the world. And so I think what we found now is this seems great for right now because it allows us to avoid this complexity explosion of three different platforms and trying to keep them in sync and trying to keep them up to date. But it does, I think, give us an opportunity as we move forward to slowly sort of transition things over. We are, to state it, this isn't just like wrapping a WebView around things. We are building essentially a mini framework on both iOS and Android, or roughly Swift and Kotlin is what the actual languages are, to work with Inertia because inertia is the core technology that we're using. Inertia, thankfully, has a nice little event system in there, so we can say, Inertia on navigate. And when a navigate event happens, we can hook into that and then connect it to whatever Swift or Kotlin runtime that we're building here. And there are a couple of different events that we can opt into. And so that's giving us the hooks that we need in the current architecture. But longer-term, if we needed to, we could just, I think, slowly transition everything over to be truly native mobile, and then that would probably be backed by more traditional API endpoints and that sort of thing. I want to avoid that. That's my dream is to stay in this happy place where we're always going to need some web presence. And I would hate for those to be fractured distinct things. I've worked with enough mobile apps that are wonderful native experiences, and yet I'm like, could you just give me the desktop view? Just scaled to...like, I'll even pinch and zoom because you're hiding data from me, and that makes me very, very sad. Please give me the buttons, and the text, and the content that you would give me on the web. And the fact that you're not is just breaking my heart right now. And, frankly, for our user base, consistency of experience is something that I think is really important. So that's another facet of the conversation that is really interesting to me of like; I don't want it to be different on each platform. Certainly, a three-column layout doesn't work on an iOS app that is zoomed in 150%. But we can turn that into each column is just floated down and then otherwise have all the content in there. And I believe in that as sort of a fundamental truth of let's reshape the content but not fundamentally rethink it. I say that as something that I believed deeply. But as I said it out loud, I was like, yeah, but also, I don't know, make it work on the platform it's on. So I can see both sides. But I have had enough experiences personally where I'm sad about the app that I'm using. STEPH: Yeah, I could also see an argument for both ways where you don't want it to be fundamentally different, but then also, you want it to fit the platform. And then there may be some advantages to the fact that there is a different platform, and you want to utilize that. I also agree with the not hiding of the data. I have felt that pain where I have an app, but I really want to go to my desktop, and I really want to use it there. But then on mobile, it's then hiding, and I realize it's hiding. And that inconsistency really frustrates the heck out of me. So I can understand that as well. Overall, I really like this. You're taking a bet in a direction of we should have a mobile presence, and we should start attracting people through this new marketplace. But we want to reuse a lot of the logic that we already have before we go so far as then we're going to have to start building for each different platform. Because while I don't have a lot of experience in that area, the times that I have been part of teams that are building native apps, it's a big investment. I mean, they hire people very focused on that; designers have to design for browser, for mobile, and then for native, and then everything has to stay in sync across. You have to think about how a feature is going to work across all three of those different views. And so it is certainly not something to go into lightly, which I think is exactly what you're describing is that you're looking for that in-between to how can we start working our way in this direction but yet also do it in a way that we're reusing a lot of the work that we have versus having to invest full sail into then building out these different platforms? So I'm going to go with this is not a terrible idea. [chuckles] I'm excited to see how it feels once I can download this and check it out. I'm excited to then see how that feels from a UX perspective. But overall, everything you're saying really jives with me. It makes a lot of sense. I am curious, what about React Native? Is that something that you considered using? CHRIS: Oh yeah, great question and definitely something that we considered. We're not using React on the backend, so that was actually a consideration when I was thinking about Svelte initially is I assumed we'd be building a React Native app eventually for the native platforms. But I talked myself into Svelte for the web, and that is not the reason that we're not using React Native for the native apps. But it is an interesting sort of constellation of technologies that we have now. We're not using React Native because I'm clinging to this idea of what if we could have a singular experience? So React Native fundamentally you're building a native app that this is this bundle that you download that's got all of the UI and that front-end logic in that bundle that you download. And then when it wakes up, it makes some calls back to some APIs to get some data or to decide if I can do an action or to actually do an action, all those sorts of things. But you're building out a Rest or GraphQL or one of those APIs. And with my explorations of Inertia, I found that what if I didn't need to do that? What if I could do a more traditional Rails CRUD-like experience but CRUD in a good way (I mean it in the very positive sense of the familiar architecture) and still give users a delightful experience but not have to build a distinct API where all of the or majority of the logic was on our client-side? So if I did that, then my web client would need to be that much smarter. And each of the iOS and Android clients would need to be that much smarter because that's fundamentally how these technologies work. UI components they can give a higher fidelity experience, more native-like experience, but they tend to own a lot more of the smarts. And one of my core beliefs is however long I can get away with this, I want to keep as much intelligence on the server as possible and have my view layer be as minimal and as simple as possible. So I think React Native is a really fantastic technology for that sort of work. But my goal was to avoid that sort of work entirely. What if we had a singular way that we had the logic exist on the server-side, and then we rendered pretty minimal view layers? Or, from a user experience, the view should do all this stuff and show all of the things that they want. But I want that view layer to be as naive as possible. And by naive, I mean in the positive sense of like, I want to be able to change this very rapidly. I want to be able to evolve it and iterate it. And so this is more of a buy into I think the thing that Inertia gave me is valuable enough and if I can keep using that and reuse it, especially on these mobile platforms...now if we add a new fundamental part of our Sagewell platform, if we have that, it just exists on each of the iOS, the Android, and the web, and that's fantastic. And we're going to keep a really close eye on what experience that gives to the user. And is it still great? But presuming it is, the complexity savings there are so huge. Our team is a team of web developers that is able to think about things holistically and singularly. We implement it once within our stack, and it just works. And if we can do that, that is worth a ton. We may not be able to do that forever. But for now, especially while we're figuring things out, while we're super early on as a company, I think that savings and complexity is worth a lot. So it'll be interesting to see how it plays out, and will certainly report back. But I'm a big believer in this little adventure we're on. STEPH: Yeah, you said it perfectly there at the end; you're a team of web developers. And so as long as you can stick to that, then that's what's best for y'all and the team and the product. So that's wonderful. I have a short segue because I had a little bit of inspiration when we were talking about terrible ideas. I want to circle back to your other terrible idea because I have a terrible idea for your terrible idea about strings and symbols. Okay, so my terrible idea is you're talking about using HashWithIndifferentAccess for everything. What if you had a class or method that then will first try to access via string and if that fails, access via symbol, and then if that fails, then it fails loudly? So you now have this let's try this, and then let's try the next thing. I have strong feelings about this as I'm saying it. CHRIS: [laughs] STEPH: But we're in the terrible idea segment, so I'm going to embrace it. This is my terrible idea. CHRIS: HashWithIndifferentAccess with runtime exceptions. I think HashWithIndifferentAccess under the hood probably does what you're describing of, like checks one and then checks the other or checks has_key is probably the underlying implementation. I haven't actually looked at it. But some version of that makes sense. Falling back to the key error gets interesting. I did see a different thing recently of a deep fetch, which is something that I want, to stop trying to make fetch happen, except I'm going to try and make fetch happen. We thought about this a bunch where we have these objects that we need to traverse into. So we use dig to get into the third layer of the object, but dig doesn't care. And it's just going to happily nil out whatever. So I'm like, no, dig but then right at the end, fetch, deep fetch. I saw somebody post this recently. So deep fetch is something I want to make happen. HashWithIndifferentAccess, which raises at the end also intriguing. STEPH: So yes, but this will be a little different because this one, you don't have to do the transformation process upfront with HashWithIndifferentAccess where you have to pass the data first, and then it transforms it so then it can do these two different lookups or the fallback. This one, you're skipping the transformation process, and you're using your own custom method that then does that first check for a string or first check for a symbol and then default back to the other one and then fail loudly, yeah, if both of those fail. CHRIS: Interesting, and I have to see what it looks like in practice. But I mean, broadly, I'm into something in this space. Let us find some simplicity. That is what I want. STEPH: Let's find some terribleness and see which one feels not so terrible. [laughs] CHRIS: Some terrible simplicity. Well, I like that idea. We'll see where we get to with it. But I think on that note, and we've said a bunch of stuff today, should we wrap up? STEPH: Let's wrap up. CHRIS: The show notes for this episode can be found at bikeshed.fm. STEPH: This show is produced and edited by Mandy Moore. CHRIS: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review on iTunes, as it really helps other folks find the show. STEPH: If you have any feedback for this or any of our other episodes, you can reach us at @_bikeshed or reach me on Twitter @SViccari. CHRIS: And I'm @christoomey. STEPH: Or you can reach us at hosts@bikeshed.fm via email. CHRIS: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeee!!! ANNOUNCER: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.

Webcology on WebmasterRadio.fm
Google November spam update is Fully Rolled Out

Webcology on WebmasterRadio.fm

Play Episode Listen Later Nov 12, 2021 56:59


Google November spam update is fully rolled out by @rustybrick. November Spam Update might be a bit less well adjusted than...https://www.seroundtable.com/google-november-spam-update-impactful-32394.htmlHi Robothttps://www.seroundtable.com/googlebot-ip-addresses-32402.htmlGoogle releases the IP addresses of its various bots in a JSON file. Google can kill your ads if you violate the organic webmaster guidelines – very rare but it's happened. I know it happens in reverse too eh?https://www.seroundtable.com/google-ads-account-suspensions-over-violating-webmaster-guidelines-32386.htmlGoog wins some Goog lose some. It was a busy morning for Google in the European region; first losing its EU antitrust case for $2.8 billion for abusing search engine dominance by promoting its own shopping service. Then the UK Supreme Court dismissing the case against Google for allegedly tracking iOS Safari users without their consent for $4 billion.https://www.seroundtable.com/google-loses-antitrust-shopping-search-but-wins-ios-tracking-uk-case-32399.htmlSEO to Everyone: 02:00 PMhttps://www.searchenginejournal.com/discovered-not-indexed/426457/You should be creating links to yourselfhttps://www.seroundtable.com/google-you-shouldnt-be-creating-links-to-your-site-32398.htmlRIP John Carcutthttps://www.seroundtable.com/rip-john-carcutt-32388.htmlSites need to be worthwhile to be indexedhttps://www.searchenginejournal.com/discovered-not-indexed/426457/ Support this podcast at — https://redcircle.com/webcology/exclusive-contentAdvertising Inquiries: https://redcircle.com/brandsPrivacy & Opt-Out: https://redcircle.com/privacy

AppleInsider Podcast
iPad mini Review, iPhone 13 Pro Cameras, and Focus Mode Tips

AppleInsider Podcast

Play Episode Listen Later Oct 1, 2021 66:26


We go in-depth on our iPad mini review, discuss the big improvements of the iPhone 13 Pro camera, highlight more iOS Safari extensions, and share our Focus Mode tips. Follow our hosts @stephenrobles on Twitter @Hillitech on Twitter Sponsored by: Masterclass: Get 15% off an annual membership to Masterclass when you visit: masterclass.com/appleinsider Support the show Support the show on Patreon or Apple Podcasts to get ad-free episodes every week, access to our private Discord channel, and early release of the show! We would also appreciate a 5-star rating and review in Apple Podcasts Links from the show iPad mini 2021 Review: Delightfully Small - YouTube iPad mini 2021 review: Delightfully small with few caveats Apple dismisses iPad mini 'jelly scroll' issue as normal behavior iPhone 13 Pro: Hands on with the best new features ‘Float' - Filmed in Cinematic mode 16-inch MacBook Pro power adapter out of stock ahead of expected revamp Tweaks for Twitter Mobile Super Agent for Safari PiPifier Vidimote for Safari GoodLinks Safari Extensions for iOS and iPadOS 15: A Roundup of Our Favorites Keynote, Pages, Numbers 11.2 updates with new collaboration options Apple Updates Pages with Screen View, Numbers with Pivot Tables, Keynote with Live Video, and More More AppleInsider podcasts Subscribe and listen to our AppleInsider Daily podcast for the latest Apple news Monday through Friday. You can find it on Apple Podcasts, Overcast, or anywhere you listen to podcasts. Tune in to our HomeKit Insider podcast covering the latest news, products, apps and everything HomeKit related. Subscribe in Apple Podcasts, Overcast, or just search for HomeKit Insider wherever you get your podcasts. Podcast artwork from Basic Apple Guy. Download the free wallpaper pack here. Those interested in sponsoring the show can reach out to us at: steve@appleinsider.com

2MinTech
Episode 111 - IOS - Safari TABs magic and TAB history

2MinTech

Play Episode Listen Later Sep 27, 2021 2:01


Episode 111 - IOS - Safari TABs magic and TAB history

Software Defined Talk
Episode 321: Cambrian explosion of screw drivers

Software Defined Talk

Play Episode Listen Later Sep 24, 2021 65:08


This week we discuss GitLab going public, review iOS 15 and a few more thoughts on remote work. Plus, should the EU impose a universal phone charger? Rundown GitLab Microsoft GitHub rival GitLab files to go public after annualized revenue tops $200 million (https://www.cnbc.com/2021/09/17/github-rival-gitlab-files-to-go-public-on-revenue-over-200-million.html) GitLab: Benchmarking the S-1 Data (https://cloudedjudgement.substack.com/p/gitlab-benchmarking-the-s-1-data) GitLab S-1 Analysis: How 7 Key Metrics Stack Up by @ttunguz (https://www.tomtunguz.com/gitlab-s-1/) Apple iOS 15 Review Buy a 'free' iPhone 13 with trade-in at Verizon, T-Mobile and AT&T: All you need to know (https://www.cnet.com/tech/mobile/buy-a-free-iphone-13-with-trade-in-at-verizon-t-mobile-and-at-t-all-you-need-to-know/) Apple iPhone 13 Review: The Most Incremental Upgrade Ever (https://www.nytimes.com/2021/09/21/technology/personaltech/apple-iphone13-review.html) EU to impose universal phone charger, in blow to Apple (https://punchng.com/eu-to-impose-universal-phone-charger-in-blow-to-apple/) 1Password's iOS Safari extension looks good (https://support.1password.com/getting-started-safari-ios/) Ship / Show / Ask (https://martinfowler.com/articles/ship-show-ask.html) Spend the money on Zoom-Box-Discord instead! Relevant to your interests Original Creators of Apache Pulsar Raise $23M Series-A for StreamNative, Round Led by Prosperity7 Ventures (https://finance.yahoo.com/news/original-creators-apache-pulsar-raise-130000869.html) Werner tweet on NDAs (https://twitter.com/werner/status/1438536990211858436?s=21) Amazon gives Kindle e-readers a rare user interface overhaul (https://arstechnica.com/gadgets/2021/09/a-quick-tour-of-amazons-new-ui-for-kindle-e-readers/) Microsoft accounts can now go fully passwordless (https://www.theverge.com/2021/9/15/22675175/microsoft-account-passwordless-no-password-security-feature) Over the last 90-days, if you average more than 6-viewers, you are in the top 6.7% of Twitch. (https://twitter.com/zachbussey/status/1367868296473813001) Hundreds of Ways to Get S#!+ Done—and We Still Don't (https://www.wired.com/story/to-do-apps-failed-productivity-tools/) WSJ News Exclusive | Apple Is Working on iPhone Features to Help Detect Depression, Cognitive Decline (https://www.wsj.com/articles/apple-wants-iphones-to-help-detect-depression-cognitive-decline-sources-say-11632216601) WSJ News Exclusive | U.S. to Target Crypto Ransomware Payments With Sanctions (https://www.wsj.com/articles/u-s-to-target-crypto-ransomware-payments-with-sanctions-11631885336) WeWork shares expected to start trading in late October (https://www.protocol.com/bulletins/wework-ipo-spac-deal-bowx) Salesforce rival Freshworks raises $1.03 bln in U.S. IPO, valued at $10.13 bln (https://www.reuters.com/technology/freshworks-valued-1013-bln-after-raising-103-bln-us-ipo-source-2021-09-22/) Apple rolls major Safari redesign out to Macs ahead of Monterey release (https://arstechnica.com/gadgets/2021/09/apple-rolls-major-safari-redesign-out-to-macs-ahead-of-monterey-release/) This is your final warning to re-certify, Red Hat tells tardy sysadmins (https://www.theregister.com/2021/09/21/red_hat_pandemic_certification_generosity_over/) Facebook introduces portable Portal Go for $199 (https://www.engadget.com/facebook-new-portals-go-170004952.html) Raspberry Pi attracts $45m after lockdowns fuel demand for PCs (https://www.telegraph.co.uk/technology/2021/09/20/raspberry-pi-attracts-45m-lockdowns-fuel-demand-personal-computers) Zoom's $14.7 billion deal for Five9 under US national security review (https://www.zdnet.com/article/zooms-14-7-billion-deal-for-five9-under-us-national-security-review/) Rundown Follow the millimetres (https://twitter.com/kosso/status/1438847578586718209?s=21) It Has Come to Subscription Tacos (https://www.theatlantic.com/technology/archive/2021/09/taco-bell-subscription-netflix-for-tacos/620109/) A 10-Foot Wide House In Boston Sells For $1.25 Million (https://www.npr.org/2021/09/21/1039324508/boston-skinny-house-spite-house-sold) Samuel Adams' latest potent beer is illegal in 15 states (https://www.upi.com/Odd_News/2021/09/20/Samuel-Adams-Utopias-beer-illegal-15-states/7301632163091/) Sponsors strongDM — Manage and audit remote access to infrastructure. Start your free 14-day trial today at strongdm.com/SDT (http://strongdm.com/SDT) CBT Nuggets — Training available for IT Pros anytime, anywhere. Start your 7-day Free Trial today at cbtnuggets.com/sdt (https://cbtnuggets.com/sdt) Conferences DevOps World by CloudBees September 28-30 (https://www.devopsworld.comDeveloper> Advocate / Developer Experience Engineer at Weaveworks) DevOps Loop | October 4, 2021 (https://devopsloop.io/?utm_campaign=Global_P6_TS_Q322_Event_DevOpsLoop_at_VMworld&utm_source=twitter&utm_medium=social) - see Coté's promo video (https://twitter.com/cote/status/1425460843014131716). KubeCon October 11-15 Virtual and In Person (https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/) THAT Conference comes to Texas January 17-20, 2022 (https://that.us/activities/call-for-counselors/tx/2022) Listener Feedback Go Slack Discussion on Ship / Show / Ask (https://martinfowler.com/articles/ship-show-ask.html) Brian recommends The Disconnect | KUT Radio, Austin's NPR Station (https://www.kut.org/the-disconnect) Jordi wants you to be a Developer Advocate / Developer Experience Engineer at Weaveworks (https://weaveworks.breezy.hr/p/31f1bfca89fb01-developer-advocate-developer-experience-engineer) SDT news & hype Join us in Slack (http://www.softwaredefinedtalk.com/slack). Send your postal address to stickers@softwaredefinedtalk.com (mailto:stickers@softwaredefinedtalk.com) and we will send you free laptop stickers! Follow us on Twitch (https://www.twitch.tv/sdtpodcast), Twitter (https://twitter.com/softwaredeftalk), Instagram (https://www.instagram.com/softwaredefinedtalk/), LinkedIn (https://www.linkedin.com/company/software-defined-talk/) and YouTube (https://www.youtube.com/channel/UCi3OJPV6h9tp-hbsGBLGsDQ/featured). Brandon built the Quick Concall iPhone App (https://itunes.apple.com/us/app/quick-concall/id1399948033?mt=823) and he wants you to buy it for $0.99. Use the code SDT to get $20 off Coté's book, (https://leanpub.com/digitalwtf/c/sdt) Digital WTF (https://leanpub.com/digitalwtf/c/sdt), so $5 total. Become a sponsor of Software Defined Talk (https://www.softwaredefinedtalk.com/ads)! TriggerMesh is hiring! (https://twitter.com/sebgoa/status/1437722696536797185) Recommendations Brandon: iPhone Battery & Power Repair (https://support.apple.com/iphone/repair/service/battery-power) Matt: Deep Rock Galactic (https://store.steampowered.com/app/548430/Deep_Rock_Galactic/) Coté: Hornbach (https://en.wikipedia.org/wiki/Hornbach_(retailer)); box cutters; Drunker & Retireder (https://drunkerandretireder.fireside.fm/). Photo Credit (https://unsplash.com/photos/OIfFRthAASc) Photo Credit (https://unsplash.com/photos/ZV_64LdGoao)

I'm sure they're doing their best
113 - I'm sure they're known for their sacs

I'm sure they're doing their best

Play Episode Listen Later Aug 30, 2021 49:28


With the postponement of the concert in London, Paul is relieved and Drew is 0-2 in the gift exchange. Drew get a new sactional couch. Paul gets a new wallet and Drew is... supportive? Drew apologizes about a phone case recommendation. Paul has a case of "mistaken identity." Paul shares some iOS Safari updates. Also: turns out Roblox is shady. Recorded 08/26/2021 Show links: Behemoth and Arch Enemy postpone European Siege Tour Lovesac Unpacking Your Sactionals Anovus Smart AirTag Wallet Apple iPhone 12 Leather Case Investigation: How Roblox Is Exploiting Young Game Developers

Think Like a Hacker with Wordfence
Episode 122: Largest Password Dump in History Fuels Credential Stuffing Extravaganza

Think Like a Hacker with Wordfence

Play Episode Listen Later Jun 18, 2021 21:56


Sites running Jetpack are being infected via compromised WordPress.com credentials. The largest password dump ever with 8.4 billion passwords is used in credential stuffing attacks. Wordfence Threat Intelligence discloses new plugin vulnerabilities as well as a vulnerability at tsoHost. Data Breaches impact VW and EA, REvil compromises a nuclear weapons contractor, and TurboTax accounts are taken over. Ransomware surveys show conflicting results. Chrome and iOS Safari are both patched against 0-days.

Mini MY CUP OF TEA - #ポトフさん
iOS版のSafariで拡張機能が使えるようになる

Mini MY CUP OF TEA - #ポトフさん

Play Episode Listen Later Jun 8, 2021 2:59


WWDC 2021 がありましたね。まだ、あまりニュースを見れてないですが。 #ポトフさん --- Send in a voice message: https://anchor.fm/potaufeu/message

wwdc ios safari
新聞愛幻想
11/08pocast暴走人均破三萬美未來人預言失敗蘋果推自家搜索引擎

新聞愛幻想

Play Episode Listen Later Nov 9, 2020 20:57


財經 1.聽覺經濟新勢力 Podcast當紅時代已到來 2.拜匯率升值 明年人均破3萬美元 娛樂 1.KIMIKO喝珍奶要求「混珍洗珠」 獨特點法網轟奧客 運動 1.統一獅1比3逆轉奪隊史第10冠 中信兄弟苦吞7年6亞軍 國際 1.KFK預言「川普連任」破功 2.加密數碼幣圈出了件大事:維卡幣(OneCoin)全球吸金40億歐元 生活 1.三十而已! 保全值班台倒下不治 公司駁過勞 2.陸中藥「疫」齊漲!台灣民眾立冬補身荷包縮 健康 1.安胎藥「妳得寶」副作用恐危及性命 2.半澤直樹教我們的職場紓壓術 科技 1蘋果最好的時機推出搜索引擎. 谷歌與蘋果訂立限制性合約,由前者向後者每年支付高達約80-120億美元的費用,以將自身的谷歌搜索置入蘋果的生態內,成為iOS默認瀏覽器Safari、

onecoin kimiko ios safari
Divagaciones de Adrián Perales
iOS y los navegadores

Divagaciones de Adrián Perales

Play Episode Listen Later May 1, 2020 7:43


5/11/2018. Una de las rarezas de iOS: Safari es omnipresente en muchos sentidos, y es imposible librarse de él.

navegadores ios safari
Apple Daily
Apple Ditches Intel In 2020, The iVan, and A Fun iOS Safari Bug

Apple Daily

Play Episode Listen Later Feb 22, 2019 2:59


Apple Ditches Intel In 2020 - https://www.axios.com/apple-macbook-arm-chips-ea93c38a-d40a-4873-8de9-7727999c588c.html iVan - https://www.macrumors.com/2019/02/21/apple-car-electric-van-rumor/ Fun iOS Safari Bug - https://www.macrumors.com/2019/02/21/safari-fake-headline-bug/ Cover art photo provided by @hollymindrup on Unsplash. More Apple Daily: appledailypodcast.com More Tech: techdailypodcast.com More Shane: shanelother.net --- Support this podcast: https://anchor.fm/appledaily/support

The Frontside Podcast
116: Styled Components and Functional CSS with Kris Van Houten

The Frontside Podcast

Play Episode Listen Later Dec 20, 2018 32:59


Special Guest: Kris Van Houten: @krivaten | krivaten.com In this episode, we are joined by Kris Van Houten to chat about Functional CSS and Styled Components: pros and cons, the problems that they are trying to solve, and how to choose between one or the other. This show was produced by Mandy Moore, aka @therubyrep of DevReps, LLC. Transcript: DAVID: Hello, everyone. Welcome to Episode 116 of The Frontside Podcast. I'm David Keathley, a software developer here at Frontside and I'll be your host for today's episode. Joining me as a co-host is Jeffrey Cherewaty. JEFFREY:: Hey, there. DAVID: And we've got an amazing guest with us today, Kris Van Houten. Kris is the author of a very interesting functional CSS library called Elassus, a good friend of mine and today, we're going to be talking about how that compares with another new pattern I've been seeing everywhere recently: styled-components. Hi Kris. KRIS: Hey, how's it going? DAVID: Doing great. Let's just go ahead and jump into things. Kris, you want to give us a little introduction to your functional CSS library? KRIS: Yeah, for sure. I guess, first of all about me. I've been primarily a frontend developer for about seven or eight years now. I don't know, at some point you start losing count but over the years, I worked largely within the Ember framework but I've also worked within React and Vue. Like most of developers over the years, you tend to require an affinity towards certain areas of software development and for me, those areas tend to lean towards accessibility but also, learning how to write CSS with what I call like the future in mind. To try to keep the story as short as possible but a couple of years ago, I was working on a project and started to realize that our CSS is one of those things that just continues to grow over time along with the rest of our application but I also noticed that we tend to have a lot of areas of repetition within our CSS, like how many times are we setting text align to center, how many times are we setting the text color to the primary color or to gray or something of that nature and maybe we could create a utility library that just does all the stuff for us, similar to if you've ever worked with Bootstrap that they had utility classes that allow you to do some things like set the text alignment or the text color or font size and things of that nature. I started thinking around it but eventually, I changed jobs and that idea kind of just went to the side but then, I'd say about a year and a half or two years ago, I came across a blog post called '15kb of CSS is all you'll ever need' and so, immediately I was intrigued. It was actually a blog post on Medium that was talking about the benefits of using something like Tachyons or base CSS, which are two different functional CSS libraries. To explain what I mean by functional CSS, it's just a whole library, a whole arsenal of these utility classes that just do one or two things that allow you to basically take any design and implement it by composing all these classes together throughout your HTML. I was looking at Tachyons, looking at base CSS and thinking, there's a couple of things I like to customize about this but at the time, when I was looking at it, I couldn't really figure out how to customize those values very easily and so, I did every developer does and just decided to make my own and that's where Elassus came into play, where it's a CSS library that is entirely made up of functions that generate your CSS based off of the value of variables in Sass. Everything is customizable, all the way down to how the class names look and the syntax that you use. If you hate what I'm doing, you can customize it very easily. A lot of people might wonder why would you want to use functional CSS, what are the benefits that you get out of it and really, one of the first two things that comes to mind for me that really attracted me to it was that your CSS files start small and they stay small. For the most part, depending on the configuration and the particular library that you're using, your entire CSS payload can be anywhere from 10 to 20 kilobytes, minified and gzipped, which is in stark contrast to some other projects I've worked on, where just one of the many CSS files you're downloading are 745 kilobytes. Dramatic improvements there, so that's why it was instantly appealing to me. But one of the other nice things you kind of get for free by default is a consistent design pattern, right out of the box. Because if you're working on a large team that has maybe multiple designers and many developers, one designer might implement something with the spacing system that's maybe based on five pixels: your padding, your margins, your widths, might be five, 10, 15, 30 pixels, 45 pixels but then maybe, another designer is implementing something based off of more material design, which is base-4 pixels, so it's like four pixels, eight pixels, 16 and so on. Over time, little differences like this can really show up as you navigate between pages of your application and with functional CSS, you're given a limited number of options to choose from. As a result, it actually makes your application feel like it's one cohesive consistent piece of software between pages and between the features that you're navigating through. Those are really two areas that have really attracted me to functional CSS and I guess, is a tl;dr -- if that was a tl;dr in fact -- of what functional CSS is and why I like it. DAVID: One of the things we've got here was the problem that functional CSS and styled-components are both trying to solve. KRIS: Like I said earlier, a lot of the applications that many of us might be working on, they tend to grow at time by either adding features or rewriting and improving existing feature. In JavaScript, over the years, we have made tremendous improvements in our tooling with things like code splitting and tree shaking to really limit and minimize the amount of payload that we're sending to our users at the end of the day. But really, it's only up until recently we hadn't really been talking about how we do that for CSS and typically, as developers, we had deadlines, we're working with them in sprints, we had a real strict time constraints on what we can work on and for how long and so, we tend to focus on making sure the features look right, they work right, and that our test passed. In CSS cleanup is just one of those things that often doesn't get cleaned up as often as you would like. Sometimes, that's also because we assume that a particular set of styles is probably getting used by another team, working on a completely different part of the application. As a result of just not being able to work on this problem or this issue, we likely have many, many kilobytes of orphan styles being shipped to our users at the end of day and our style sheets tend to grow over time. If there's one thing that's kind of become a mantra within software development over the last few years, it's that every kilobyte matters. One of the main reasons I wanted to come and talk to guys today was about some things that I've been tinkering with on the side, just to figure out how we solve this problem and so, their approach of using functional CSS is one of those things but using something like styled-components, which is mostly used in React library of the solution of writing your CSS in your JavaScript and that's another approach to how to tackle this problem. DAVID: That's an interesting thing you said there. I remember, whenever I started off in software development, one of the big no-nos for styling is don't put your styles in your JavaScript. It's interesting to see that that has kind of changed. KRIS: Yeah, indeed. I remember listening to a podcast about two, maybe three years ago and they had a panel on and they were talking about there's a new thing called CSS and JS and I was like screaming in my car like, "This is the most horrible thing in the world you could possibly do. Why would someone want to do this?" and obviously over the last couple few years, the technology has definitely matured and they definitely hardened it, to where when I was working on updating my personal blog, working on moving over to Gatsby, I didn't want to have to pull an entire functional CSS library because I kind of thought that would be overkill for just a couple small pages and so I was like, "Let me try this whole styled-component thing. That way if I'm going to hate it, I can hate it from the experience point of view." I actually found that the developer experience of working with styled-components was really nice and so, I kind of became converted over to that way of thinking about, "I'm not a hater. It's actually a really nice way to write your CSS for your blog or your applications." JEFFREY:: I count myself still as a skeptic about this whole idea, so I'm excited that we're going to talk about it now and then, you have the opportunity to sell me on it, which should be fun. Some of the work I've been doing on lately, we've been doubling down on the idea of CSS modules, that at least fix some of the encapsulation and problems around CSS where everything is sending up in a global scope. How do these ideas of functional CSS kind of take that even farther? What advantages are there over using, just simply using say, CSS modules where we're fixing the global namespace. KRIS: I'd say with functional CSS, again the things that kind of mine for me are you keep the file size small, you have your design patterns that you can get for free right out of the box. Your styles are pretty low specificity, meaning that if you ever have a need to where you get a really customized something because you just can't do a functional CSS, which I found to be very, very few and far between as far as the number and instances I've come across, it's very easy to overwrite if you need to go back into, I guess old fashioned way of actually writing some CSS yourself. But then you also have the benefit of not having to come up with clever class names to describe the different states or different use cases of your component that you're working on or the future that you're trying to implement and so, I'd say those are definitely some of the pros of why I like using functional CSS at the end of the day. I will say that there are some cons -- I'll be completely honest -- and say that one of the areas where functional CSS tends to have a weak spot is in the area of browser specific issues. In my experience, I tend to have a lot of issues with iOS Safari and it's like the bane in my system sometimes. Sometimes, worse than i11 but if you have to really target something that's exclusively for a specific browser, that's really not doable from what I've seen in functional CSS. That's where we should have to go back in and handwrite some CSS for that kind of situation. But also, one of the cons is that sometimes, depending on the element or the component you're trying to style, I think the example is if you have a nav bar that can toggle between being a sidebar but also a top nav bar, that's a completely different set of styles and to achieve those few layouts at the end the day, you have to have a completely different collection of class names that you have to toggle between based off of the state of that component or that feature that you're working on. While that's doable, especially with something like a frontend framework like Vue, React or Ember, it's just a little pain point that sometimes you have to work around but I say, those are the pros and admittedly some of the cons of using something like functional CSS to tackle your styling needs. JEFFREY:: My favorite thing that you mentioned there was how hard naming is. I think everyone can agree, very strong of it, just naming things is the hardest thing. What has been your experience in learning these? They're almost new domain languages for like we want to padding of this amount. Have you found that pretty easy to get up to speed and get fluent in or have you run into some blocks in kind of learning these new languages that some of these CSS tools have presented. KRIS: That's a really good question. When I first started digging into Tachyons -- that was the first functional CSS library I started working with -- there is definitely, I'd say a small learning curve of maybe, I was trying to implement it just to see how it worked and it took me, maybe a couple of hours, if that, to kind of get a feel for how they write their classes and how the classes are put together to do certain things. But once you kind of get through that little initial pain point, it's pretty easy. In one of the things that when I was working on my own implementation of it, I wanted to make sure that no matter what you're doing, all the class names are consistent, that the patterns that you use to your class naming is consistent and I guess, because I wrote it, then it wasn't so hard for me but I also understand that that's not the case for everybody. When I wrote Elassus, one of the things I did is I actually was able to create a compiled JSON version of all the CSS and actually, use that to create like a little React search tool. If you're looking for padding or margin, you can just enter that in a search bar and it'll tell you all the options in the classes that are associated with that and that's one thing I did to kind of help with that barrier but it definitely can be a bit of a learning curve but like I said, it's maybe an hour or two of your time to really get familiar with it. JEFFREY:: That is not bad. KRIS: No, not at all. I was actually really surprised at how fast I got up and running with it. DAVID: That actually ties into something that I was kind of curious about myself. Whenever I went through the coding bootcamp that I did a couple years ago, after we finished going over raw CSS and how that works and the basics of that, they introduced us to Bootstrap as our first real CSS library to play with. That was fairly achievable for someone brand new to frontend work in general. What I was curious about is would you see these functional CSS libraries as equally accessible or maybe, more advanced than something like Bootstrap or Foundation. KRIS: I never thought about that before. I think I kind of see it like as the next step. I've worked on several products over the years where Bootstrap was what they started with. As we went on to build out the feature set of the product, we started to find ourselves battling with the various styles that we get at from Bootstrap for free. I think one of the things about working on a website, where actually using Bootstrap is that sometimes you can just kind of tell that it's a Bootstrap based website. I don't know if I'm making any sense to you guys -- DAVID: Oh, yeah. Definitely. KRIS: That was another reason why I wanted to have something... That had basically forced me to decide how my navigation bar looked. It forced me to think more about how my sidebar is looked or what my spacing scale -- it's the term I like to use -- based on what you're using for your pure margins, your paddings or what's your heights, things like that. It make me think about what those values should be and that's how you kind of break out of the box of having everything look like it was built in the same framework. I would say it's more of a next step if you're talking about your experience as a developer. Yeah, learn CSS. I think it's still incredibly valuable to know CSS and for me, like you David, I kind of got started and learned about this thing called Bootstrap and you can quote me. Back in the day, I said, "This is like the jQuery for CSS. It's amazing," but quickly, I kind of ran into some of those issues that I mentioned earlier and kind of force me think about, "Maybe, I don't want to use Bootstrap. Maybe, I want to handle my own thing," and so, I say functional CSS, as far as like again your education level, it's more or less that step of if you think about how do you want to solve certain problems in our design. DAVID: Okay. We've gone over functional CSS with some and styled-components, how would you choose between the two? KRIS: This is actually really hard because I actually like both approaches. I'm not one of those guys that's like, "That one sucks. I don't want to use it." I actually think both have their place and so, I know I kind of sound like the typical 'this versus that' blog post in technology right now but I will say that there's a few questions you should ask yourself and ask your team if you're considering changing up your approach to CSS. One of those is what is the preferred developer experience of your team. That's something we've been talking about a lot at the company. What we mean by that is how enjoyable is it to work in a particular codebase? Do your developers mind writing their CSS, instead of a JavaScript file? Or would they prefer to have something where they can actually read the HTML and build a C, just by looking at the elements in the classes that are being applied there? What this layout looks like or what's being applied to this layout? You know, questions like that can definitely help determine what direction you should go. Again like I said, one thing I love is that both approaches remove the developer's burden from having to come up with clever class names for all the different use cases or states of your components. I think you're going to get a win-win either way there. However, if you're using React, we already have a ton going on in our JSX and so, if adding a series of class names to determine your design tips is overwhelming for you, then maybe give styled-component a try because it can definitely simplify your JSX output a little bit. If the idea of having JS to handle your CSS seems a little fishy, I think one of the cons of using styled-components is that we're asking JavaScript to do yet another thing for us. If you're one of those people who has a problem with that, then give functional CSS a try. There's definitely more than one flavor out there and I've tried out almost all of them and like them. They all have their nice tidbits inside of them. I'll say, if you prefer to have easy theming, if you're working on a project that has to have a lot of theming involved, then I might be more toward styled-components. If design consistency and design patterns is a priority, then maybe functional CSS is an option for you. With both of those scenarios, easy theming in patterns is possible in both. It's just one is harder in one than the other. With styled-components, there are implementations of it in Vue and Ember but they don't seem to be very widely used yet, so I'd say use at your own risk or contribute to open source to make them better. I'd say for right now, if you don't mind being locked into using React, then styled-components is pretty cool. It also allows you to transfer your styled-components from one project to another without having to worry about. [inaudible] all the CSS because that's a big deal but I would ask myself those kind of questions to determine what solution I would choose. JEFFREY:: I am interested in the performance implications of these tools. You touch earlier on by using tools like this, you can definitely shrink your CSS payload by a lot, so what is the actual output of using these tools? What will it look like? Do you end up with still an external CSS file or is it a scenario where you're kind of getting some CSS injected into your markup? KRIS: Yes with one and no on the other. With functional CSS, you typically have a CSS file that is compiled and maybe, you're using Sass to do the operation for you or post-CSS, so you get an output CSS file that you help you fetch on the frontend of your application. Like I said, [inaudible] if these files are between 10 to 20 kilobytes, which is remarkably small. With styled-components, it's a totally different approach. It's a totally different implementation as well, unless you have a normalize or perhaps a reset CSS that you're fetching on the frontend, all the styles are actually -- I guess, I should start with earlier. What happens is you define your styles in your JavaScripts and at runtime, the component will read the styles that you set and then create a unique class for that instance into the head of your document. It's basically a single class use for that component and so, all in all, it gets compiled at runtime. There's no additional CSS files being injected. It's actually being created dynamically in your actual HTML document. One of the things I was first concerned about was what are the performance implications of having JavaScript do this for us and over the last couple of years, as the technology has been maturing, performance has been an issue but I think it was with V4 -- version 4 styled-components that just released, I want to say, in September or October, they have tremendous performance improvements. It's rapidly fast now, so it's not really something you need to be concerned about. I'd say again, it's one of those things: Can you get over the mental hurdle of having JavaScript do one more thing for you? And can you get used to the developer's ergonomic practice of writing CSS inside a JavaScript file? I know it kind of takes a little bit of getting over that because it just seems so strange but you also get a lot of perks by doing that with having easy access to theming, you get to use some of the power of JavaScript to help build out your CSS, which can be nice as well even if it kind of feels weird. JEFFREY:: Yeah, I agree with the ergonomics do feel weird but you'll get some benefits out of doing that. In the styled-components where it'd bring on the fly, I'm happy to kind of figured out the performance like runtime implications with that but it seems to me that now you no longer have a cache CSS and that you're having to get that all the time on the fly. Maybe for some systems, that is okay but that's definitely something that I would miss having -- the idea that CSS actually can be a little heavier because it will always be cached. KRIS: That is totally a valid point. I think one thing I do kind of like about the styled-component approach is that when you delete a component, all the styles go with it, so you no longer have orphaned styles just hanging out there that are getting shipped down to your user. I agree that the caching is definitely a concern but I just kind of start to weigh the pros and cons and again, you have to decide for your product, for your team what works best for you. Also, one of the pros that I would bring up is that you don't have any orphan CSS hanging out in your application anymore, which is definitely one of the key contributors to growing bloat in your files over time. JEFFREY:: That is very nice. KRIS: Yeah. DAVID: That ties into a question that I was kind of wondering. As your projects get larger and larger and more complex, your style sheets tend to grow along with that and one of the issues that you might have as time goes along is visual regressions like styling bugs. How does using functional CSS or styled-components sort of deal with that or prevent that? KRIS: With functional CSS, like I said, you have those patterns kind of built in out of the box. As long as you don't change the value of what a particular class renders out of, maybe someone goes in and without thinking of it, they change the second value of your spacing scale to a lot of pixels just because they felt they needed to. You're not going to have visual regression that happen over time because the whole premise of functional CSS, those values don't change. Those are basically meant to be seen as immutable values, immutable classes. You shouldn't have style regressions that pop up over time as people continue to work on your application. With styled-components you still have that risk unless you are setting all those same values and your theme properties that you can use within styled-components. Unless you're setting all your different spacing values, you have a tendency to potentially run the same issue. But actually, now that I think about it, maybe not because with styled-components, every component is unique. Every components styles are completely unique, so again, unless you're changing those core values of your themes, you should not have visual regression that happen in a totally separate part of your application when you're working on say, the home page. I would say both handle that pretty well, now that I'm thinking of it. DAVID: That's cool. KRIS: This reminds me, I'm working on a particular piece of software at a particular feature of my work and we don't use functional CSS or styled-components yet. I'm trying to get them to move over so again, this is all stuff I do on my free time but I'm working on editing a component and I had to make some pretty drastic changes to it and I was like, "How is this going to break on some other page that I'm not aware of yet," and so, this requires a lot more going back and checking all the various uses of this particular component. We used it in 10 or 11 different places on different pages and so, we have to go back to each and every single one of those use cases to make sure I didn't break something. Whereas if I was using one of these two approaches, it wouldn't be something that I would have to be concerned about. This is what I'm trying to push through on my own job as well. DAVID: Yeah, it really eat up your time. KRIS: Yeah. JEFFREY:: I want to talk for a few minutes about media queries because, I think that the situation is kind of handled. It's definitely something I've run into: CSS variables and with post-CSS tooling. I'm interested in kind of how does the media query story is handled with the setup. KRIS: With functional CSS, you tend to have, basically say, I have a class that sets a margin on the top of 16 pixels, for example. Let's say that that class name is MT-3... I don't know, meaning for like the third position in your spacing scale, 'MT' stands for margin top. If you wanted to only use that style for perhaps, like your medium break point, then different libraries have a different way to approach this, basically, you're 'MT-3--medium' or '--desktop.' It's the additional characters that you append to the class name to target that specific media query. Also, depending on the framework that you're using, you can also target pseudo states, whether or not this element is focused or on hover, maybe you want the background code to change. There's variations of those classes that allow you to target those specific states, which is really nice in functional CSS. Again, just by looking at the classes that you're adding to your DOM, you don't have to scroll through your style sidebar to figure out like what styles are associated with this class name and why it's being overwritten by these 10 other things that we have going on. Again, you can just look at the HTML and see what's happening and what should happen if you hover over an element. With styled-components, you can still use media queries and all that stuff right out of the box. In order to keep your media queries consistent, that way not everybody is having a handroll, at least by every single time that you need to use them. You can actually store your media queries in a separate JS files and it's kind of import them as you need them, which again, kind of feels like a weird developer ergonomic for your CSS but definitely, it comes in handy and definitely keeps your styling consistent the more you break out the various pieces into small pieces or small components like that. That's how to handle things like media queries and things like that. JEFFREY:: It's interesting how these approaches are kind of pushing the web towards, I'm feeling a lot more like native development, where you build your style and your visual look in conjunction with your component code and those things are not really ever separate. I think, there's some interesting influences coming in there from some made up things. KRIS: One thing I think about a lot, especially when I'm thinking about functional CSS is I'm reminded of this image I saw kind of posted on Twitter somewhere in the interwebs. It was a picture of the Super Mario Brothers start screen and the entire Super Mario Brothers video game was something like 23 kilobytes. This screen that you're looking at, which was like the start screen was like 345 kilobytes or something. My numbers are probably off but it was something drastic like that and this makes me think about, if you were to go back through, there's a couple of documentaries about how the loops that developers had to jump through in order to make old video games for Nintendo Entertainment System back in the late-80s -- I'm probably dating myself right now -- but the things they had to go through and to think about in order to make those games work the way they did is insane and I kind of feel like over the last... I don't know, maybe 10 or 15 years, because we've gotten such fast computers and such fast mobile devices and so on and so forth, we've kind of gotten crazy. I look at video games now and they're 100 gigabytes sometimes and I kind of feel like they didn't need to be 100 gigabyte video game and I think -- DAVID: But it's so much cooler because it is. KRIS: I'm not saying it's not cool but I'm think like if they really took the time to pay attention to some of these details, we probably could automate this a little better. Maybe, I'm just being biased but I think about we're kind of starting to do the same thing and talk about the same kind of problems in web development. Again, just because we can have a 745 kilobytes of CSS file and thought the world falling over, it doesn't mean we should, so maybe, let's take into consideration that not everybody is using a cinema display on a super-fast MacBook to view your application, what about the person who's using an outdated Android device that hasn't been updated in three or four years? How's your product going to work on their device? I'm really glad that people actually started to take that kind of thing into consideration and it even reminds me a little bit of another area that I think a lot about is the area of accessibility: how do people with various impairments or disabilities use your software and how can they use your software but also, outside of that, how do people, who maybe don't have the money to have a fancy mobile device like you have, use your product along those same veins. It kind of dips into the same vein of accessibility when we're talking about how do we optimize our products to make them usable by everyone despite their income level or their ability to have a fancy, nice desktop or a latest iPhone. JEFFREY:: Awesome. DAVID: Yeah. Definitely, you think about who are the majority of users on the internet these days and really, it's an emerging market with underpowered devices and the internet is becoming much more and more accessible for people to get on and browse, so you really got to keep those people in mind. KRIS: Definitely, especially if you're creating software that you want people across around the world to be using, a lot of people don't have access to crazy high speed internet like we do here in the States, so we should probably be taking more time to consider what it looks like for those people to use our product. At my company, what we've been talking about is like we should be testing and basically, starting mobile first with all of our development to see how does this work on our mobile device. I'm a remote developer so we're trying to figure out how to get me mobile devices that I can actually test on our VPN but it's something that we're trying to move towards at my company as well. DAVID: Okay, that about wraps up Episode 116, our final episode of 2018. Man, the year has gone by fast. We are the Frontside. We're the frontend specialists who make your largescale application projects run smoothly by helping your team assemble the right tools and implement the right automated processes. We can ensure your projects can move forward on time and without regressions while preserving quality and long term maintainability. If that's something you're interested in, please get in touch with us at @TheFrontside on Twitter or Contact@Frontside.io via email. Do send us any questions you might have, any topics you'd like to hear about in the future. We look forward to hearing from you. Thanks again to the wonderful Mandy Moore for producing today's podcast. You can find her on Twitter at @RubyRep and that's it.

Back to Work
347: Beast Coast

Back to Work

Play Episode Listen Later Oct 24, 2017 89:41


TOPIC: Too much ambiguity in time. This week, your hosts discuss hot weather adjustments, Merlin's Skype woes, the state of the union on Skype replacement contenders, ruminations on Mac troubleshooting, the fraught future of retail comic book stores, a side rant on the really dumb economics of the comics industry, hobby shop nostalgia, lobby bell techniques and triangle mounting options, some great tips for pressing things on iOS Safari, the joys of Safari Reader mode, Chrome vs. Safari, changing our browser habits, and Dan's weird screen problem. Then, Merlin just goes freaking OFF on the problems with how we talk about time.

Back to Work
347: Beast Coast

Back to Work

Play Episode Listen Later Oct 24, 2017 89:41


TOPIC: Too much ambiguity in time. This week, your hosts discuss hot weather adjustments, Merlin's Skype woes, the state of the union on Skype replacement contenders, ruminations on Mac troubleshooting, the fraught future of retail comic book stores, a side rant on the really dumb economics of the comics industry, hobby shop nostalgia, lobby bell techniques and triangle mounting options, some great tips for pressing things on iOS Safari, the joys of Safari Reader mode, Chrome vs. Safari, changing our browser habits, and Dan's weird screen problem. Then, Merlin just goes freaking OFF on the problems with how we talk about time.

The Frontside Podcast
079: Web Security and Keeping Developers on the Cutting Edge via Trainings and Workshops with Mike North

The Frontside Podcast

Play Episode Listen Later Aug 10, 2017 41:29


Mike North: @michaellnorth | mike.works Show Notes: 00:51 - Transitioning from CTO to Independent Trainer 03:37 - Customizing Content and Developing Curriculum 06:37 - Bringing a Developer Into the JavaScript Ecosystem 12:47 - Training Developers with Non-Traditional Backgrounds 16:56 - Keeping Up with “Fifth Gear” 19:27 - Developing Frontend Masters Courses 22:40 - “Progressive Web Apps” 34:37 - Web Security Resources: LinkedIn's REACH Program IndexedDB Transcript: CHARLES: Hello, everybody and welcome to The Frontside Podcast, Episode 79. My name is Charles Lowell, a developer at the Frontside and your podcast host-in-training. With me today is Elrick, also at the Frontside. Hello, Elrick. ELRICK: Hey, what's going on? CHARLES: Today, we are going to be talking with Mike North, who is doing all kinds of interesting stuff as per the usual so we'll jump right in. Hey, Mike. MIKE: How is it going? I'm glad to be here. CHARLES: Last time that I saw you, I think it was about a year ago at the Wicked Good Ember Conf and we were standing on the beach, drinking scotch and talking about Fastboot but you were doing something completely and totally different then than you are now so I was wondering, we were talking the conversation before we started rolling, that your role nowadays is independent consultant and personal dev trainer. I was wondering if you talk a little bit about that move from the CTO role that you're playing at your old company to kind of moving into that independent trainer, like why and how. MIKE: Yeah, I do remember talking about Fastboot at Wicked Good Ember. It feels like things have moved quite a bit since then. I have always loved teaching developers. When I've been a team lead, it's the favorite part of my job just because I get profound satisfaction out of helping people get over these hurdles that most of the time took me a much longer time with blog posts and podcasts and incomplete examples and libraries that were out of date and Stack Overflow with half answers. I've decided to dedicate myself to trying to make it easier for people in an increasingly complex web development world to wrap their head around everything. While I was a tech lead or a CTO, I always had to split my focus between helping developers grow and something else. Oftentimes, that something else was where the deadlines were and the time pressure was. It felt a little bit like I was driving a car that only had first and fifth gear where you're like on the bleeding edge of open source and what was the latest commit to master and [inaudible]. Then like, "Oh, let's be extremely patient with this person. They've never seen promises before because they came from another programming language. Let's help them digest this at their own pace." It's this slow and patient process of building up from the fundamentals and then the bleeding edge is like, "Let's use Babel Stage 0." It was very hard for those two aspects to exist at the same time in myself so I decided I'm just going for the training side. That's really all I do these days. CHARLES: It was so, but now would you qualify that as the first gear or the fifth gear? MIKE: That's the first gear. It gets you off the ground. It takes you from stop and gets you moving and then you have to develop your own expertise beyond that. But I like to think I'm developing a really, really excellent first gear. Today for example, I'm converting a bunch of Python developers at LinkedIn who are basically the ops team. I'm teaching them Ember and JavaScript at the same time through a series of about 20 exercises over three days. That process is many weeks long without assistance so this is like, "Let's get rolling much more efficiently and quickly," than via DIY approach. CHARLES: Now, do you find you have to custom-tailor for the environment or the developers moving from like someone coming from, say C# would have a different experience than someone coming from Python? MIKE: Absolutely. When I have my material, I have sections that I can drop. If you are a C# developer, I do not have to explain conceptually what 'async' and 'await' mean. You've been working with that for a while. I probably throw up a little example in C# and then the equivalent in JavaScript to sort of create a bridge from your existing expertise into the JavaScript world. Another one -- this is very true -- is teaching Ruby developers how to use Elixir. You don't have to say, "This is a router. We have controllers. There are actions and controllers." There are so many parallels that really it's more useful to help, rather than teach things from scratch to create connections back to the expertise they already have so they're not starting from zero and they can say like, "In the Ruby world, I would think of doing XYZ." Now, I have a map in between that and this new thing. CHARLES: Obviously, there's a lot, a lot, a lot of languages and environments that you could transition to, probably more than matches your own personal experience, in doing that frontline development. What kind of research do you have to do to develop a curriculum for, say someone coming from Clojure or someone coming from Scala or something like that? Maybe that never happens. MIKE: I have a pretty, pretty broad background. My entry into programming was a subset of C and then I graduated to C++ and Java and Ruby and I used to do ASP stuff. I've written iOS apps. I feel like I have enough of a foothold into various areas like I know one JVM language. That is usually enough. If you're running a lot of Clojure, I can at least speak Java to you because odds are, you're working with that and you're seeing that and you know it. Oftentimes, I have what I need. There are situations where I can borrow something in a very cursory level. Not to rip on Scala but I have not found it valuable to make connections to that particular language for clarity and [inaudible] but I have used Haskell before and I'm not a Haskell developer but it is a pure functional language. When trying to help people understand how is this different, then the JavaScript got them running where the Ruby ends up running. It's useful to use something like that. It's a very small language, very simple and you can wrap your head around the basics. ELRICK: What are some of the particular challenges that you face when bringing in a developer outside of the JavaScript ecosystem into JavaScript since JavaScript is kind of the Wild West that you can do everything in JavaScript? What are some of the challenges you face in bringing in a new developer from Python or C or whatever that may be? MIKE: You put it very well. It is definitely the Wild West. You can do anything if you have enough [inaudible] yourself and enough power to get serious stuff done. Really, it's like the explosion in number of choices and tools, the explosion of complexity. I learned JavaScript when it was something that you sprinkle on top of your Rails app for a little interactivity, a little animation on a screen or something like that. I was lucky to learn it at that point in time when that was the norm because I've been able to gradually accumulate for more than ten years now. The tooling like using Grunt, using Golf, using Brunch and then stepping up to other more sophisticated build tools. I learned those one by one in the context of real projects. Now, it's like the mountain is so high, people don't know where to start so that's a big challenge for developers. To throw them into a meaningful project like if you asked a mean JavaScript developer, not angry but the average JavaScript developer, they're like maybe -- CHARLES: I should dare to say that the average JavaScript developer is mean. MIKE: A little bit and probably maybe [inaudible] with me as well, depending on [inaudible]. But they're going to spin up some project with webpack and Babel and all of these tools. If that's your first exposure to the language and to working with the language, you're operating in an environment that you don't understand. Research shows that is the less effective option there to slowly building things up over time. I spend a lot of time going back to the basics and making sure we're not working with promises until we've explicitly focused on them, chained a couple together, managed errors and then now, we can work with Fetch. We're not going to jump into that and throw ourselves into this deep end of the pool. We want to incrementally build up skills. It takes a little bit longer but when you have that understanding as you're learning, you get a lot more out of it because anything that you can't get a grip on to as you learn it, it sort of just evaporates into thin air and don't retain that, even if you kind of fill in those holes later. CHARLES: Yeah, it could be so hard too. Actually, this has been an experience that I've been having, I would say almost for the past two years, as the tools advance, not only you are starting from a place of not understanding but the tools themselves do not teach you. I've had two moments where I got really mad. One actually was on an Ember project and one was a project using webpack but it was the same fundamental problem where in one I was actually working with someone who was very new to JavaScript and an error happens and the stack trace was some just big bundled garbage that gave no insight at all. MIKE: In vendor.js. CHARLES: Yes, in vendor.js or in bundle JS. It was like, "How is anyone supposed to learn?" The most fundamental thing about working with Ruby or working with Node or working with anything is you get a stack trace. MIKE: Debugging is really hard. I think it just takes a little time reaching out to people who are experiencing the Stockholm Syndrome like most of the time, JavaScript developer. We all are working with Ember CLI and webpack. I'm not ripping on these tools but we're used to that complexity in our lives. When we see that stack trace, we're like, "Oh, well. I probably need a source map. I'll make sure that that's there. It's natural that I'm debugging a file that the browser is not really seeing like it mapped back to my source code debugging." This is natural to us. But if you put that in front of a developer who hasn't been living under those circumstances, the number of times they raised their hand is like, "What the hell is this?" It is just amazing and it really helps. I've reset my expectations to what a normal programming experience should be and JavaScript does not provide that today. That is really challenging to keep someone in the midst of all that. CHARLES: I feel like it's hard and do you think we'll ever achieve that? Or is it just going to be a constant hamster wheel of progress versus the tooling to educate what progress has been made or to communicate what progress has been made? MIKE: I think the tooling is fine but it's just that we have a gap in terms of learning experience. We just need really -- I'm not voluntary here because I've got a ridiculous backlog -- a couple long tail horses working with vanilla JavaScript, rendering some stuff on the screen, maybe a course of React but no JSX yet, just create component. A couple of things to fill in a gap between where maybe code school leaves off and where you are expected to be by the time you start interviewing for a spot as frontend developer on a team but there's a huge chasm right now. There's the intro guides and then there's professional life and trying to bridge the gap between those is ridiculously a challenge right now due to the huge ramp up of complexity from like, "Let's do some stuff in the console," to, "Running transpile JSX code with async [inaudible]. We've got regenerator in there to polyfill generator functions." There's so much in your average JavaScript at these days. CHARLES: Your work that you're doing at LinkedIn, part of it is trying to bring and train developers who come from more nontraditional backgrounds, including a lot of things like boot camps. What is your experience of their experience coming in? Are boot camps doing the right thing? Are they teaching the right things? Are they trying to kind of parachute them on top of that mountain? Or do you find that they're just at the base camp, so to speak? Because it sounds like your approach is like you've got to really start from fundamentals so that you can understand the layers of complexity if you're going to, someday stand on them. MIKE: I think a lot of the boot camps are doing an excellent job. These days, the employees we have at LinkedIn who come from boot camps, I would bet on them against your average MIT grad every time, just because their education is so practical. It's amazing that in the world of computer science, the stuff that you're taught in school is a little bit farther removed than one would expect, compared to the stuff that we do every day in our jobs -- building real apps. I do not need to know in my day-to-day work at LinkedIn how an operating system works or how to build a device driver. This is a little bit too fundamental. It's the wrong abstraction for practical everyday work for most people. Where in these boot camps, they focus completely on the practical. In fact, I've been fortunate enough to get involved with the REACH program here at LinkedIn, where we hire explicitly people from nontraditional backgrounds like boot camps. They're not all from boot camps but many of them are. We just hired 30 of them in March. The pilot program, I think we've hired two or three in our New York office and it just went really well. It started like, "Let's double down and double down again and double that again." This time, we're doing 30 and I expect there will be a new round next year where we poll even more. The idea is we take these REACH candidates and pair them with a mentor engineer for six months. At the end of that six months, we had to make a decision as to like this person at the level we expect of an entry level software engineering hire. From what I've seen, we're doing really well at preparing these folks and they're unbelievably valuable to the teams that they've been placed in. ELRICK: That's amazing. That's very interesting. Is there a standardized curriculum thing that each mentor will follow to get this person after they entered his REACH program and then ramp them up or is it like each person just goes and looks at what the person knows and then ramps them up accordingly. MIKE: I'd say, it's a mix of both. We have a set of technical trainings for them or we'll have a testing expert from within the company and teach a little testing seminar to them. There's that standardized curriculum there. But the nature of being taught by boot camp or teaching yourself is that you're going to have holes in your knowledge and it's not often predictable where those holes will be. That's why we make sure we do this mentorship very explicitly and over a long period of time so that if it turns out that you never learned about how to work with tree-data structures. That was not part of the go-no/go decision that brought you on but we should probably, at least get you there. At least to the point where if you're traversing a down tree and you're like parent and child, what is this, what do you mean by leaf-level node. This is stuff that is actually meaningful for web developer in some cases. CHARLES: In the context of the work that you're doing with the REACH program but also touching on something that we talked about at the beginning about the first gear and the fifth gear, part of generating a curriculum is still being in contact with what's up in the fifth gear right because ultimately, what you're trying to do is you're working with people who are in first gear or looking to get a smooth transition in the first gear but at the same time, you want to set them up and you want to be in contact for what's in fifth gear now is going to be first gear in five years. How do you feed that in? MIKE: I'm fortunate to have a great team that I work with here. This group that I roll up to in LinkedIn, they're experts and you probably know of like Chris Epstein and Tom Dale and Steph Petter. A 15-minute coffee break with one of these people is enough to keep [inaudible]. Sometimes, it's a little bit like drinking from a fire hose because it's like I spend an hour with a student trying to help them understand like, "This is why a Promise is useful. Here is the callback equivalent," and then now, "Let's dive in to Glimmer. Why this track annotation is the right way to go for automatic updating." It sends me for little bit of a loop sometimes but it is definitely keeping me up to date. The other factor, of course is when you've been doing this for a while. History sort of repeats itself so a lot of the patterns that we're seeing today, I've seen somewhere else. I was working with code splitting when I was writing Dojo JavaScript code years and years ago. I was defining my module layers in a very explicit way. I had to do that. I didn't have done a webpack that would figure out, put these splits are. But I have that experience to look back to and for that reason, it is not often that an entirely new concept comes along. Oftentimes, they're like amazing refinements on things that how to smell like stuff that we've used before in the software engineering world. CHARLES: Yeah or here's something that has never been used, is very prevalent in these other context which we're going to apply here. MIKE: Exactly. CHARLES: And like, "Oh, my goodness. It's a perfect solution." In addition to the work that you're doing with LinkedIn and developing those training curricula and stuff, you're also doing some work for Frontend Masters in an area that's very exciting, I think to me. I'm sure it's exciting to you because you decided to throw a whole lot of time into developing a course for it. That's in the development of progressive web apps, which for me has been like this thing that I'm so curious about but I'm like a kitten playing with a little yarn ball. I want to dive in but I'm just going to tap it with my paws right now. MIKE: Yeah, it's a really interesting area and I think that even if you're not using progressive web technologies today, it's one of these things that sort of reinvigorates your energy for JavaScript's future and what may be possible soon. Steve and I have put together this amazing progressive web app course, which has I think like 18 short examples of iteratively building up a grocery shopping app. If you've used InstaCard or something like that, we start out with app already built and it's like a single-page app as doing everything that you would expect. After a few of the exercises, it works offline. After a few more, you can add stuff to the card and background sync, push it to the API when you come back online. We get deep, deep, deep into service workers. That's one of the areas that my work at LinkedIn and my teaching with Frontend Masters overlaps really well because I've been heavily involved in creating our service worker for LinkedIn.com. I may be able to take some of what we've learned here and disseminate it a little bit so that, hopefully fewer people have to learn the hard way. It's best to keep things simple at first and add on functionality. I'm about to cross like the [inaudible]. This is my favorite just because the example turned out to fit so well and in particular, on Frontend Masters, I think Steve and I have had contrasting teaching styles but they complement each other so well because I'm like the 'melt people's brains' instructor. I love to throw people exercises that are like 120% of what they can do and it's going to hurt, just like when you're lifting weights at the gym, like you're going to beg for mercy but we're going to make you strong. Then Steve, just listening to him, even with I am in the classroom and he is teaching me Electron. He's so energizing and he's really funny too but not in an overtly cracking jokes kind of way. He's just so fun when he teaches. I think it is a really good combination just because things lined up just by luck and through hard work and just the right way out of a couple of important areas. CHARLES: Now, just for people who might not be familiar with the term progressive web apps, what does it encompass? Do people actually call them PWAs? MIKE: No. I'm going to start, though. I like that. That carries very well over a video chat or something. Nobody knows how to spell that: P-U-A? P-W-U-A? It is a rejection of the old idea that in order to take advantage of some web technology, it has to be supported in all of the browsers that we need to support. The idea here is to hold as a core tenet of our design practices, the idea of progressive enhancement, meaning we serve up a basic experience and where we can take on these superhero features, like the ability to work offline, the ability to receive push notifications, we go ahead and do so. If your browser doesn't support this, that's unfortunate. No big deal. You still get a good experience. But if you're using a very recent version of Chrome or Safari or you have a new Android device, these browsers can take advantage of sophisticated metadata or sped up a background process that can serve up data to your app and your app doesn't even know that there's something between it and the API. That is the idea of progressive web apps -- apps that become superheroes where possible and they still work and provide a great basic experience for antiquated browsers like IE8 and Safari. CHARLES: The idea theoretically, you could work without any JavaScript or whatsoever. What's the ground floor there? MIKE: That is ideal. I think server-side rendering, which is what you're talking about there, even if JavaScript is not working, just HTML and CSS will provide a basic experience. That's great but that's not a modern browser technology thing. If you have JavaScript turned off in today's Chrome, like Chrome 60, versus IE9, both of them working with them without JavaScript. What we're really talking about here is app-like characteristics, where we are pushing web technology to the point where you will swear that this came from an App Store. It's on your home screen. It's running in the full screen. You're getting push notifications. It works offline and you can store a large amount of structured data locally on the device. All of the stuff sounds like the list of reasons to reach for native mobile technology because the mobile web is not good enough. But in fact, it has a feature set of this family of progressive web technologies. It's really like a web app that is so good and so modern that it feels and looks just like a native mobile app. CHARLES: That sounds so hard to do right. MIKE: Well, it is now, just because what we have to work with can be thought of it like a basket of ingredients, rather than a solution that we drop in. But over time, as more people start working with these ingredients, I think we're going to see a lot of consensus around the best patterns to use and boilerplate code will fall away as we can identify that the set is in fact commonly needed and not a beautiful and unique snowflake. CHARLES: Because it seems like the thing that I always struggle with is not wanting to put the critical eggs in the basket of a superhero feature or have you being able to provide an alternative if the superhero feature doesn't exist. Some features, if you just don't have it, that's fine. You can turn it on if the capabilities available but certain features are very critical to the functioning of your application. I'm casting about for an example and I'm not finding one immediately but -- MIKE: Offline is a great one. That fits pretty neatly. If you're using an older browser or if you're using Safari, which by the way, I should stop ripping on Safari. For the listeners out there, we saw a commit lend in webkit, where service for APIs are beginning to be stubbed out. No longer do we have to look at length. Service worker, enthusiasm and Safari has got it in the five-year plan. There was motion last week. We haven't seen motion in ages so thank you Safari Team. Thank you. Keep up the good work. CHARLES: Is there a discipline of Safari-ologists who monitor the movement of Safari to bring this news? MIKE: Of course, we monitor it because right now, Chrome and Firefox, they are pretty much hopeful in terms of supporting this modern stuff. Opera supports this modern stuff. Samsung's fork of Chromes support this modern stuff. Especially when we think about the mobile web, you got to worry about Android and you got to worry about iOS Safari and right now, like we've talked about these progressive web apps, you don't get that superhero experience on an iPhone or an iPad. Once we crossed that threshold, this is going to have a breakaway level of adoption because there are no more excuses. Essentially, for a mobile web experience, you can send push notifications to the user. That is huge. That is probably at the top of the list for why some people use native apps, instead of mobile web. The more we can do that, the more we can make it so that a great LinkedIn experience can be delivered to your phone without having to install a binary. I just have to update Facebook the other day and it was over 100 megabytes. Why do we need to do that? You should be able to make it work with less. I'm sure that there's some great stuff in there. Apparently, Snapchat filters are popular but I don't need this. Can we code split that away or something because I don't want to have to download that? I can't even download it on the cell network because it's over 100 megabytes. It's really exciting to see the web start to compete with this heavy mobile experience because now I think is ready. CHARLES: Now, when you talk about push notifications, you're talking about being able to send things to my lock screen. MIKE: To your lock screen while the browser is not on the foreground, while the app is not open. Essentially, you're installing a lightweight process that runs in the background. It receives events that originate from your server and the user can tap on them and then your little lightweight worker process in the background decides what to do when that tap happens, like open up the app, take them to this URL or something like that. That is a game changer. That's huge. Or background sync like the user added some items to their cart and then they lock their phone and now, their plane has landed. That's why they were offline and they get back on the internet and without them having to touch their phone, now we can push that data to the server and everything's in sync, rather than like, "Please revisit your app. We need to run some JavaScript code to flush IndexedDB or API." It still feels like a hack at that point. This is a fluid experience. ELRICK: Wow. This is exciting for me as I don't have any more space on my cellphone, thanks to all the apps that I have to install to do various things on the web. MIKE: You're not alone. CHARLES: Yeah, it's crazy and just the amount of code sharing that you can have, I guess that doesn't happen much these days on the web where you've got these popular libraries out on CDNs so that the chances are that you've got jQuery 1.2.1 on your cache, you've got 16 versions of jQuery so most of your web applications don't have to do that. I guess we kind of do the equivalent of statically linking everything. MIKE: There is a benefit near that where we have imperative code managing our cache, instead of just relying on the HTTP cache or app cache, if you have a vendor.js file that is not changing over six months, there is no reason you should be re-downloading that every time you deploy your app or letting the browser evict that, just because memory pressure is high from Google image search results or something like that. We really don't have much control over it. But with a service worker, we can say, "Hold on to this," or maybe like prefetch the next version of the app so that we're going to show you the old version now but the next time you refresh, here's the new version available instantly. It's downloaded in the background and it's like click to update your version, like it's already here waiting for you. That's huge. That's amazing. CHARLES: That is amazing. Although the complexity skeptic in me is thinking, "Oh, my goodness. Now, we've got all this state that we're storing on the server. We have to have data migrations." We need some sort of migration mechanism for our clients-side state and perhaps some transaction and rollback in case you're not able to successfully migrate your data. It sounds like a lot of fun but I'm just imagining we really are getting started here. Has there been any work on that aspect? MIKE: If you've ever worked with IndexedDB, it does have a concept of migrations. Basically, the data you store on a device has a version and when you read in what's called a file but it's a database, when you read that in, the first thing you do is you basically bring it up to date incrementally. You'll bring it in, you're looking for version nine like your code wants version nine. What you see is version two because your user hasn't been at your site for six months and you're going to take it from two to three to four to five to six. Each of those, essentially constitutes a migration. We just have to apply the same principles of forward-compatible changes. The escape hatch here is remember it's progressive enhancement so if we had to destroy everything, fall back to a basic experience and start from scratch, like discard all of our data, it's really being held there as an optimization. Some people use this immutable caching strategy or basically, like rolling out a new service worker version constitutes for the most part. Any data that wasn't created by a user you're going to discard that and you're going to fetch it new. You don't have to worry about like, "Crap. This six month-old thing is still plaguing half our users and we can't get rid of it," like you can have [inaudible]. But you should really check out this course. It is simpler than you think and what we demonstrate is not a trivial like hello service worker. It is taking in a classic single page app, making it completely offline, having it exist on the home screen and I think the service worker ends up being no more than 100 lines of code. It's not too bad. ELRICK: I'm definitely going to check that out because my progressive web app journey is still on just service workers. MIKE: That's very [inaudible], though. ELRICK: Yeah. I'm definitely checking it out. Sounds like a really fantastic course. MIKE: I've been focusing a lot on this area and another one is security. The reason I picked these two is because developers are not really going to learn about these on the critical path to [inaudible] plus they learn about them the wrong way. As the JavaScript world is becoming radically more complex with each passing year, I've tried to target some of my efforts towards areas where they are not getting as much attention as I'd like to see, just because we have to focus somewhere. Obviously, getting the app out and figuring out how to make the build tools work for us. Without that, we can't do anything at all. One of the courses that's coming in September for Frontend Masters is a one-day web security workshop or we'll do with like cross-site scripting, how to work with certificates because if you start playing with HTTP/2 -- the next generation of HTTP -- you will need to generate some certificates for development at least today you need to. I've seen some amazingly smart developers get this dangerously wrong to the point where they compromise their own machine and anything that's on that machine, just by trying to set up dev environment. Typically, I'm an optimist but when it comes to this PWA stuff and security, I am paranoid. I feel like, we as a community need to get together and have the discipline to brush up in these areas so that as we introduce all of this new stuff, we don't end up opening a bunch of holes. Nowhere near the same rigor as put into frontend compared to backend and now, the line is blurred. Right now, we're server-side rendering so our code is running on the backend somewhere so injecting something can really mess things up in a bigger way. ELRICK: Yeah, I think that's a fundamental characteristic of someone does going to be involved in security paranoia. You have to be paranoid about everything. MIKE: Yep. I don't trust anything. CHARLES: It's important to make those things easy because I'm definitely fall more into the hippie camp like, "Everything is going to be fine. Let's trust everybody," which is I know is totally unrealistic. But then you get into these secure technologies and you learned enough of it just to get the task that you're going to do and then you forget. SSL is a great example. Over the course of my career, I've learned how SSL certs have worked probably, at least 10 times. ELRICK: Right, [inaudible] you had to set it up in production. CHARLES: Yes, exactly and then I promptly forget about it, never worry about it again and then the next time I'm like, "How did that work? What's this trust chain? What?" ELRICK: Exactly. I read a study from Carnegie Mellon a couple of years ago that showed developers observe security best practices dramatically less than the general public and the general public is not good. Do you know what I'm talking about when I say a certificate warning and a browser, there's big scary red screen saying like something is wrong here? Before the Chrome team put some effort into improving that, 70% of people would click through those and proceed anyway. After their improvements, over a third of people still clicked through and that number when you just look at Canary versions of browsers, that number is actually considerably higher close to 50% of our developers. We're trained by every broken certificate system that exists on the internet like the legitimate ones or maybe some things just expired. They're training people to just click straight through these things and as a result, it is terrifyingly easy to mess with people. We have to remember as developers, our machines, those have the private deploy keys and those have the SSH keys to commit code to GitHub, we have to treat that like it's a private data. It's really, really important that we make it easy and that we make sure that that easy path is also very safe. CHARLES: Absolutely. All right. Well, thank you so much Mike for coming by and talking with us. We touched on a lot of subjects but I feel like I certainly learned a lot. MIKE: Yeah, thanks. It's been so much fun talking with you this morning. CHARLES: Anybody who wants to go and check out those courses, they're on Frontend Masters. Now correct me if I'm wrong, you've obviously got the one on progressive web apps or PWAs. If it doesn't work offline, it's faux-PWA. MIKE: Yes, I like that. That's going to become a t-shirt sometime soon. CHARLES: The fundamentals of progressive web app development, which is now released if I understand correctly. MIKE: Members have access to everything, you can watch the raw video now. The edited course will be available later this year. CHARLES: Okay, and that's with Steve Kenny. I am very much looking forward to looking at that and learning more about it. Then you've also got ones coming up in September on TypeScript web security in Visual Studio Code. MIKE: Yep and members can watch that as a live-streamed event. Frontend Masters even ask people to watch the comment stream so you'll have a proxy question asker or hand raiser in the room. It's really a great experience to be part of a live thing. CHARLES: Oh, man. That sounds awesome. Then if you are obviously doing your independent consulting and if people want to get in contact, how would they do that? MIKE: You can find me on Twitter, @MichaelLNorth or you can visit my website, Mike.Works and I have all of the courses I teach and outlines and I can just open up a little chat bubble on the lower right, ask me any questions that you have. I am really passionate about teaching people. If you like that's useful for your team, please reach out and I'd love to talk. CHARLES: Fantastic. Thanks, Mike and thanks everybody for listening to us. If you want to get in touch with us, you can always do that. We're on Twitter at @TheFrontside and email, Contact@Frontside.io. Thanks, Mike. Thanks, Elrick and I will see you all later. MIKE: Thank you so much. ELRICK: Bye.

科技最前沿,论天文物理 人工智能 数码编程 大数据等
513、Google 版小程序,为什么大家都喜欢用?|灵感早读

科技最前沿,论天文物理 人工智能 数码编程 大数据等

Play Episode Listen Later May 12, 2017 18:25


爱范儿 2017-04-26 10:41过去的 2016 年里,你一定不下数次听到 PWA 这个词,但它究竟是什么呢?PWA 其实是一种渐进式的的无需用户安装、可被随时唤起的 Web App,融合了 Native App 的结构、交互、降级方案等的更优体验技术,使得用户通过浏览器打开网站时,获得有如原生 app 般的顺滑体验。Google 的官方文档中是这样介绍的:PWA(Progressive Web App), Progressive Web Applications take advantage of new technologies to bring the best of mobile sites and native applications to users.利用最新的技术带给用户最好的无线体验。按照官方文档,PWA 具有这些特性:Reliable, Fast, Engaging。可靠的(Reliable):瞬间加载,即使在不稳定的网络下也不会显示 downasaur(小恐龙页面),通过预加载缓存关键资源,消除对于网络的依赖,确认用户在无网络或者网络情况较差情况下的即时可靠体验。快速的(Fast):快速响应并带给用户平滑的动画体验,没有卡顿。参与感(Engaging):原生 app 一般的体验,具有沉浸式的用户体验,可以将 Progressive Web App 安装在用户的主频幕上,甚至没有浏览器的头部,给用户提供一种如原生 app 的全屏体验。但说了这么多,关于 Progressive Web App 我们应该关注些什么呢?独立的 Logo快速加载 App Shell 模型添加到主屏幕,从主屏幕启动App-like 启动画面Web App ManifestService Worker 离线缓存推送通知 Push Notification简单概括描述一下,PWA 是一种给用户提供无需下载、快速启动、顺滑体验的一项移动端技术。独特的识别性,快速与 Native App 进行区分PWA 可以拥有一个桌面图标。Flipkart 不仅重新设计了 icon,还将 PWA 改名为 Flipkart Lite。使用 App Shell 快速加载页面App Shell 预加载页面的框架结构和基础 UI 元素,渐进式缓存,动态加载内容。很多网站在加载页面时都会遇 loading 等待的问题,这段时间里其实服务器在紧张的传输数据给客户端,再由客户端将结构渲染出来、内容填充进去。可惜用户并没有耐心等待,大家极有可能在这短短几秒内就关闭页面走掉了。通过 App Shell 快速加载,可以减少用户界面中的白屏感受,让用户知道数据正在填充回页面。无需下载,随时唤起PWA 让 Web 应用能够像原生应用一样添加到主屏,无需通过应用商店下载,减少了用户安装原生 app 的成本。用户可以通过 Chrome 等浏览器的侧边栏添加(下图左)或者通过 Chrome 弹出的 Add to Home Screen Banner 选择同意添加(右图)。可将 PWA 自带的 icon 生成一个桌面 app 图标,方便用户随时唤起。友好的启动页在无线页面中,所有的元素都是实时渲染的。所以 PWA 增加了类似 Splash screen 的等待画面,显示品牌 Logo 和品牌名,以便在这个等待时间内,预加载第一个页面所需的资源,缓和用户的等待时间。沉浸式的的全屏体验 Web App Manifest用户点击被保存在桌面的 PWA icon ,进入全屏的 PWA 界面。没有了浏览器头部,Progressive Web App 和 Navtive App 几乎没有界面上的差别。用户在浏览和使用页面的过程中,完全感知不到卡顿,所有的动效和反馈都是接近原生体验的。这对于像欧美这些应用下载意愿较低的用户而言,无疑是更进一步提升了在手机端的使用体验。无网络也能访问当你处于无网络时,可以继续使用 PWA,会自动加载你已经缓存的内容得以在离线时继续访问。这对于像巴西这类流量资费偏贵的用户来说,可以节省很多不必要的浪费。不同网站对于 Service Worker 的使用也不同:Flipkart 在无网络状态下,置灰展示所有页面信息,所有已经加载的内容可以继续浏览,但是给到用户的感觉过于消极;Digikala 在无网络状态下,仅使用灰色提示用户已经离线状态;Alibaba 在无网络状态下,通过品牌定义的报错颜色提示用户出于离线状态,但是由于整体页面都比较明亮,用户感知不到处于离线状态;Currency Converter 在无网络状态下,缓存的汇率比例可以继续离线使用;可以看到不同产品对于自己产品诉求的不同,使用离线提示的方案也会各有不同。不安装也能推送通知 Push NotificationPush 是如今的产品必不可少的一个营销工具,我们需要通过它传递信息、唤醒用户。但通常的 Mobile Site 是不具备 Push 能力的。PWA 却可以,它能像 app 一样接收网站讯息,通知用户网站产生了新的内容或者和用户相关的通知,促使用户的回访。与很多喜欢尝鲜的团队一样,2016 年初我们开始与 Google 团队合作,推动 PWA 技术在 AliExpress 上的落地。希望通过“新设计带来新体验;新技术推动新变革” 来看看 PWA 对于电商平台的意义。结果是非常令人惊奇和满意的。AliExpress 发现新用户的转换率增加了 104%。在 Safari 的转化率也上升了 82%。现在用户每次访问的页面数量是原先的两倍,也大大提升了用户浏览页面的时间。AliExpress 的 Mobile Site 存在已经有些年头了,逻辑也不比 app 简单,想要重新开工并不是件容易的事情。而对于设计团队,我们的精力主要放在了以下几个方面:无线「格式化」抛弃了原有 PC 年代的 Header 和 Footer 的形式,以更符合 Web App 的特性。优化交互结构使用了类 app 的头部导航结构,整合页面中的功能,更合理的利用首屏的高度,更充分的展示有效内容。界面升级不仅在 UI 界面层遵循了 Material Design ,也在功能动效的还原上接近原生体验。结果喜人,但过程同样也是坎坷不易的。有些 tips 给到大家:1. 为你的 PWA 设计一个有识别性的 icon ,区别于 Native App icon(如果你有的话)。由于市面上有较多投放尺寸,所以桌面启动icon需要适配各种场景,包含的内容:Android Chrome 桌面图标及开机画面iOS Safari 桌面图标及全屏开机画面浏览器 favicon Windows Phone 图标其他配置推荐使用 Favicon Generator for all platforms: iOS, Android, PC/Mac… 来生成各种尺寸的图标及配置。2. 梳理原有交互框架结构,使得页面层级更轻量,流程更简洁。确认 App Shell 首先预加载的框架结构和 UI 元素,为每个页面设计渲染加载图片。

CartoonSmart Tutorials
How to Open URLs in Safari with Swift and Sprite Kit (Episode 11)

CartoonSmart Tutorials

Play Episode Listen Later May 7, 2016


This video we'll learn how to open the Safari window within your iOS app itself, which can also limit the user from opening other domain, or simply pass the user off to the actual iOS Safari app.