HTTP 標準的翻新

HTTP 的標準之前都是用新的 RFC 補充與修正舊的標準,所以整體讀起來會比較累,對於開始了解 HTTP 的人會需要交叉讀才能理解。

而這次 RFC 9110~9114 算是一次性的把文件全部重新整理出來,可以看到蠻多人 (以及團體) 都有丟出來對應的看法,這邊丟這兩篇:「A New Definition of HTTP」與「HTTP RFCs have evolved: A Cloudflare view of HTTP usage trends」。

而這五個 RFC,從名稱列出來就可以看出來命名簡單粗暴,把核心概念先拆出來講,然後再講不同 protocol 的部份:

Cloudflare 這邊提供了一些資料,可以看到三個 protocol 使用率都算高,而目前最高的是 HTTP/2:

另外比較特別的是 Safari 在 HTTP/3 的趨勢居然有倒縮的情況:

然後 bot 的部份幾乎大家都支援 HTTP/2 了,目前還沒看到太多 HTTP/3 的蹤跡,倒是 LinkedIn 的 bot 有個奇怪的 adoption 然後全部 rollback 的情況,而最近又開始少量導入了:

這次看起來淘汰了 (obsolete) 很多之前的文件,以後要引用得往這五份來引...

GOV.UK 拔掉網頁上的 jQuery

英國政府的網站拔掉 jQuery 了:「GOV.UK drops jQuery from their front end.」,Hacker News 上的討論也可以看一下:「Gov.uk drops jQuery from their front end (web.dev)」。

當年會選擇用 jQuery 大概有幾個原因,第一個是當年 (很舊的 browser 版本) 對 DOM 的操作非常的混亂,像是:

而 jQuery 在那個年代就已經把這堆 DOM operation 都窮舉支援了 (可以直接看「Category: DOM Insertion, Around」、「Category: DOM Insertion, Inside」、「Category: DOM Insertion, Outside」這三個大分類),可以注意 jQuery 1.0 就已經把基本界面都弄出來了,而 jQuery 1.0 是 2006 年八月出的,另外 IE7 是在 2006 年十月出,也就是說在 IE6 的年代就提供一整套完整的方案。

另外 jQuery 幫忙處理了早期 IE 與 W3C 標準的不一致行為,像是經典的 attachEvent (出自 DOM events):

Microsoft Internet Explorer prior to version 8 does not follow the W3C model, as its own model was created prior to the ratification of the W3C standard. Internet Explorer 9 follows DOM level 3 events, and Internet Explorer 11 deletes its support for Microsoft-specific model.

就功能面上來說,jQuery 提供的 Sizzle engine 也提供了 CSS selector 的能力,這在早期還沒有 querySelectorAll() (IE9+) 的時候方便不少,而且就算有了 querySelectorAll(),Sizzle 支援的 CSS selector 更完整。

上面提到的解決 browser 早期的各種亂象,jQuery 其實也帶入了不少好用的 pattern,其中一個是 fluent interface 讓人寫起來很舒服:(這個範例只是要介紹 fluent interface,不要管實際上在亂搞什麼 XD)

$('#foo').html('<p>bar</p>').css('width: 100px;');

另外就是不需要對 null object 做太多處理:

$('#foo').css('width: 100px;');

與這樣比較:

let elem = document.querySelector('#foo');
if (elem) {
    // ...
}

不過在這些年,負面的部份已經大幅改善了,所以也陸陸續續可以看到很多人在討論要怎麼拔掉 jQuery。而這次英國的 GOV.UK 拔掉 jQuery 有看到一些效果:

  • Less front end processing time overall.
  • 11% less blocking time at the 75th percentile.
  • 10% less blocking time for users at the 95th percentile. These are users who experience seriously adverse network and device conditions, and every performance gain matters especially for them.

但說實話,~10% 左右的 performance 改變比預期中少很多耶?可以看出來 John Resig 當年在上面為了效能花了多少功夫...

