我与 IT 这三十年:1997,那只蝴蝶飞过浏览器战争

发布时间:2026/7/12 17:15:08

我与 IT 这三十年:1997,那只蝴蝶飞过浏览器战争
上一篇写到 1996 年,我说那一年屏幕还很小,世界刚刚变大。文章最后留下了一只蝴蝶:1997 年,我用 JavaScript 写过一个小程序,一只蝴蝶可以在页面上飞舞。现在回头看,这件事小得不能再小。它不是一个系统,不是一个项目,不是一个能上生产的产品,也不是一段值得放进简历的经历。它只是一个网页小动画。鼠标、窗口、脚本、图片、坐标、定时器,凑在一起,让一只蝴蝶在浏览器里飞来飞去。但三十年后再想,我反而觉得那只蝴蝶比很多正式项目更像一个时代的标本。因为它飞起来的时候,Web 还没有今天这么稳。HTML 是页面,JavaScript 是新鲜玩意儿,CSS 刚开始试图给网页一点像样的表现能力。浏览器厂商彼此不服,标准还在追赶现实,程序员写一个小动画,都可能要面对不同浏览器完全不同的脾气。那只蝴蝶不是飞在一个成熟的平台上。它飞在浏览器战争的缝隙里。先让页面动起来今天写一个网页动画很容易。CSS animation、requestAnimationFrame、Canvas、SVG、WebGL、各种框架和组件库,随便拿一个都能做出比当年复杂得多的效果。1997 年不是这样。那时你想让页面动起来,先要相信一件事:浏览器不只是文档阅读器。它可以执行脚本,可以响应用户,可以改变页面内容,可以把原本静止的 HTML 变成一个有行为的东西。这个想法现在理所当然,当年却很新鲜。我写那只蝴蝶,大概就是从最朴素的坐标开始。页面上有一个图片元素,脚本不断改变它的位置。为了让它看起来不是机械地横着走,还要给它一点上下浮动,一点速度变化,一点边界反弹。蝴蝶不是真的会飞,只是坐标不断变化,浏览器不断重绘。可就是这种“假的飞”,让人第一次感到网页有了生命。一只在早期浏览器窗口中飞舞的像素蝴蝶。图为按年代氛围生成的示意图。这件事的技术含量,在今天看当然很低。可是当时真正让人费劲的,不是动画数学,而是浏览器差异。同一段脚本,在一个浏览器里能跑,在另一个浏览器里可能不认。这个对象有,那个对象没有;这个属性这样叫,那个属性换了名字;这个事件能触发,那个事件行为又不一样。你要写判断,要试,要改,要在心里记住不同浏览器的怪癖。很多年后,前端工程发展出一整套工具链:兼容层、构建工具、Polyfill、Babel、框架、测试、打包、组件化。它们看起来很现代,但根子上解决的仍然是同一个问题:Web 是开放的,开放就意味着差异;Web 是开放的,开放也意味着没有谁能彻底控制它。1997 年的程序员还没有这些成熟工具,只能手工对付差异。所以那只蝴蝶飞得并不轻盈。它每飞一下,背后都有一堆 if。DHTML:网页第一次想做应用1997 年,浏览器大战已经不是口号,而是每个网页作者都能直接感受到的现实。

相关新闻

Momentum-Firmware RGB背光控制系统:打造个性化Flipper Zero灯光体验 [特殊字符]

Momentum-Firmware RGB背光控制系统:打造个性化Flipper Zero灯光体验 [特殊字符]

2026/7/12 17:05:07

Momentum-Firmware RGB背光控制系统:打造个性化Flipper Zero灯光体验 🎨 【免费下载链接】Momentum-Firmware 🐬 Feature-rich, stable and customizable Flipper Firmware 项目地址: https://gitcode.com/GitHub_Trending/mo/Momentum-Fir…

3步快速上手MMSegmentation:从零开始掌握语义分割实战

3步快速上手MMSegmentation:从零开始掌握语义分割实战

2026/7/12 17:05:07

3步快速上手MMSegmentation:从零开始掌握语义分割实战 【免费下载链接】mmsegmentation OpenMMLab Semantic Segmentation Toolbox and Benchmark. 项目地址: https://gitcode.com/GitHub_Trending/mm/mmsegmentation 语义分割是计算机视觉领域的核心技术之一…

vLLM加载优化终极指南:从分钟级等待到秒级启动的实战手册

vLLM加载优化终极指南:从分钟级等待到秒级启动的实战手册

2026/7/12 17:05:07

