It's too long for this in comment, so I'm posting here.
When speaking of caching DB results in PHP before output, I'll always be a little hesitated, as that isn't "intuitive" for the relationship of *data*base and PHP.
In this case, especially if you have a very large ITEM
table, you'll be caching a lot string in PHP before you can output.
So I think you can use the current logic, and take advantage of prepared statement:
$req=$mysqli->query("SELECT id, name FROM ITEM WHERE 1 ORDER BY id DESC");
$tag=$mysqli->prepare("SELECT id, name FROM tag, item_tag WHERE item_tag.id_item=? AND item_tag.id_tag=tag.id LIMIT 5");
$tag->bind_param("i",$tid);
while($res=$req->fetch_assoc())
{
echo "<h1>".$res['name']."</h1>";
$tid=intval($res["id"]);
$tag->execute();
$req_tag=$tag->get_result();
while($res_tag=$req_tag->fetch_assoc())
{
echo "• ".$res_tag['name']."<br/>";
}
}
The above code is not tested, but I think you can get the idea.