這次的結果反倒是讓我在思考,如果可以用 jQuery 降低開發的瓶頸,我還蠻偏好就拿 jQuery 進來用...

可以看 Chrome Extension 程式碼的 Chrome extension source viewer

好像沒有提過「Chrome extension source viewer」這個套件,來介紹一下...

這個套件可以在尚未安裝前看 Chrome Web Store 裡 extension 的原始程式碼,算是可以在安裝前看一下 extension 在幹什麼。

以前還會遇到會 obfuscated code,導致很難看出來在幹什麼,但在 2018 年以後 Google 公告直接禁止這類行為,就不太會遇到這種情況了 (除非是很舊的 extension):「Trustworthy Chrome Extensions, by default」。

先前跟 Brave 還會打架,不過後來看起來沒這個問題了...

NGINX 官方給的十個常見的設定錯誤

也是在 Hacker News 上看到的,NGINX 官方給的 10 個設定上的常見錯誤:「Avoiding the Top 10 NGINX Configuration Mistakes」,對應的討論串在「Avoiding the top Nginx configuration mistakes (nginx.com)」這邊,看了一下裡面還蠻多蠻實用的?(雖然有些算是官方自己的偏見,或是官方自己在搞事...)

第一個是 worker_connections 設定與 fd 的上限沒有對應,因為每個連線會吃掉兩個 fd,所以要給夠才有辦法讓 connection 衝上去:

The common configuration mistake is not increasing the limit on FDs to at least twice the value of worker_connections. The fix is to set that value with the worker_rlimit_nofile directive in the main configuration context.

另外就是要檢查系統的 limit 設定,像是 /etc/security/limit.conf 這類的設定。

第二個是 error_log off 這個設法,在 NGINX 裡面是有 access_log off,但沒有 error_log off 這個設法,如果你這樣設的話會寫到 error 這個檔名內。所以如果真的要丟掉的話要丟到 /dev/null,像是官方給的範例這樣:

error_log /dev/null emerg;

第三個是 NGINX 對 upstream (backend) 沒有設定 keepalive,這會導致在量很大的時候會產生不少 overhead。

第四個是違反直覺的繼承設定,官方用這樣的範例來表達:

http {
    add_header X-HTTP-LEVEL-HEADER 1;
    add_header X-ANOTHER-HTTP-LEVEL-HEADER 1;

    server {
        listen 8080;
        location / {
            return 200 "OK";
        } 
    }

    server {
        listen 8081;
        add_header X-SERVER-LEVEL-HEADER 1;

        location / {
            return 200 "OK";
        }

        location /test {
            add_header X-LOCATION-LEVEL-HEADER 1;
            return 200 "OK";
        }

        location /correct {
            add_header X-HTTP-LEVEL-HEADER 1;
            add_header X-ANOTHER-HTTP-LEVEL-HEADER 1;

            add_header X-SERVER-LEVEL-HEADER 1;
            add_header X-LOCATION-LEVEL-HEADER 1;
            return 200 "OK";
        } 
    }
}

而你會發現 add_header 會蓋掉先前繼承的項目,但同一個 block 之間會疊加而不是蓋掉...

所以打 localhost:8081/test 的時候只會有 X-LOCATION-LEVEL-HEADER: 1;打 localhost:8081/correct 會有四個 HTTP headers...

第五個算是官方自己的偏見,我們一般都會希望壓低 TTFB (Time To First Byte),把 proxy_buffering 關閉算是常態了。

第六個是官方雖然實做了 if 但很不希望你拿來用。

第七個是 health check 的正確設法,避免多個 block 都有 health check,造成無用的功夫。

第八個是保護內部的資訊,這邊給的範例是 stub_status

第九個是個地雷,ip_hash 這個演算法可以依據 client 的 IP address 來打散流量到後端的伺服器上,對於 IPv6 他會拿整個 IPv6 當作 key (128 bits),但對 IPv4 他只會拿前面三碼 (24 bits) 當作 key:

