Wojna pomiędzy przeglądarkami dbającymi o prywatność użytkowników, a serwisami personalizującym reklamy trwa już od dobrych paru lat. W minionym tygodniu pod przykrywką dbania o użytkowników Facebook zaprezentował nową broń w swoim arsenale – szyfrowanie query params.
1. Facebook idzie na wojnę z Firefox i Brave?
Po aferach takich jak Cambridge Analitica świadomość ludzi w kwestii prywatności w mediach społecznościowych znacząco wzrosła. Ciężko mi powiedzieć jak duże odwzorowania ma to w całokształcie społeczeństwa (prawdopodobnie niewielkie), ale wśród moich kolegów programistów coraz większy odsetek korzysta z Brave lub z mechanizmów ochrony przed śledzeniem Firefox i Safari.
Na całym zjawisku najbardziej obrywają dostawcy reklam, którzy powoli tracą możliwość ich personalizacji. Nie czekają oni jednak bezsilnie i nieustannie pracują nad rozwiązaniami, które zadowolą obie strony konfliktu. Najlepszym tego przykładem będzie Google, który po porażce FLoC (alternatywy dla śledzenia przez ciasteczka) pracuje aż nad pięcioma potencjalnym algorytmami.
Kilka tygodni temu ukazała się aktualizacja Firefox, która do pakietu funkcjonalności ochrony przed śledzeniem dołożyła możliwość usuwania najpopularniejszych śledzących query params. Nie jest to funkcjonalność zupełnie nowa, bo na przykład Brave oferuje ją już od dłuższego czasu, Jest to jednak pierwszy przypadek, kiedy funkcjonalność ta trafiła do pierwszoligowej przeglądarki.
Co ważne, nie mówimy tu o wszystkich śledzących query params, ale o tych szczególnie złośliwych. Przykładowo znane z Google Analytics ‘utm_medium’, ‘utm_source’, ‘utm_medium’ i `gclid` pozostały nietknięte. Analogiczne facebookowe `fbclid` usuwane jest całkowicie. Dlaczego? Informacji na ten temat nie znalazłem ani w release note Firefox, ani w opisujących je mediach.
Na odpowiedź firmy Marka Zuckerberga nie musieliśmy czekać długo. Facebook usunął wszystkie linki z parametrem `fbclid` i zamienił je tajemniczymi nowymi parametrami takimi jak`__cft__[0]` czy` __tn__`. Ich usunięcie nie jest możliwe, gdyż kodują one zarówno informację o lokalizacji na jaką przenieść należy użytkownika jak i identyfikator śledzący. Całość zaszyfrowana jest nieznanym jeszcze publicznie algorytmem, więc nie ma sposobu na pozbycie się złośliwego identyfikatora śledzącego nie psując jednocześnie samego linku.
Przedstawiciele Facebooka bronią się, twierdząc, że nowa funkcjonalność ma na celu nie tyle obronę przed wycinaniem parametrów śledzących, co obronę przed scrapperami. Znając identyfikator użytkownika czy strony, taki scrapper był w stanie pobrać publiczne posty umieszczone na tablicy. Poprzez zaszyfrowanie adresu nie będzie to już możliwe. No cóż, zimna wojna o prywatność użytkowników trwa nadal.
Źródła:
https://www.bleepingcomputer.com/news/security/new-firefox-privacy-feature-strips-urls-of-tracking-parameters/
https://www.ghacks.net/2022/07/17/facebook-has-started-to-encrypt-links-to-counter-privacy-improving-url-stripping/
Zainstaluj teraz i czytaj tylko dobre teksty!
2. React Native – Hermes coraz bliżej
O nowym silniku renderowania React Native słyszy się już od dawna. Po raz pierwszy został on zaprezentowany światu w połowie 2019 roku i działał tylko na Androidzie.
Trochę ponad rok temu zespół Facebooka przygotował również wersję na system iOS, czym wywołał małą furorę. Był to bowiem pierwszy przypadek kiedy na urządzeniach z jabłuszkiem działał inny silnik JavaScript niż Applowy Webkit.
Niespełna pół roku temu, zespół React Native ogłosił, że Hermes stanie się domyślnym silnikiem JavaScript dla ich frameworku. Dzisiaj stoimy u progu tej historycznej zmiany, bo React Native 0.70, który ostatecznie ją przypieczętuje, ukaże się już za kilka tygodni.
Hermes jest szybszy od aktualnie używanego silnika JSC. Jest tak przede wszystkim ze względu na przeniesienie parsowania i wstępnej kompilacji z inicjalizacji aplikacji do procesu jej budowania. Dzięki temu jednemu sprytnemu trikowi, początkowy czas uruchamiania aplikacji spadł o ponad 50% procent.
Nie poruszamy tematu Hermes bez przyczyny. Zespół React Native na swoim blogu przygotował notatkę przygotowującą deweloperów na tą historyczną zmianę. Znajdziecie w niej całą niezbędną dokumentację i garść ciekawych benchmarków. Jeśli jesteście głodni szczegółów, to zapraszam do linku, który znajdziecie w źródłach.
Źródła:
https://reactnative.dev/blog/2022/07/08/hermes-as-the-default
Zainstaluj teraz i czytaj tylko dobre teksty!
3. Jednolity stan, czyli dlaczego frontendowe frameworki są jak fizyka kwantowa
Jeśli myślicie, że sezon ogórkowy trwa właśnie w najlepsze to… no cóż, macie rację. Ze względu na to, że nowości nie dopisały, na zakończenie dzisiejszego przeglądu przyjrzymy się ciekawemu Twitterowym wątkowi (oryginał znajdziecie w źródłach – ja w trosce o Waszą wygodę skopiuję snippety kodu tutaj). Okazuje się bowiem, że prosty, kilkulinijkowy kod przetłumaczony do najpopularniejszych obecnie frameworków daje kompletnie różne rezultaty.
import React, { useState, useMemo, useRef } from 'react';
export default function App() {
const [count, setCount] = useState(0);
const doubleCount = useMemo(() => count * 2, [count]);
const elem = useRef();
return (
<button
ref={elem}
onClick={() => {
setCount(count + 1);
console.log(count, doubleCount, elem.current.textContent);
}}
>
{doubleCount}
</button>
);
}
React podczas renderu utrzymuje stałe referencje obiektów, a efekty aktualizacji stanu widoczne będą dopiero podczas kolejnego renderowania.
Wynik: 0 0 0
<script setup>
import { ref, computed } from 'vue'
const elem = ref()
const count = ref(0)
const doubleCount = computed(() => count.value * 2)
function handleClick() {
count.value++
console.log(count.value, doubleCount.value, elem.value.textContent)
}
</script>
<template>
<button ref="elem" @click="handleClick">{{ doubleCount }}</button>
</template>
Vue natychmiast aktualizuje modyfikowaną zmienną i jej zależności, ale odświeżenie HTML’a następuje z opóźnieniem.
Wynik: 1 2 0
<script>
let count = 0;
let elem;
$: doubleCount = count * 2;
function handleClick() {
count++;
console.log(count, doubleCount, elem.textContent);
}
</script>
<button bind:this="{elem}" on:click="{handleClick}">{doubleCount}</button>
Svelte natychmiast aktualizuje zmienną, ale nie przelicza zależności i nie odświeża wartości w DOM.
Wynik: 1 0 0
const App: Component = () => {
let elem: any;
const [count, setCount] = createSignal(0);
const doubleCount = createMemo(() => count() * 2);
return (
<button
ref={elem}
onClick={() => {
setCount(count() + 1);
console.log(count(), doubleCount(), elem.textContent);
}}
>
{doubleCount()}
</button>
);
};
export default App;
SolidJS to jedyny framework, który wraz z aktualizacją stanu odświeża zarówno wartość zmiennej i jej zależności jak i HTML.
Wynik: 1 2 2
@Component({
selector: 'my-app',
template:
'<button #ref (click)="handleClick()">{{ doubleCount$ | async }}</button>',
styleUrls: []
})
export class AppComponent {
@ViewChild('ref') button: any;
readonly count$ = new BehaviorSubject(0);
readonly doubleCount$ = this.count$.pipe(map((it) => it * 2));
constructor() {}
async handleClick(): Promise<void> {
const count = await firstValueFrom(this.count$);
this.count$.next(count + 1);
console.log(
await firstValueFrom(this.count$),
await firstValueFrom(this.doubleCount$),
this.button.nativeElement.innerHTML
);
}
}
Pewnie zauważyliście, że wśród wymienionych w twitteromy wątku frameworków brakuje Angulara. Jest tak zapewne dlatego, że nie posiada on analogicznego API hooków. Posiada on natomiast dobrą integrację z RxJS, która w większości przypadków może zastąpić hooki. Powyżej znajdziecie moją Angularową implementację.
Wynik: 1 2 0
Które rozwiązanie jest najbardziej czytelne? Ku mojemu zaskoczeniu, wyniki wszystkich frameworków są sensowne. Ja najbardziej skłaniam się ku funkcyjnemu podejściu Reacta (zmiana wartości zmiennych jest równoznaczna z kolejnym wywołaniem funkcji) i zrównoważonemu podejściu Vue i Angulara (zmienne odświeżane są natychmiast, ale ciężka operacja renderowania odkładana jest na koniec wykonania funkcji). A Wy co sądzicie na ten temat?
Źródła:
https://dev.to/this-is-learning/the-cost-of-consistency-in-ui-frameworks-4agi
https://twitter.com/ryancarniato/status/1353801009844240389