Loading modern code for modern browsers while still supporting older browsers should be possible via module/nomodule:
<script type="module" src="/modern.js"></script>
<script nomodule src="/legacy.js"></script>... however this results in over-fetching of scripts in Edge and Safari.
We can circumvent these issues by implementing a tiny script loader, similar to what we do with LoadCSS:
<!-- preload the modern script in browsers that support modules: -->
<link rel="modulepreload" href="/modern.js">
<!-- use a module script to detect modern browsers: -->
<script type=module>self.modern=1</script>
<!-- now use that flag to load modern VS legacy code: -->
<script>
document.head.appendChild((function(s){
if (self.modern){ s.src='/modern.js'; s.type='module'; }
else s.src = '/legacy.js'
})(document.createElement('script')))
</script>Here's what that might look like in prod:
<script type=module>self.modern=1</script>
<script>
function loadJS(e,d,c){c=document.createElement("script"),self.modern?(c.src=e,c.type="module"):c.src=d,document.head.appendChild(c)}
loadJS('/bundle.js', '/bundle.legacy.js')
</script>I don't have a code sample for this, since User Agent detection is nontrivial.
Essentially, this technique uses the same <script src=bundle.js> for all browsers,
but when bundle.js is requested, the server inspects the browser's User Agent string
and actually serves up modern or legacy JavaScript depending on whether it's recognized
as a modern browser or not.
While this approach is versatile, it comes with some severe implications:
- since server smarts are required, this doesn't work for static deployment (static site generators, Netlify, etc)
- caching for those JavaScript URLs now varies based on User Agent, which is highly volitile
- UA detection is difficult and can be prone to false classification
- the User Agent string is easily spoofable and new UA's arrive daily
The ill-effects of module/nomodule are seen in old versions of Chrome, Firefox and Safari - these browser versions have extremely limited usage, since they employ automatic updates. This doesn't hold true for Edge 16-18, but new versions of Edge will use a Chromium-based renderer that doesn't suffer from this issue.
It might be reasonable for some applications to accept this as a trade-off: you get to deliver modern code to 90% of browsers, at the expense of some extra bandwidth on older browsers. Notably, none of the User Agents suffering from this over-fetching issue have significant mobile marketshare - so those bytes are less likely to be coming from an expensive mobile plan or through a device with a slow processor.
One clever approach here is to use nomodule to conditionally load bundles of code that isn't
required in modern browsers, such as polyfills. With this approach, the worst-case is that the
polyfills are loaded or possibly even executed (in Safari 10.3, for example), but the effect is
limited to "over-polyfilling". Argubaly, compared to always polyfilling, that's a net improvement.
<!-- newer browsers won't load this bundle: -->
<script nomodule src="polyfills.js"></script>
<!-- all browsers load this one: -->
<script src="/bundle.js"></script>Angular CLI can be configured to use this approach for polyfills, as demonstrated by Minko Gechev.
GitHub-- [[ KARD HUB - VERSÃO ROUBE UM BRAINROT ]] --
local ScreenGui = Instance.new("ScreenGui")
local MainFrame = Instance.new("ImageLabel")
local Content = Instance.new("Frame")
-- Configuração da UI
ScreenGui.Parent = game.CoreGui
MainFrame.Name = "Main"
MainFrame.Parent = ScreenGui
MainFrame.Position = UDim2.new(0.3, 0, 0.3, 0)
MainFrame.Size = UDim2.new(0, 400, 0, 320)
MainFrame.Image = "rbxassetid://1000074288" -- Sua foto
MainFrame.Active = true
MainFrame.Draggable = true
-- [[ BOTÕES LATERAIS (+ / -) ]] --
local OpenBtn = Instance.new("TextButton")
OpenBtn.Text = "+"
OpenBtn.Size = UDim2.new(0, 35, 0, 35)
OpenBtn.Position = UDim2.new(0, 5, 0.5, -40)
OpenBtn.BackgroundColor3 = Color3.fromRGB(0, 255, 0)
OpenBtn.Parent = ScreenGui
local CloseBtn = Instance.new("TextButton")
CloseBtn.Text = "-"
CloseBtn.Size = UDim2.new(0, 35, 0, 35)
CloseBtn.Position = UDim2.new(0, 5, 0.5, 5)
CloseBtn.BackgroundColor3 = Color3.fromRGB(255, 0, 0)
CloseBtn.Parent = ScreenGui
OpenBtn.MouseButton1Click:Connect(function() MainFrame.Visible = true end)
CloseBtn.MouseButton1Click:Connect(function() MainFrame.Visible = false end)
-- [[ FUNÇÃO: SPEED BRAINROT (CORRIGIDO) ]] --
local SpeedBtn = Instance.new("TextButton")
SpeedBtn.Parent = MainFrame
SpeedBtn.Text = "Ativar Speed Brainrot (30)"
SpeedBtn.Position = UDim2.new(0.05, 0, 0.15, 0)
SpeedBtn.Size = UDim2.new(0, 160, 0, 35)
SpeedBtn.MouseButton1Click:Connect(function()
-- Loop para garantir que a velocidade não volte ao normal
spawn(function()
while true do
if game.Players.LocalPlayer.Character and game.Players.LocalPlayer.Character:FindFirstChild("Humanoid") then
game.Players.LocalPlayer.Character.Humanoid.WalkSpeed = 30
end
wait(0.5)
end
end)
end)
-- [[ FUNÇÃO: PULO INFINITO (CADA PULO - SEM MORRER) ]] --
local InfJumpBtn = Instance.new("TextButton")
InfJumpBtn.Parent = MainFrame
InfJumpBtn.Text = "Pulo Infinito: OFF"
InfJumpBtn.Position = UDim2.new(0.05, 0, 0.3, 0)
InfJumpBtn.Size = UDim2.new(0, 160, 0, 35)
local infJumpEnabled = false
InfJumpBtn.MouseButton1Click:Connect(function()
infJumpEnabled = not infJumpEnabled
InfJumpBtn.Text = infJumpEnabled and "Pulo Infinito: ON" or "Pulo Infinito: OFF"
end)
game:GetService("UserInputService").JumpRequest:Connect(function()
if infJumpEnabled then
local humanoid = game.Players.LocalPlayer.Character:FindFirstChildOfClass("Humanoid")
if humanoid then
-- Muda o estado para Jumping em vez de forçar a velocidade Y (evita morrer)
humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
end
end)
-- [[ FUNÇÃO: AUTO GRAB (PEGAR BRAINROT) ]] --
local GrabBtn = Instance.new("TextButton")
GrabBtn.Parent = MainFrame
GrabBtn.Text = "Auto Grab Brainrot"
GrabBtn.Position = UDim2.new(0.05, 0, 0.45, 0)
GrabBtn.Size = UDim2.new(0, 160, 0, 35)
local autoGrab = false
GrabBtn.MouseButton1Click:Connect(function()
autoGrab = not autoGrab
GrabBtn.Text = autoGrab and "Auto Grab: ATIVO" or "Auto Grab Brainrot"
end)
-- [[ SISTEMA DE TELEPORTE COM BOLINHAS ]] --
local tpPoints = {nil, nil, nil}
local balls = {nil, nil, nil}
for i = 1, 3 do
local Save = Instance.new("TextButton")
Save.Parent = MainFrame
Save.Text = "Salvar P" .. i
Save.Position = UDim2.new(0.55, 0, 0.15 + (i-1)*0.2, 0)
Save.Size = UDim2.new(0, 75, 0, 35)
end