The ip_hash algorithm load balances traffic across the servers in an upstream{} block, based on a hash of the client IP address. The hashing key is the first three octets of an IPv4 address or the entire IPv6 address. The method establishes session persistence, which means that requests from a client are always passed to the same server except when the server is unavailable.

這完全就是官方自己在搞... 而 workaround 是自己指定 key:

The fix is to use the hash algorithm instead with the $binary_remote_addr variable as the hash key.

第十個是沒有使用 upstream,大多數的情況就是測試發現會動,就直接上 production 的關係 XDDD

德國的地方法院說使用 Google Fonts 服務沒有告知使用者違反 GDPR

看到「German Court Rules Websites Embedding Google Fonts Violates GDPR」這篇,雖然不是最終判決,但總是個開始:

A regional court in the German city of Munich has ordered a website operator to pay €100 in damages for transferring a user's personal data — i.e., IP address — to Google via the search giant's Fonts library without the individual's consent.

因為 GDPR 內把 IP address 資訊視為 PII,所以看起來任何 3rd-party 的內嵌服務應該都會受到影響,來追起來看一下後續的發展好了...

Alexa.com 宣佈將在 2022 年五月退役

Hacker News 上看到的消息,Alexa.com 將在 2022 年五月退役:「We will be retiring Alexa.com on May 1, 2022」,對應的討論在「We will be retiring Alexa.com (alexa.com)」這邊。

討論裡面有提到一些替代方案,大概只有 similarweb 堪用,另外也有提到「Tranco」這個:

A Research-Oriented Top Sites Ranking Hardened Against Manipulation

歷史啊...

繞過 Web 上「防機器人」機制的資料

這兩天的 Hacker News 冒出一些討論在講 Web 上「防機器人」機制要怎麼繞過:

第一篇主要是從各種面向都一起討論,從大方向的分類討論 (「Where to begin building undetectable bot?」),另外介紹目前有哪些產品 (在「List of anti-bot software providers」這邊)。

在文章裡有提到一個有意思的工具「puppeteer-extra-plugin-stealth」,主要是在 Node.js 類的環境,查了一下在 Python 上也有 pyppeteer-stealth,不過 Python 版本直接講了不完美 XDDD

Transplanted from puppeteer-extra-plugin-stealth, Not perfect.

第二篇文章在開頭就提到他不是很愛 Proxy,因為 Proxy 很容易偵測。在文章最後面則是提到了兩個方案,第一個是用大量便宜的 Android 手機加上 Data SIM 來跑,另外一個是直接用 Android 模擬器加上 4G 網卡跑。

依照這些想法,好像可以來改善一下手上的 RSS 工具...

Google Analytics 會愈來愈不準的問題

Hacker News Daily 上看到在討論 Google Analytics 會愈來愈不準的問題:「58% of Hacker News, Reddit and tech-savvy audiences block Google Analytics」,先大概知道 Plausible 也是一個分析工具,宣稱重視隱私以及相關法規 (...),所以網站裡面提到的推論可以看看就好,這次我主要是看數字而已。另外當然,Hacker News 上對這篇文章的討論「Tech-savvy audiences block Google Analytics (plausible.io)」也可以翻翻。

作者先前注意到愈一般性的網站,阻擋率就愈低,但科技相關的網站就會高到失真:

In a previous study, I’ve found that less than 10% of visitors block Google Analytics on foodie and lifestyle sites but more than 25% block it on tech-focused sites.

其實不算太意外,除了 Google 自家的瀏覽器,其他的瀏覽器愈來愈多預設就會擋掉各種 tracker,而科技相關網站的受眾常常會「保護自己」。

首先的段落提到的全站的比率,有大量的使用者會擋掉 Google Analytics (要注意這邊是拿科技類網站的數字,不是一般性的網站),:

58% of visitors block Google Analytics

然後是桌機與筆電的使用者阻擋率比較高 (還是科技類網站的數字):

68% of laptop and desktop users block Google Analytics

