哈希娱乐 行业新闻 党建先锋

从制作世界上最快的网站中学到的十件事[译]哈希娱乐

发布时间:2026-02-16 11:33:12  浏览:

  哈希游戏作为一种新兴的区块链应用,它巧妙地结合了加密技术与娱乐,为玩家提供了全新的体验。万达哈希平台凭借其独特的彩票玩法和创新的哈希算法,公平公正-方便快捷!万达哈希,哈希游戏平台,哈希娱乐,哈希游戏本文是聊的是性能提升相关的技术,希望你们别太介意题目中提到的那个网站目前尚未完成。

  但是如果你非得看看该网站的实际情况以判断我后面的观点是否有价值,点击进入Know it all。

  不出意外,它的打开速度应该极快(对于国内用户,请把墙的影响考虑在内,不要让它影响你的判断),毫无疑问,它会打消你们对于我能力的质疑。如果你觉得我不够谦虚,那是因为我就是这么牛逼。

  我来给网站功能做个简单推销:“你有没有想过对于 web 到底有哪些东西是你所不清楚的?它的哪些部分成功的躲过你的注意?难道你不曾想过列个清单然后看看勾出那些东西是你真正理解的部分,然后开始学习剩下那些有趣的东西?”

  如果你还纠结于我为什么要在该网站还没完工之前写这篇文章...因为我需要反馈。影响性能的因素面很广,也有很多奇淫邪技可以提升页面速度。我希望能有一些我并不知道的东西,热烈欢迎给我提出各类建议。如果你迫不及待的想深入挖掘该站实现代码,项目在这。

  我把 repeat view 放在上面。因为这是我的东西我想怎么弄就怎么弄。

  不,当然不了。这些网站功能完全不同,要求它们有相同的加载时间显然是不理智的。但是它们都是一些拼尽全力提升性能试图赶超 google 首页加载速度的网站。

  如果你不巧觉得被它震惊了,建议你(暂时)先冷静一下。是的,我不需要从数据库中读取产品内容,或者进行登录操作、加载那些要跳转40次以加载一个flash文件的第三方广告,甚至我连图片都没有。哦,还有,我的页面数——一个。

  在页面加载完成并展示到你面前时,它已经下载并解析了一个长达 75,000 行的 JSON 文件。最终得到的树——如果全展开的线 行(是的,我把整个都规范搬过来了)。

  一路上我纠正了很多观点和态度,学到了不少东西,整理之后,四舍五入一下有 10 点。两个月前我发现其中7个非常有用,另外3个纯粹垃圾。

  最近我听一个非web开发者跟我说:“前几天我上,它慢的要死,他们是怎么做到让一个网站那么慢的?”。

  我当时刚弄了一个纹身,满嘴谈论upper register(慎点),所以回答的可能有点不清楚。但是大概想法是要做个龟速的网站很容易,不尽力将它变快就行了。

  这是个好消息,也就是说如果你尽力让它变快,你最终将自动得到一个飞快的网站。你要不停的尝试,就像做混蛋一样,稍做练习就会很容易。

  在这个网站的实现过程中,每隔一段时间我就考虑一下在做的部分对于性能的影响。对于这个应用中使用到的几乎每个库,我都衡量了三个尺度:

  如果一个库对性能有负面影响,抛弃。比如有一次,脑子发热使用lodash对 7,5000 个属性的 JS 对象执行 deepClone 操作。最后改用Immutable.js,性能显著提升。

  我现在使用 React,有一次引入了 classnames 库,然后我照常去测量那三个尺度的性能...没影响,嗯, classnames,你幸免于难。

  引入新的库或者进行重大修整时测量花个5分钟使用这种方式测量它们对性能的影响对于提升网站性能其实是个很划算的买卖。

  第一种(也是在这个项目之前我一直使用的),你坐在27寸的显示器前,就像看页面的 imax 版那样,用着非常好的显卡还有用不完的内存,使用 media query 指定 min-width,然后告诉朋友我在做移动优先。

  这个项目中,我做了真正的移动优先。即开发时,使用移动设备运行页面。我这样做直到性能和 UI 已经满足我的需求,然后才转到电脑上继续工作。

  (这个故事并没有说的那么简单,项目开始时,我延续了以前的坏习惯,中途才突然顿悟然后开始默认在移动设备上进行开发测试。)

  如今,仅在提供手机版本的网站不切实际,除此之外,我们要持续测试性能,这需要一个稳定的量尺,看过这个视频你会发现移动设备不适合作为稳定的测试平台。

  进行性能测试时,注意使用 Chrome DevTools 提供对 CPU性能和网络给予适当限制。我将 CPU 调低10倍,网络改为“3G”网络。我知道这种限制下它可能还是比手机的平均性能要高,但是我还不想矫枉过正,在极端环境中去无谓地折磨自己。

  一个令我吃惊的发现:我的电脑使用i7 处理器,移动设备是一台全新的 Pixel XL——世界上最快的手机。你觉得该手机的性能大概是电脑的百分之多少呢?80%?60%?至少 10% 以上?

  这是点击响应速度为 20ms 和 200ms 的差别;渲染一帧时间为 16ms 与 160ms 的差别。(麻烦在评论中继续把这个排比补全)

  我的自负让我来到这里跟你们炫耀(它已经溢出来了)。一旦在某个性能测试网站上获得了高分,我会跑到所有其它测试站点听它们测试完成后自动化的称赞。

  在lighthouse中测试我的站时,分数停在了 97。我剩下的那三分呢!

  奥,它告诉我有个输入有 285ms 的延迟。如果这是真的,那也真是骇人听闻了。但我知道它只需花费 20ms。

  冷静了一下,我不情愿的承认也许还是需分析一下究竟是什么情况,尽管显然我是对的,Google 写的算法明显搞错了。

  然后我开始了拉低 CPU 速度进行测试那一档子流程,果然,我感觉应该瞬时完成的部分现在有了 200+ms 的延迟。

  我进行了仔细的分析,发现延迟的大部分时间耗费在 React 中。我已经做了 React 性能相关所有的最佳实践,也没有做“无用的更新(wasted update)”。

  我甚至对 low-cardinality components(译者注:读者中有知道什么意思的,麻烦告知一下)做了缓存优化。(我不知道cardinality是什么意思,但我觉得我用的没错。)

  这里我得指出我是 React 的超级粉丝,我有三只宠物都是以 React 命名的(一只狗,两只雪貂),最后不得已不这样做了是因为它们一个个都死了,我不禁想问题肯定出在这个名字上。

  对 React 的这种热爱让我在找其他前端框架时就像在上 Ashley Madison(Ashley Madison是一家专门为已婚人士提供交友、约会服务的社交网站。网站的口号是:“人生短暂,偷情无限!”)。但是性能高于忠贞,我沉重的拥抱了Preact。

  最开始我尝试的事 preact-compat。花了大概 15 分钟就迁移过去了。性能提升明显,真棒~。

  我把这事跟 Preact 的开发者说了一下,他建议我试一下完整版的 Preact。果然又快了不少。

  另一个人发推提醒我该试一下Inferno。然后我把应用转成 inferno 的试图再挤出一点性能。

  好吧,我尝试过了,Inferno 的确很快,但是没有 Preact 快,所以我回滚了代码。

  每当我不大乐意重写时,我就想反正活着本来就没什么意义,而且不幸电脑奔溃什么都留不下。——给你的小小的建议。

  然后我在yslow上测了一下。我想毫无疑问应该得最高分,然后他们因为我的 DOM 节点过多给了我一个 D!这简直是无理取闹,我知道应该使用多少 DOM 节点,没人能告诉我应该怎么做,我才是自己的老大。

  然后我不情愿的想也许可以减少要渲染的 DOM 节点的数量。所以我修改了默认渲染的分支。

  客户端渲染(Client Side Rendering,CSR)——我称之为“把钱点着然后扔到河里”——有其用处,但是对于这个网站,不适合这样。

  这个页面不包含任何用户相关的信息,可以直接将一份相同的 HTML 发给每个人。而且在客户端中计算量比较大,使得 CSR 更为耗时间。CSR 显然不是将页面展示出来最快的方式。

  对于那些用于给公司带来收入的——需要被持续维护——的页面,下面是我给出的建议:

  显然是自相矛盾了,胡说些什么?不在服务端渲染 HTML 怎么提供 HTML 页面?这是上个世纪90年代人做的事情...

  React(还有比它更快的表亲们)能够在几十毫秒内将渲染好 HTML。(有人统计过 PHP 或者 JSP 要花多长时间吗?我对这个比较很感兴趣。)这意味着单核每秒只能给 50 个人提供服务;额外的请求需要排队,这可不妙。

  就我这个小站而言,我给每个人发送相同的 HTML。如果你的站点和我一样,那么你不需要让你的服务器对每个请求进行 HTML 的渲染然后发送页面、CSS和JS文件。你可以在编译时生成 HTML 页面。然后将所有东西打包静态托管(或者放在一个好的 CDN 上)。Github、Firebase 或者其他好人愿意托管你的静态资源。

  这种情况并不多见所以如果你跳过这条建议我也不会太失望。但是如果你有任何可以编译时生成的页面(比如 LinkedIn,Paypal,Github 的主页),使用这种方式。

  这条是我后来突然想到的,当时我在浏览一篇博客,然后想到点近该博客只花了 96ms。(然而我还时认为我的网站是世界上最快的——现实也不能改变这点。)

  我深挖了一下发现该博客托管在 Firebase 上。我想我会试试他们的服务。

  如果 React 能够将生成的 DOM 输出成字符串就好了。那我就可以在构建脚本中把它存为 HTML 文件。

  对那些不知道的人悄悄说一句,很有意思的是,React 的确有个叫 renderToString 的方法。

  (既然到这一步了,在保存 HTML 之前不妨先用 minifier 处理一下。)

  每当我坐下来尝试想出到底应不应该使用內联 CSS 时,总是得出一个结论——得看情况...

  如果像一样,99.9% 的页面访问来自回头客,最好将 CSS 文件分开便于浏览器进行缓存。对于丧葬公司首页来说,可能回头客没那么多,也许使用內联 CSS 可以帮你减少一点请求。

  如果你的生活太过一帆风顺,想制造点泪水和挫折,可以尝试一下给一些元素添加內联样式,其他样式放在单独的 CSS 文件中。

  我个人的原则是(所以现在我不需要考虑这个问题):如果将 CSS 放进 HTML 且保持最终所有东西控制在 14KB,那么就使用內联。(不知道为什么是 14?读这个)

  有时候我觉得自己太容易分心了,有一次有人告诉我我的脑子不仅在神游,它是穿着短裤乱蹦跶。

  这种方式可能会增加需要传输的HTML文档大小,不过这并不会影响到首屏用户体验,只会让用户真正的可操作时间点后延,毕竟JavaScript的传输开始时间被推迟。如果你的页面在不加载 JavaScript 时能显示大部分有用内容,页影响不大。但是我的那个站在没有 JavaScript 的话就一脸懵逼。

  我可以在 JavaScript 中使用各种风骚的技巧实现这些,但是有一个更好的方法。至少它能满足要求,但我感觉可能哪个地方有点不对。

  一个插曲:我想把 JSON 文件的 hash 添加到名字中以永久缓存时,坏了自己的规则,像个一样到 npm 中找了半天,突然发现 Node 内建了一个 crypto 库,果断存到gist中去:

  用户中使用 Chrome、Edge和Firefox的都是好人。创建一个 30KB 大小的 polyfill 发给他们对他们公平吗?不,不公平。

  这个项目中,我创建了一个单独的 polyfill 文件,然后在需要的时候加载:

  你可能也意识到了现在为止我还没提过下载大小相关事宜。因为文件大小无关紧要。

  如果你要测量站点“到可交互花费时间”,那么你已经把下载时间考虑在内了;它包含了下载和解析的时间。

  如果你想做更细致的裁剪,为不同浏览器定制不同的 polyfill,polyfill.io已经帮你做了。这供一些特殊用户使用,下面是为什么你不需要使用它的原因:

  (我觉得没提 Safari 有点过分——Safari 10 对 JavaScript 支持非常好——但是没有 fetch 所以在我眼中不算现代浏览器)

  很长一段时间内我都拖着没有学习 service workers。我想总有一天我要花上 400 小时看看它到底是怎么实现的。直到这天,我决定制作这个星球最快的网站,我想时候到了。

  五个小时后,我都搞明白了。一点没骗你。而且其中4小时35分钟都是在做错事。简而言之:

  网站加载一次后,之后使用就不再需要网络。新版本可用时,如果接入了网络,刷新一下,新版本在后台被自动加载。

  朋友们,这是未来啊。好吧,它早些年就已经出来了,只是我最近才学它。朋友们,广而告之,都去用 service worker 吧。

  很不幸,你们中 50% 使用 Safari/iOS 阅读这篇文章的没有 service worker 支持。Apple 肯定再加紧实现它了,不然有一天你想上网快一点只能用安卓了。

  那么为什么不使用它们呢?我选择了 Calibri Light, Roboto and Helvetica Neue。如果你坚持要在所有设备上使用相同的字体,那么你没救了。

  我的 app.js 大小已经降到了约 28KB,我在想它由哪些部分组成。一番侦查后发现 ImmutableJS 占据了 19KB!一个小小的库竟然占据了整个应用大小的三分之二!

  我仅用了 ImmutableJS 中很少的部分,我觉得我可以自己实现那个部分。花了几个小时替换掉了 ImmutableJS,性能提升按百分比来说大于之前做的所有改变。减少了 60% 的加载时间!

  写一个快的网站就像养一条小狗,需要持之以恒的耐力。你可以很注意的优化所有代码到最优、最小,但是一次懒惰然后使用了一个 11KB 的库来格式化日期、让狗狗在床上拉了一次粑粑,就白瞎了那么多幸苦的劳动、得去洗半天的被子。