vLLM加载优化终极指南:从分钟级等待到秒级启动的实战手册 【免费下载链接】vllm A high-throughput and memory-efficient inference and serving engine for LLMs 项目地址: https://gitcode.com/GitHub_Trending/vl/vllm 在大语言模型部署的战场上&#xf…

Actor-Critic 方法

Actor-Critic 方法

2026/7/12 18:55:11

1. The simplest actor‑critic (QAC) 2. Advantage actor‑critic (A2C) 2.1. Baseline invariance 2.2. The algorithm of advantage actor‑critic 3. Off‑policy actor‑critic 3.1. Illustrative examples 3.2. Importance sampling 3.3. The theorem of off‑policy po…

Kent C. Dodds个人网站:React专家与JavaScript教育者的技术博客完全指南 [特殊字符]

Kent C. Dodds个人网站:React专家与JavaScript教育者的技术博客完全指南 [特殊字符]

2026/7/12 18:55:11

Kent C. Dodds个人网站:React专家与JavaScript教育者的技术博客完全指南 🚀 【免费下载链接】old-kentcdodds.com Kents Homepage 项目地址: https://gitcode.com/gh_mirrors/ol/old-kentcdodds.com 欢迎来到Kent C. Dodds个人网站的终极指南&…

洛谷 P1469:找筷子 ← 位运算

洛谷 P1469:找筷子 ← 位运算

2026/7/12 18:55:11

【题目来源】 https://www.luogu.com.cn/problem/P1469 【题目描述】 经过一段时间的紧张筹备,电脑小组的“RP 餐厅”终于开业了,这天,经理 LXC 接到了一个定餐大单,可把大家乐坏了!员工们齐心协力按要求准备好了套餐…

生产环境ClickHouse ETL 操作规范指南(附检查清单)

生产环境ClickHouse ETL 操作规范指南(附检查清单)

2026/7/12 18:55:11

引言在AI编码工具大行其道的今天,很多人拿到需求的第一反应是“让AI帮我写段SQL”和直接让ai操作数据表。但AI生成的SQL常常语法正确、逻辑通顺,在本地环境运行无误,上线后导致查询过慢,甚至把集群直接打崩——因为它可能忽略生产…

3步快速开始使用vagas:免费接收完整职位信息的完整教程

3步快速开始使用vagas:免费接收完整职位信息的完整教程

2026/7/12 18:55:11

3步快速开始使用vagas:免费接收完整职位信息的完整教程 【免费下载链接】vagas 🚀 Divulgue facilmente e receba a vaga por completo no seu e-mail 项目地址: https://gitcode.com/gh_mirrors/vagas/vagas 🚀 想要轻松获取巴西QA测…

anthropics-skills | 02 - Skill 解决的核心问题:把隐性经验变成显性流程

anthropics-skills | 02 - Skill 解决的核心问题:把隐性经验变成显性流程

2026/7/12 18:45:11

系列:《把经验封装成能力:Agent Skills 设计与落地》 本文是系列第二篇。上一篇我们回答了 Skill 是什么;这一篇继续往下走:为什么 Skill 最重要的价值,不只是复用提示词,而是把个人和团队的隐性经验变成 A…

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践

2026/7/12 0:03:42

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator XUnity.AutoTranslator作为Unity游戏社区中最成熟的文本翻译解决方…

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持

2026/7/12 0:03:42

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持 【免费下载链接】raspberrypi-kernel It provides openEuler kernel source for Raspberry Pi 项目地址: https://gitcode.com/openeuler/raspberrypi-kernel 前往项目官网免费下载&…

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧

2026/7/12 0:03:42

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧 【免费下载链接】integration-test The repo contains test suits for system integration test 项目地址: https://gitcode.com/openeuler/integration-test 前往项目官网免费下载:…

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践

2026/7/12 0:03:42

Unity游戏文本翻译架构深度解析:XUnity.AutoTranslator的技术实现与工程实践 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator XUnity.AutoTranslator作为Unity游戏社区中最成熟的文本翻译解决方…

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持

2026/7/12 0:03:42

openEuler Raspberry Pi Kernel设备驱动开发指南:为树莓派硬件添加支持 【免费下载链接】raspberrypi-kernel It provides openEuler kernel source for Raspberry Pi 项目地址: https://gitcode.com/openeuler/raspberrypi-kernel 前往项目官网免费下载&…

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧

2026/7/12 0:03:42

openEuler系统集成测试实战:基于smoke-test套件的环境验证技巧 【免费下载链接】integration-test The repo contains test suits for system integration test 项目地址: https://gitcode.com/openeuler/integration-test 前往项目官网免费下载:…