另外提到 Firefox 使用者的阻擋率超高,應該是幾乎都會裝套件擋,另外記得新版的 Firefox 預設會擋,可能也有關係 (再提醒一下,這是科技類網站):

88% of Firefox users block Google Analytics

另外一個不算意外的是 Linux 使用者也是擋的很兇 (科技類網站):

82% of Linux users block Google Analytics

這有兩個重點蠻重要的,第一個是,就算你不是科技類網站,你也應該試著用其他工具「校正」Google Analytics 的數字,你要知道 Google Analytics 偏差了多少。

第二個是 Firefox 使用者的數量可能都被低估了,以 Firefox 阻擋率這麼高的情況下,有可能 Firefox 使用者會裝各種阻擋工具,把各種分析平台都擋一輪。不要直接用這些工具的數字決定忽略掉 Firefox 的使用者,最好要多方面驗證:

I expected these numbers to be higher. However, an even more interesting metric is the 88% block in Firefox.

Firefox may not have a great market share, but based on these numbers it's market share may very well be eight times higher than your analytics report. This can change the argument of "it's only 3% of our users so we don't need to test on FF" to "it's a quarter of our user base, we should at least test it", depending on your target audience. I've seen tons of people claim general Firefox usage is negligible based on public data from websites such as statcounter, but these metrics prove that those statistics are unreliable and should not be used.

The best you can do is use server side UA inspection, though you can't really distinguish bots from real users that way.

另外順便提,我在辦公室裡面推銷 uBlock Origin 的方式是跟他們說 YouTube 影片就沒有 Google 的廣告了 (業配那種不算),基本上用過就回不去了...

用 CSS Selector 產生 RSS feed

Hacker News 首頁看到「Show HN: RSS feeds for arbitrary websites using CSS selectors (vincenttunru.com)」這個,程式在 GitLab.com 上的「Feed me up, Scotty!」這邊,另外這個專案名稱是在玩 Star Trek 的梗:「Beam me up, Scotty」,然後這邊講的 RSS feed 已經算是通稱了,實際上大家都是輸出 Atom

他用的設定檔格式是 TOML,文章給的範例:

[funfacts]
title = "Wikipedia — did you know?"
url = "https://en.wikipedia.org/wiki/Main_Page"
entrySelector = "#mp-dyk > ul li"
titleSelector = "b"
linkSelector = "b a"

[wikivoyage]
title = "Wikivoyage recommendations"
url = "https://en.wikivoyage.org/wiki/Main_Page"
entrySelector = ".jcarousel-wrapper .jcarousel-item"
titleSelector = "h2"
linkSelector = "h2 a"

feed-me-up-scotty/src/index.ts 這邊看起來是 TypeScript 專案,然後用 browser 帶起 Firefox 來,可以預期會吃不少資源...

另外 Hacker News 的討論裡有另外提到「Feed Creator」,看起來也是個不錯的專案,有免費版與付費版...

Google Web Store 裡的黑暗交易

標題只寫了 Google Web Store,主要是因為瀏覽器市占率的問題,其實是包含 Firefox 的 Add-Ons。

這是在 Hacker News 首頁上看到的:「Many temptations of an open-source chrome extension developer」,講一直會有人來接觸,可以付費給開發者,想要在這些專案裡面放一些「東西」,可能是蒐集資料,可能是強制導到特定的 search engine,也有可能更邪惡...

另外是老規矩,在 Hacker News 上的討論也可以翻一翻,還蠻有趣的:「Many temptations of an open-source Chrome extension developer (github.com/extesy)」。

先大概看一下 Hover Zoom+ 這個套件在 Google Web Store 的安裝數量,大約 30 萬人:「Hover Zoom+」,作者公佈的信件內容裡面有一些包括價錢與目的...

話說回來,Brave 上的 CRX Viewer 還是沒修好啊:「Stopped working with Brave」,要裝新的套件都得另外再拉 crx 檔下來看,麻煩不少...